Messages in this thread |  | | Subject | Re: linux bug in pclose | Date | Sat, 13 Jul 1996 08:42:13 +0200 | From | Michiel Boland <> |
| |
On versions before 2.0.1, SIGCHLD used to be discarded when a process calls any of the wait() functions. This is no longer the case, and is, as far as I can see, correct behaviour.
In past-2.0.0 kernels SIGCHLD is never lost. That means that it is still delivered when one calls system(), popen/pclose. Ergo: you have to be a bit more careful inside the signal handler and do proper error checking and stuff.
In pre-2.0.1, this is what happens with your program: fork() creates the first child popen() creates the second child pclose() waits for the second child to exit; SIGCHLD gets discarded, the handler is not called. When the first child exits, the signal handler is called; nbpgm is decreased, and the program exits.
In post-2.0.1, we now have this behaviour: fork() creates the first child popen() creates the second child pclose() waits for second child; SIGCHLD is not discarded, handler is called, nbpgm is mistakenly decreased, program exits. The first child keeps running, but will now also get a SIGCHLD when the system() finishes. But since system() has already waited for *its* child process, wait() now returns -1. This explains the mysterious `pid -1'.
So, to fix your program, you should check inside the SIGCHLD handler *what* child has exited, and realize that wait() may return -1 when someone else already waited for the child.
Hope this has made matters clearer. -- Michiel Boland <boland@sci.kun.nl> University of Nijmegen The Netherlands
|  |