in reply to Detecting when a child process is killed unexpectedly
Two main problems that I see:
1) A faulty assumption that the process exit code covers
the 'death by signal' case.
2) Missing parentheses on the exists statements, giving
the wrong precedence.
Here is code which covers all cases hopefully:
#!/usr/bin/perl use strict; use warnings; use diagnostics; use POSIX ":sys_wait_h"; use Data::Dumper; my %child_status; sub reaper { my $child; while (($child=waitpid(-1,WNOHANG))>0) { # See waitpid(2) and POSIX(3perl) my $status = $?; my $wifexited = WIFEXITED($status); my $wexitstatus = $wifexited ? WEXITSTATUS($status) : undef; my $wifsignaled = WIFSIGNALED($status); my $wtermsig = $wifsignaled ? WTERMSIG($status) : undef; my $wifstopped = WIFSTOPPED($status); my $wstopsig = $wifstopped ? WSTOPSIG($status) : undef; $child_status{$child} = { status => $status, wifexited => $wifexited, wexitstatus => $wexitstatus, wifsignaled => $wifsignaled, wtermsig => $wtermsig, wifstopped => $wifstopped, wstopsig => $wstopsig, }; print STDERR "reaper: reaped child=$child" ." status=$status" ." wifexited=$wifexited" ." wexitstatus=".(defined($wexitstatus) ? $wexitstatus : " +undef") ." wifsignaled=$wifsignaled" ." wtermsig=".(defined($wtermsig) ? $wtermsig : "undef") ." wifstopped=$wifstopped" ." wstopsig=".(defined($wstopsig) ? $wstopsig : "undef") ."\n"; } } sub copy { my $file = shift; my $dir = shift; local $SIG{CHLD} = \&reaper; my $reader_pid = open( my $reader, '-|' ); if ($reader_pid) { print STDERR "copy: spawned reader child=\"$reader_pid\"\n"; } else { exec '/bin/cat', $file; exit; } my $writer_pid; if ($writer_pid = fork()) { print STDERR "copy: spawned writer child=\"$writer_pid\"\n"; } else { chdir($dir); open( STDIN, "<&=" . fileno($reader) ); exec '/bin/tar', '-x', '-p', '-f', '-'; exit; } while (1) { sleep 1; next if !%child_status; foreach my $pid ($reader_pid, $writer_pid) { if (exists $child_status{$pid}) { my $st = $child_status{$pid}; # check for non-zero exit status # check for death by signal if (($st->{wifexited} && $st->{wexitstatus} != 0) || $st->{wifsignaled}) { print Dumper \%child_status; die "failed ".($pid == $writer_pid ? "tar" : "rea +der"); } } } if (exists($child_status{$writer_pid}) && exists($child_status +{$reader_pid})) { last; } } } copy("/home/tmp/quotes.tar","."); exit 0;
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Precedence/Prototypes - Re^2: Detecting when a child process is killed unexpectedly
by jakobi (Pilgrim) on Oct 17, 2009 at 10:05 UTC | |
by gmargo (Hermit) on Oct 17, 2009 at 15:55 UTC | |
by jakobi (Pilgrim) on Oct 17, 2009 at 16:11 UTC | |
by rlb3 (Deacon) on Oct 19, 2009 at 21:30 UTC |