M
Moritz Karbach
....such that it doesn't become a zombie?
Hi,
I'm trying to implement something like this:
parent
|
|
|\ fork
| \
| \
| | child calls an system command,
| | exec("foo");
| |
fork /| |
/ | |
/ | |
watch- | | |
dog | | |
kills | | -
foo - |
|
|
But everytime the watchdog kills the child, the child becomes a zombie. Is
there a way to prevent this?
Here is some code (the run-function of my Command-class, which handles
system calls):
sub runFork # ()
{
my $this = shift;
my $fh_child; # pipe to the child process running the command
$pid = fork;
die "cannot fork: $!\n" unless defined($pid);
if ( $pid == 0 )
{
#
# child (command branch)
#
my @temp = ($EUID, $EGID);
my $orig_uid = $UID;
my $orig_gid = $GID;
$EUID = $UID;
$EGID = $GID;
# Drop privileges
$UID = $orig_uid;
$GID = $orig_gid;
# Make sure privs are really gone
($EUID, $EGID) = @temp;
die "Can't drop privileges"
unless $UID == $EUID && $GID eq $EGID;
open(STDERR, ">&STDOUT") or die "Can't dup STDOUT: $!";
$SIG{TTIN} = "IGNORE";
$SIG{TTOU} = "IGNORE";
$SIG{CHLD} = "IGNORE";
$SIG{CLD} = "IGNORE";
setpgrp(0,0);
exec($this->{command}) or die ("cannot run program: $!");
exit;
}
#
# fork once more for the watchdog for the timeout
#
my $wdog_id;
$wdog_id = fork;
die "cannot fork: $!\n" unless defined($wdog_id);
if ( $wdog_id == 0 )
{
#
# child - watchdog branch
#
$SIG{TTIN} = "IGNORE";
$SIG{TTOU} = "IGNORE";
$SIG{CHLD} = "IGNORE";
$SIG{CLD} = "IGNORE";
setpgrp(0,0);
sleep($this->{timeout});
kill(-9, $pid);
#`kill -9 $pid`;
exit;
}
#
# read output of the command
#
my @output = <$fh_child>;
close($fh_child);
$this->{output} = \@output;
#
# return value of the command
#
$this->{ret} = $?;
my $sig = $this->{ret} & 127;
#
# if command succeeded, we don't need the watchdog any more: kill!
#
if ( defined($wdog_id) && $sig != 9 )
{
kill(-9, $wdog_id);
}
return $this->{ret};
}
Hi,
I'm trying to implement something like this:
parent
|
|
|\ fork
| \
| \
| | child calls an system command,
| | exec("foo");
| |
fork /| |
/ | |
/ | |
watch- | | |
dog | | |
kills | | -
foo - |
|
|
But everytime the watchdog kills the child, the child becomes a zombie. Is
there a way to prevent this?
Here is some code (the run-function of my Command-class, which handles
system calls):
sub runFork # ()
{
my $this = shift;
my $fh_child; # pipe to the child process running the command
$pid = fork;
die "cannot fork: $!\n" unless defined($pid);
if ( $pid == 0 )
{
#
# child (command branch)
#
my @temp = ($EUID, $EGID);
my $orig_uid = $UID;
my $orig_gid = $GID;
$EUID = $UID;
$EGID = $GID;
# Drop privileges
$UID = $orig_uid;
$GID = $orig_gid;
# Make sure privs are really gone
($EUID, $EGID) = @temp;
die "Can't drop privileges"
unless $UID == $EUID && $GID eq $EGID;
open(STDERR, ">&STDOUT") or die "Can't dup STDOUT: $!";
$SIG{TTIN} = "IGNORE";
$SIG{TTOU} = "IGNORE";
$SIG{CHLD} = "IGNORE";
$SIG{CLD} = "IGNORE";
setpgrp(0,0);
exec($this->{command}) or die ("cannot run program: $!");
exit;
}
#
# fork once more for the watchdog for the timeout
#
my $wdog_id;
$wdog_id = fork;
die "cannot fork: $!\n" unless defined($wdog_id);
if ( $wdog_id == 0 )
{
#
# child - watchdog branch
#
$SIG{TTIN} = "IGNORE";
$SIG{TTOU} = "IGNORE";
$SIG{CHLD} = "IGNORE";
$SIG{CLD} = "IGNORE";
setpgrp(0,0);
sleep($this->{timeout});
kill(-9, $pid);
#`kill -9 $pid`;
exit;
}
#
# read output of the command
#
my @output = <$fh_child>;
close($fh_child);
$this->{output} = \@output;
#
# return value of the command
#
$this->{ret} = $?;
my $sig = $this->{ret} & 127;
#
# if command succeeded, we don't need the watchdog any more: kill!
#
if ( defined($wdog_id) && $sig != 9 )
{
kill(-9, $wdog_id);
}
return $this->{ret};
}