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