It looks like the problem exists at the C level as well. This code doesn't work past the first alarm:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <time.h> int n; char s[10]; char* prog; int alarm_called = 0; void handle_alrm(int signo) { if (signo == SIGALRM) { execv(prog, (char*[]) { prog, s, NULL }); } } int main(int argc, char** argv) { prog = argv[0]; if (argc == 1) { n = 1; } else { n = atoi((const char*)argv[1]); } printf("run %d\n", n); n++; snprintf(s, 10, "%d", n); signal(SIGALRM, handle_alrm); alarm(1); sleep(3); alarm(0); return 0; } But this code does work: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <time.h> int n; char s[10]; char* prog; int alarm_called = 0; void handle_alrm(int signo) { if (signo == SIGALRM) { alarm_called = 1; } } int main(int argc, char** argv) { prog = argv[0]; if (argc == 1) { n = 1; } else { n = atoi((const char*)argv[1]); } printf("run %d\n", n); n++; snprintf(s, 10, "%d", n); signal(SIGALRM, handle_alrm); alarm(1); sleep(3); if (alarm_called) { execv(prog, (char*[]) { prog, s, NULL }); } alarm(0); return 0; } On Tue, Oct 4, 2016 at 10:40 AM Chas. Owens <chas.ow...@gmail.com> wrote: > First, never use -w flag to enable warnings; use the warnings pragma > instead. > > Second, you should not exec the script directly, you don't know if it is > executable or not, and it could even wind up running under a different > version of perl. Instead, you should exec same the interpreter that is > running the current program. Happily perl stores the path to the current > interpreter in $^X for you. > > It appears as if the process becomes insensitive to the SIG_ALRM signal if > you run exec within the signal handler. In general you should avoid doing > anything in a signal handler other than setting a status variable. This > code seems to work the way you were expecting: > > #!/usr/bin/perl > use strict; > use warnings; > > my $n = shift || 1; > > my $exec = 0; > > $SIG{ALRM} = sub { die "timeout\n" }; > > print "\$\$ is $$ this is run $n\n"; > > alarm 1; > eval { > sleep 5; > alarm 0; > 1; > } or do { > alarm 0; # handle cases where it wasn't a timeout that died > if ($@ eq "timeout\n") { > exec $^X, $0, $n + 1; > } > }; > > print "should not get here\n"; > > What are you trying to solve with this code? Is this just academic > playing around? If not, there may be a much better solution than > re-execing the script. > > > On Tue, Oct 4, 2016 at 12:13 AM Unknown User <knowsuperunkn...@gmail.com> > wrote: > > I am trying to re-exec my script after a delay. I expect that the code > below would go on re-execing indefinitely, however that does not > happen. It exits after one reexec. What should be done to make the > code re-exec forever? > > $ cat exec.pl > #!/usr/bin/perl -w > use strict; > alarm(5); > $SIG{"ALRM"} = sub { > print "Reexecing\n"; > exec($0,@ARGV); > }; > > print join(".",@ARGV); > sleep 12; > $ ./exec.pl 1 2 3 4 > 1.2.3.4Reexecing > 1.2.3.4$ > $ > > -- > To unsubscribe, e-mail: beginners-unsubscr...@perl.org > For additional commands, e-mail: beginners-h...@perl.org > http://learn.perl.org/ > > >