in reply to $? is -1???

After you fork off the children is the parent using stuff like system/backticks/qx/etc? I've seen cases in the past where my SIGCHLD reaped the child of a system() call (and I wouldn't be surprised if system() on some machines could reap a child I forked as well). These resulted in the '-1' being returned.

Since I'm paranoid about signal handlers and I tend to have code where the parent just hangs around waiting for the children, I don't usually install SIGCHLD, but just loop with waitpid/sleep on the PIDs I care about. If you don't have this luxury, try changing your waitpid to just wait for the pid's you care about.

Replies are listed 'Best First'.
Re^2: $? is -1???
by kscaldef (Pilgrim) on Jun 21, 2004 at 21:59 UTC

    No, the parent just waits around doing nothing (except sleeping).

    On your advice, I tried removing the SIGCHLD handler, but taking the contents into the wait loop in the parent, so it now does:

    while ($children) { while ((my $pid = waitpid(-1, &WNOHANG)) > 0) { print "$?\n" if $?; delete $children{$pid}; $children--; print "$children children running\n"; } sleep; }

    where it used to just sleep

    However, this never terminated for me. My child processes become zombies and waitpid() never gives me anything back and I just loop forever. I also tried looping through the keys of the %children hash and waiting on each PID, but that didn't work any better for me. Am I misunderstanding something about your technique?

      With no arguments, the call to 'sleep' will sleep forever. Try something like 'sleep 1'.

      Is there a reason you are using WNOHANG? It seems like you could just use the blocking form of waitpid (unless I'm missing something).

      Other than that this looks ok. The main reason I mentioned waiting on each individual pid was that this comes in handy if your parent actually did use something like system().

        Whoops! That was dumb.

        I put in the '1' and I also took out the WNOHANG since, as you point out, it isn't needed here. (I just copied from my signal handler, where it is desirable.)

        Now it seems to work completely as expected. I'm still curious as to why the signal handler has this wierd behavior, but I'm guessing the answer is that the docs that claim that post-5.7.3 has safely reentrant signal handling are not quite correct.

        Thanks!