On Thu, Apr 22, 2010 at 2:44 PM, Maik Hentsche <maik@mm-double.de> wrote: > and I don't see any new issues. 1. You removed the race condition by removing the functionality that caused it. There's now no way of getting the status returned by system. Yeah, you get the status of your children back, but you have no idea if it's from the system child, so you can't act on it appropriately. 2. Another added issue is that it delays handling of the death of non-system children to the next time system is called. Fixes (2) but not (1): use subs qw( system ); $SIG{CHLD} = sub { my $pid = wait(); cleanup_child($pid) if $pid != 1; }; sub system { # open3 closes <& handles open(local *TO_CHLD, '<&STDIN'); my $pid = open3('<&TO_CHLD', '>&STDOUT', '>&STDERR', @_); cleanup_child($pid) if waitpid($pid, 0) != -1; } while(1){ my $pid = fork(); if ($pid == 0){ ... exit 0; } else { ... system($command); ... } } Fixes (1) and (2): use subs qw( system ); my %exit_codes; $SIG{CHLD} = sub { local ($!,$?); my $pid = wait(); return if $pid == -1; $exit_codes{$pid} = $?; cleanup_child($pid); }; sub system { # open3 closes <& handles open(local *TO_CHLD, '<&STDIN'); my $pid = open3('<&TO_CHLD', '>&STDOUT', '>&STDERR', @_); return waitpid($pid, 0) == -1 ? delete($exit_codes{$pid}) : $?; } while(1){ my $pid = fork(); if ($pid == 0){ ... exit 0; } else { ... system($command); ... } }Thread Previous | Thread Next