Subject: | PreFork[Simple] child exits when system() [or friends] is called |
Hi,
The bug occurs in versions >= 0.84, and has been tested under
mandrakelinux 9.2 and redhatlinux 7.2. It's a bug in the handling of
$SIG{CHLD} in run_child() of PreFork.pm and PreForkSimple.pm. A patch to
fix it is attached.
The script below makes the bug manifest. A child exits and doesn't
execute "print 'second pass';" when system() [or backticks, etc.] is
called. Uncommenting "local $SIG{CHLD};" works around the bug.
# --- BEGIN test.pl
#!/usr/bin/perl -w
use strict;
package MyPackage;
use Net::Server::PreFork;
our @ISA = qw(Net::Server::PreFork);
sub process_request {
# uncomment to work around the sigchld bug
# local $SIG{CHLD};
print 'first pass';
system ('echo foo > /tmp/foo');
print 'second pass';
}
MyPackage->run(port => 10000);
exit;
# --- END test.pl
The perl under mandrakelinux 9.2 is v5.8.1 built for
i386-linux-thread-multi and under redhatlinux 7.2 is v5.6.1 built for
i386-linux.
Cheers,
Sherwin Daganato
diff -Naur Net-Server-0.87.orig/lib/Net/Server/PreFork.pm Net-Server-0.87/lib/Net/Server/PreFork.pm
--- Net-Server-0.87.orig/lib/Net/Server/PreFork.pm 2004-02-15 05:52:50.000000000 +0000
+++ Net-Server-0.87/lib/Net/Server/PreFork.pm 2004-03-11 16:12:12.000000000 +0000
@@ -221,10 +221,11 @@
### restore sigs (turn off warnings during)
$SIG{INT} = $SIG{TERM} = $SIG{QUIT}
- = $SIG{CHLD} = sub {
+ = sub {
$self->child_finish_hook;
exit;
};
+ $SIG{CHLD} = sub { $self->child_finish_hook; wait };
### let pipes take care of themselves
$SIG{PIPE} = sub { $prop->{SigPIPEd} = 1 };
diff -Naur Net-Server-0.87.orig/lib/Net/Server/PreForkSimple.pm Net-Server-0.87/lib/Net/Server/PreForkSimple.pm
--- Net-Server-0.87.orig/lib/Net/Server/PreForkSimple.pm 2003-03-29 20:42:40.000000000 +0000
+++ Net-Server-0.87/lib/Net/Server/PreForkSimple.pm 2004-03-11 16:11:50.000000000 +0000
@@ -177,10 +177,11 @@
### restore sigs (turn off warnings during)
$SIG{INT} = $SIG{TERM} = $SIG{QUIT}
- = $SIG{CHLD} = sub {
+ = sub {
$self->child_finish_hook;
exit;
};
+ $SIG{CHLD} = sub { $self->child_finish_hook; wait };
$self->log(4,"Child Preforked ($$)\n");