Sorry for the late reply. My family life took away to much of my hacking time recently. Eric Brine <ikegami@adaelis.com> wrote: > Fixes (1) and (2): Yes, I didn't see (1) and did not consider (2) to be an issue because in every case I used it it was not. Certainly, that doesn't mean anything ;-) Thinking about your solution I wonder whether it's a good idea to introduce use subs and open3 in a documentation on wait() and SIGCHLD handling. Especially, since the documentation mainly addresses newbies like me and it took me half an hour to _really_ get the feeling of understanding it. This means an additional explanation of the code example would be needed even though an example should be as self explaining as possible. Thus, I still favour the idea of using non blocking waitpid. This still leaves us with two possible race conditions. The issue there is the fact that calling waitpid(-1, WNOHANG) could occasionally return the pid of system's child. 1.) We could ignore that fact and try to cleanup for a child that is not cleanable. 2.) Safe the pid returned by fork, only cleanup when waitpid returns a saved pid and live with the fact that the child could die before we got the chance to save it's pid for the signal handler (thus not cleaning up even though we should). This cleanup might include closing IPC handles. I'm not sure whether your approach handles this correctly. I think it does not. The example below follows the second approach. use POSIX ":sys_wait_h"; # for nonblocking read my %children; $SIG{CHLD} = sub { # don't change $! and $? outside handler local ($!,$?); my $pid = waitpid(-1, WNOHANG); return if $pid == -1; return unless defined $children{$pid}; delete $children{$pid}; cleanup_child($pid, $?); }; while(1){ my $pid = fork(); if ($pid == 0){ ... exit 0; } else { $children{$pid}=1; ... system($command); ... } } Thanks for your comments, so long MaikThread Previous | Thread Next