| From: Dave Anderson <anderson@xxxxxxxxxx> | Yeah, but I'm still paranoid about re-introducing the hang I used | to see. | | I think I'll just put a "stall(1000);" call after each waitpid(). | Works for me... I take that as a challenge. I think that I've eliminated this busy-wait and simplified the code. I admit that wait_for_children is slightly more complicated. In light testing this worked fine. I'd really like to find out how this is going to hang. I promise to attempt to debug any hang that I can duplicate. =================================================================== RCS file: RCS/cmdline.c,v retrieving revision 1.1 diff -u -r1.1 cmdline.c --- cmdline.c 2007/07/10 19:30:01 1.1 +++ cmdline.c 2007/07/10 20:16:57 @@ -31,6 +31,7 @@ static void set_my_tty(void); static char *signame(int); static int setup_stdpipe(void); +static void wait_for_child(pid_t *); static void wait_for_children(ulong); #define ZOMBIES_ONLY (1) #define ALL_CHILDREN (2) @@ -878,25 +879,15 @@ if (pc->stdpipe) { close(fileno(pc->stdpipe)); pc->stdpipe = NULL; - if (pc->stdpipe_pid && PID_ALIVE(pc->stdpipe_pid)) { - while (!waitpid(pc->stdpipe_pid, &waitstatus, WNOHANG)) - ; - } - pc->stdpipe_pid = 0; + wait_for_child(&pc->stdpipe_pid); } if (pc->pipe) { close(fileno(pc->pipe)); pc->pipe = NULL; console("wait for redirect %d->%d to finish...\n", pc->pipe_shell_pid, pc->pipe_pid); - if (pc->pipe_pid) - while (PID_ALIVE(pc->pipe_pid)) - waitpid(pc->pipe_pid, &waitstatus, WNOHANG); - if (pc->pipe_shell_pid) - while (PID_ALIVE(pc->pipe_shell_pid)) - waitpid(pc->pipe_shell_pid, - &waitstatus, WNOHANG); - pc->pipe_pid = 0; + wait_for_child(&pc->pipe_pid); + wait_for_child(&pc->pipe_shell_pid); } if (pc->ifile_pipe) { fflush(pc->ifile_pipe); @@ -907,12 +898,8 @@ (FROM_INPUT_FILE|REDIRECT_TO_PIPE|REDIRECT_PID_KNOWN))) { console("wait for redirect %d->%d to finish...\n", pc->pipe_shell_pid, pc->pipe_pid); - while (PID_ALIVE(pc->pipe_pid)) - waitpid(pc->pipe_pid, &waitstatus, WNOHANG); - if (pc->pipe_shell_pid) - while (PID_ALIVE(pc->pipe_shell_pid)) - waitpid(pc->pipe_shell_pid, - &waitstatus, WNOHANG); + wait_for_child(&pc->pipe_pid); + wait_for_child(&pc->pipe_shell_pid); if (pc->redirect & (REDIRECT_MULTI_PIPE)) wait_for_children(ALL_CHILDREN); } @@ -1967,7 +1954,7 @@ if (CRASHDEBUG(2)) console("pipe: %lx\n", pc->stdpipe); - return TRUE;; + return TRUE; } else { close(pc->pipefd[1]); /* child closes write end */ @@ -1998,13 +1985,26 @@ } } +static void +wait_for_child(pid_t *chp) +{ + if (*chp != 0) + { + int waitstatus; + + do ; while (waitpid(*chp, &waitstatus, 0) == -1 && errno == EINTR); + *chp = 0; + } +} + static void wait_for_children(ulong waitflag) { - int status, pid; - while (TRUE) { - switch (pid = waitpid(-1, &status, WNOHANG)) + int status; + pid_t pid = waitpid(-1, &status, waitflag==ZOMBIES_ONLY? WNOHANG : 0); + + switch (pid) { case 0: if (CRASHDEBUG(2)) @@ -2014,6 +2014,8 @@ break; case -1: + if (errno == EINTR) + continue; if (CRASHDEBUG(2)) console("wait_for_children: no children alive\n"); return; ================ end ================ -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility