in reply to Re^3: Protection from zombies
in thread Protection from zombies

First of all, this seems to not play along very well with my code. For some reason (I do many systems and forks), setting a global SIGCHLD handler makes my program behave very badly in ways I'm not willing to debug. Second, I know I could use the handler locally only in the part I shown in the original post, but I'm wondering why the waitpid done by the close of the pipe does not work. Third, and most interesting, here's a C test I wrote:
#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> static char buf[512]; int main() { int pfd[2]; pipe( pfd ); pid_t pid = fork(); if ( pid ) { /* parent */ ssize_t s = read( pfd[0], buf, sizeof(buf) ); waitpid( pid, NULL, 0 ); } else { /* child */ dup2( pfd[1], STDOUT_FILENO ); close( STDOUT_FILENO ); } return 0; }
This is equivalent to the Perl code I wrote in the original post. As strace shows, the parent gets stuck in the read call even if the child closes its stdout. Adding a write of 512 bytes to stdout to the child before it closes it makes the read in the parent return and everything works correctly. But that leaves me with the same question: how can the parent not get stuck in its read if I can't control what the child does?

Replies are listed 'Best First'.
Re^5: Protection from zombies
by nomis80 (Sexton) on May 17, 2005 at 12:50 UTC
    I've found how to make my C code right: in the parent and child, I have to close the ends of the pipe that I won't be using. My code becomes:
    #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> static char buf[512]; int main() { int pfd[2]; pipe( pfd ); pid_t pid = fork(); if ( pid ) { /* parent */ close( pfd[1] ); ssize_t s = read( pfd[0], buf, sizeof(buf) ); waitpid( pid, NULL, 0 ); } else { /* child */ close( pfd[0] ); dup2( pfd[1], STDOUT_FILENO ); close( STDOUT_FILENO ); } return 0; }
    This seems to be bulletproof. How can I get that using Perl?
      Perl probably does that for you. I personally don't want to try to find the code that implements the magic open, though.