M
Marc Girod
Hello,
I have a nightly build script which forks a lot of processes which may
last long or not.
I wanted to reap them before the end of the script.
This addition made, I lose the exit code of my builds: they all
pretend to fail, which I suspect to be false.
So, I guess I was not able to read the perlipc page correctly.
Here is a short script which behaves in the same way as my nightly
build;
foo:
#!/usr/bin/perl -w
use strict;
use POSIX ":sys_wait_h";
sub child {
system('date');
my $ec = $? >> 8;
warn "Child exit code: $?\n";
exit $ec;
}
my %family;
sub reaper { # from perlipc
local ($!, $?); # don't let waitpid() overwrite current error
my ($prd, $child) = '';
while (($child = waitpid(-1, WNOHANG)) > 0) {
if (exists $family{$child}) {
$prd = $family{$child};
delete $family{$child};
warn "Reaped $prd($child) with exit $?\n";
}
}
$SIG{CHLD} = \&reaper;
}
$SIG{CHLD} = \&reaper;
if (my $pid = fork) {
$family{$pid} = 'date';
} else {
die "cannot fork: $!" unless defined($pid);
child;
}
while (%family) {
foreach my $kid (keys %family) {
delete $family{$kid} if waitpid($kid, WNOHANG);
}
sleep 1;
}
warn "Parent exit\n";
exit 0;
And an example run:
$ ./foo
Wed Sep 15 14:15:17 BST 2010
Child exit code: -1
Reaped date(21287) with exit 65280
Parent exit
So, how to protect the return code?
Thanks,
Marc
I have a nightly build script which forks a lot of processes which may
last long or not.
I wanted to reap them before the end of the script.
This addition made, I lose the exit code of my builds: they all
pretend to fail, which I suspect to be false.
So, I guess I was not able to read the perlipc page correctly.
Here is a short script which behaves in the same way as my nightly
build;
foo:
#!/usr/bin/perl -w
use strict;
use POSIX ":sys_wait_h";
sub child {
system('date');
my $ec = $? >> 8;
warn "Child exit code: $?\n";
exit $ec;
}
my %family;
sub reaper { # from perlipc
local ($!, $?); # don't let waitpid() overwrite current error
my ($prd, $child) = '';
while (($child = waitpid(-1, WNOHANG)) > 0) {
if (exists $family{$child}) {
$prd = $family{$child};
delete $family{$child};
warn "Reaped $prd($child) with exit $?\n";
}
}
$SIG{CHLD} = \&reaper;
}
$SIG{CHLD} = \&reaper;
if (my $pid = fork) {
$family{$pid} = 'date';
} else {
die "cannot fork: $!" unless defined($pid);
child;
}
while (%family) {
foreach my $kid (keys %family) {
delete $family{$kid} if waitpid($kid, WNOHANG);
}
sleep 1;
}
warn "Parent exit\n";
exit 0;
And an example run:
$ ./foo
Wed Sep 15 14:15:17 BST 2010
Child exit code: -1
Reaped date(21287) with exit 65280
Parent exit
So, how to protect the return code?
Thanks,
Marc