From 23aa013e45eba1203009d5c74cfccdbfced6d35c Mon Sep 17 00:00:00 2001 From: "K. Noel Belcourt" Date: Fri, 8 Feb 2008 16:32:35 +0000 Subject: [PATCH] Force PPC Darwin to use fork instead of vfork. This change requires both the parent and child process to explicitly set the process group id. Vfork guarantees the child process runs to the exec before it releases the parent process. Now that we use fork instead of vfork, it's possible for the parent to wait on the child process without having the child setpgid on itself. This eliminates spurious hangs on ppc darwin caused by either a race condition between vfork and execvp, or a bug in the vfork implementation. Added a test to ensure we don't try to read from the stderr pipe descriptor if the descriptor's not valid. [SVN r43176] --- src/engine/execunix.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/engine/execunix.c b/src/engine/execunix.c index 15711896e..f651c61a8 100644 --- a/src/engine/execunix.c +++ b/src/engine/execunix.c @@ -25,6 +25,10 @@ # ifdef USE_EXECUNIX # include +# if defined(__APPLE__) && defined(__ppc__) +# define NO_VFORK +# endif + # ifdef NO_VFORK # define vfork() fork() # endif @@ -211,6 +215,8 @@ execcmd( if ((cmdtab[slot].pid = vfork()) == 0) { + int pid = getpid(); + close(out[0]); close(err[0]); @@ -239,17 +245,19 @@ execcmd( r_limit.rlim_max = globs.timeout; setrlimit(RLIMIT_CPU, &r_limit); } - setpgid(cmdtab[slot].pid, cmdtab[slot].pid); - - execvp( argv[0], argv ); - _exit(127); - } + setpgid(pid,pid); + execvp( argv[0], argv ); + perror( "execvp" ); + _exit(127); + } else if( cmdtab[slot].pid == -1 ) { perror( "vfork" ); exit( EXITBAD ); } + setpgid(cmdtab[slot].pid, cmdtab[slot].pid); + /* close write end of pipes */ close(out[1]); close(err[1]); @@ -458,7 +466,7 @@ execwait() if (FD_ISSET(cmdtab[i].fd[OUT], &fds)) out = read_descriptor(i, OUT); - if (FD_ISSET(cmdtab[i].fd[ERR], &fds)) + if ((globs.pipe_action != 0) && (FD_ISSET(cmdtab[i].fd[ERR], &fds))) err = read_descriptor(i, ERR); /* if feof on either descriptor, then we're done */