in reply to Signal Question

I'm guessing the second signal is only handled after the handler returns from handling the first signal, at which point local $SIG{$sig} has already been unwound. That should be easy to verify by putting a print at the top of handlesig and another at the bottom.

Replies are listed 'Best First'.
Re^2: Signal Question (mirror)
by tye (Sage) on Nov 30, 2006 at 00:41 UTC

    That makes sense to me. Trying to think of a solution, the first thing I came up with that would probably work is to write a signal reflector.

    sub spawn { my $pid; if( $^O =~ /Win32/ ) { $pid= system( 1, @_ ); } else { # do something more complex with fork() and exec() # since Perl doesn't provide a portable way to spawn } return $pid; } my $mirror= spawn( $^X, 'mirror.pl', $$ ); my @sigs; $SIG{$_}= \&logSig for keys(%SIG); $SIG{USR1}= \&restoreHandlers; sub logSig { my $sig = shift @_; push @sigs, $sig; syslog( 'info', "Got signal '$sig'" ); $SIG{$sig}= 'DEFAULT'; kill $sig, $mirror; } sub restoreHandlers { my $sig= shift @_; if( ! @sigs ) { syslog( 'info', "Got signal '$sig'" ); } else { $SIG{$_} = \&logsig for @sigs; @sigs= (); } }

    Then mirror.pl would be:

    my $caller= shift @ARGV; $SIG{$_} = \&reflectSig for keys(%SIG); sub reflectSig { my $sig= shift @_; kill $sig, $caller; kill 'USR1', $caller; }

    A bit complex, unfortunately. Of course, if you get sent the same signal twice, you might not log two lines; that is just how signals work.

    In the unlikely event that signals have priorities and when a process has received both a USR1 and some other signal it could decide to process the USR1 before the other (even though the other came in first), that could cause problems.

    - tye