Jim, Thank you! This was a big help to me in that I ran into this problem from two directions recently, with a perl daemon and with Apache::SIG.. I did find some info about fixing this for real rather than using unsafe signals. They mostly seemed to point to using the POSIX sigaction methods rather Perl's.
I did end up getting my daemon to work without either dying after the first command or spawning endless children that would not die, those were my two choices before :) Only a part of this was related to the signal problem, but it was the hard part for a while. The child signal was what was causing me big problems. I know this is far from a complete answer, but I hope it might send someone off on the right path if they don't want to set the ENV var. I was worried about doing it that way, because what happens a year from now when I upgrade my server and we somehow forget about that little detail? I know me and I will manage to mess it up if I can :) Below are some examples from the POSIX module, it should work :). I found most of this somewhere when doing research on perl daemons but the child one I added on and I am currently using all of the below, I just did some cutting of other things. use POSIX (); use POSIX 'WNOHANG'; use FindBin (); use File::Basename (); use File::Spec::Functions; my $script = File::Basename::basename($0); my $SELF = catfile $FindBin::Bin, $script; my $sigset = POSIX::SigSet->new(); my $action = POSIX::SigAction->new('sigHUP_handler', $sigset, &POSIX::SA_NODEFER); my $action_alrm = POSIX::SigAction->new('sigALRM_handler', $sigset, &POSIX::SA_NODEFER); my $action_child = POSIX::SigAction->new('sigCHLD_handler', $sigset, &POSIX::SA_NODEFER); POSIX::sigaction(&POSIX::SIGHUP, $action); POSIX::sigaction(&POSIX::SIGALRM, $action_alrm); POSIX::sigaction(&POSIX::SIGCHLD, $action_child); sub sigHUP_handler { print "got SIGHUP\n"; exec($SELF, @ARGV) or die "Couldn't restart: $!\n"; } sub sigALRM_handler { print "got ALARM timeout\n"; } sub sigCHLD_handler { while (my $reaperpid = waitpid(-1,WNOHANG)>0) { } } ## do your while (1) and fork etc... I wish I could paste in my whole daemon thing, but it is too far along with to many things specific to my bosses application.. Thanks, Eric At 02:55 PM 6/15/2004, Jim Albert wrote: >Last week I had a problem where I could not get my Apache2/mod_perl2/perl5.8.3 web >server to catch a SIGPIPE signal in a timely manner. I was asked to post a >description of this problem and solution to this list so that it might be included in >future mod_perl documentation. > >Feel free to adjust this description as necessary when integrating it into the >appropriate documentation. > >The Problem: >Use a PerlFixupHandler to catch when the pipe from browser to httpd server has been >broken such as when the user presses the browser stop button. > >In conf.d/perl.conf >PerlFixupHandler Apache::SIG2 > >where Apache::SIG2.pm is defined in this example as: > >---------- >package Apache::SIG2; > ># This package adapted by Jim Albert from the original mod_perl1 ># Apache::SIG.pm by Doug MacEachern and Doug Bagley ># This PerlHandler can be used to prevent httpd children from killing ># off non-mod-perled CGIs when the user presses the Stop button. > >use strict; >use Apache::RequestRec; >use ModPerl::Util; >use Apache::Const; > >sub handler { > my $r = shift; > if (!$r->main) { > $SIG{PIPE} = \&PIPE; > } > > return OK; >} > >sub PIPE { > my($signal) = @_; > print STDERR ("User pressed stop button.\n"); > # Kill off the httpd child before it can kill any running CGIs. > # Or do whatever other cleanup is appropriate. > CORE::exit(); >} > >1; >---------- > >With the introduction of perl 5.8.0, this handler no longer works as expected because >of the introduction of perl safe signals. >See: >http://www.perldoc.com/perl5.8.4/pod/perlipc.html#Deferred-Signals-(Safe-Signals) > >What happens with perl 5.8 and safe signals is that the apache httpd child does >receive the SIGPIPE, but it is delayed and the perl CGI program has already been >killed. The httpd child does not act on the SIGPIPE until it receives the next httpd >request. > >The Solution: >An Apache server_startup.pl script can be used to turn off perl safe signals with the >following line: >$ENV{PERL_SIGNALS} = "unsafe"; >The server_startup.pl script can be included via the following line in perl.conf: >PerlRequire conf/server_startup.pl >The ability to revert back to "unsafe" signals is available as of perl 5.8.1. > >-- >Jim Albert > > > >-- >Report problems: http://perl.apache.org/bugs/ >Mail list info: http://perl.apache.org/maillist/modperl.html >List etiquette: http://perl.apache.org/maillist/email-etiquette.html -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html