mirror of
https://github.com/boostorg/build.git
synced 2026-02-14 00:32:11 +00:00
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]
This commit is contained in:
@@ -25,6 +25,10 @@
|
||||
# ifdef USE_EXECUNIX
|
||||
# include <sys/times.h>
|
||||
|
||||
# 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 */
|
||||
|
||||
Reference in New Issue
Block a user