Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Can't catch signals after an exec?

by mattk (Pilgrim)
on Mar 19, 2005 at 10:09 UTC ( [id://440900]=perlquestion: print w/replies, xml ) Need Help??

mattk has asked for the wisdom of the Perl Monks concerning the following question:

Given this piece of code:
$sub = sub { exec "perl $0" }; $SIG{INT} = $sub; $SIG{USR1} = $sub; print ++$counter while 1;
Each signal handler works, but only once. After that type of signal has been delivered, that signal ceases to have an effect. Why is this so? Edit: My test code was basically the same as sh1tn's, and I get this output, from perl v5.8.1-RC3, running under OS X 10.3.8:
[matt@powerbook test] perl 440900.pl 1 2 3 4 ^C1 2 3 4 ^C5 ^C^C6 ^C^C7 ^C8 ^Z [1]+ Stopped perl 440900.pl

Replies are listed 'Best First'.
Re: Can't catch signals after an exec?
by derby (Abbot) on Mar 19, 2005 at 13:56 UTC
    from perlipc:

    Not all platforms automatically reinstall their (native) signal handlers after a signal delivery. This means that the handler works only the first time the signal is sent. The solution to this problem is to use "POSIX" signal handlers if available, their behaviour is well-defined.

    So to rework your example with the one from perlipc:

    !/usr/bin/perl -w use POSIX (); use FindBin (); use File::Basename (); use File::Spec::Functions; $|=1; # make the daemon cross-platform, so exec always calls the script # itself with the right path, no matter how the script was invoked. my $script = File::Basename::basename($0); my $SELF = catfile $FindBin::Bin, $script; # POSIX unmasks the sigprocmask properly my $sigset = POSIX::SigSet->new(); my $action = POSIX::SigAction->new('sigHUP_handler', $sigset, &POSIX::SA_NODEFER); POSIX::sigaction(&POSIX::SIGINT, $action); sub sigHUP_handler { print "got SIGINT\n"; exec($SELF) or die "Couldn't restart: $!\n"; } code(); sub code { my $c = 0; while (++$c) { sleep 2; print "$$ - $c\n"; } }

    -derby

    Update: Sorry forgot to tell you. I have the same platform as you (Mac OS X 10.3.8, perl v5.8.1-RC3)

    Update: And a lot more like your original code:

    #!/usr/bin/perl use POSIX(); $|=1; $sub = sub { exec "$0" }; # POSIX unmasks the sigprocmask properly my $sigset = POSIX::SigSet->new(); my $action = POSIX::SigAction->new( $sub, $sigset, &POSIX::SA_NODEFER ); POSIX::sigaction(&POSIX::SIGINT, $action); print (++$counter), sleep 1 while 1
      In your reworking of the perlipc example, you use HUP and INT interchangeably. Did you intend to use one xor the other?

        Nope ... just a typo. It should one or the other. In the perldocs, they describe HUP but the OP was only interested in INT -- I foobar-ed the example by switching (but in this case it only matters from a maintenance/consistency view -- the signal SIGINT should probably not be handled my a method named sigHUP!).

        -derby
Re: Can't catch signals after an exec?
by sh1tn (Priest) on Mar 19, 2005 at 10:47 UTC
    The signals are catched each time, not only once.
    With exec() this program replaces itself with itself($0) thus starting a fresh copy:
    $sub = sub { exec "perl $0" }; $SIG{INT} = $sub; $SIG{USR1} = $sub; $|++; print (++$counter), sleep 1 while 1 # E:\kod>exec.pl ###>Ctrl+C # 1234567 # E:\kod>123 ###>Ctrl+C # E:\kod>123 ###>Ctrl+C # E:\kod>123 ###>Ctrl+C # E:\kod>1234567
    obviously useless code ... my mistake to take ones time ...


Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://440900]
Approved by bart
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-04-18 22:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found