summaryrefslogtreecommitdiff
path: root/tools/build/src/engine/execunix.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2015-04-08 03:09:47 +0000
committer <>2015-05-05 14:37:32 +0000
commitf2541bb90af059680aa7036f315f052175999355 (patch)
treea5b214744b256f07e1dc2bd7273035a7808c659f /tools/build/src/engine/execunix.c
parented232fdd34968697a68783b3195b1da4226915b5 (diff)
downloadboost-tarball-master.tar.gz
Imported from /home/lorry/working-area/delta_boost-tarball/boost_1_58_0.tar.bz2.HEADboost_1_58_0master
Diffstat (limited to 'tools/build/src/engine/execunix.c')
-rw-r--r--tools/build/src/engine/execunix.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/tools/build/src/engine/execunix.c b/tools/build/src/engine/execunix.c
index 965e58011..297c00377 100644
--- a/tools/build/src/engine/execunix.c
+++ b/tools/build/src/engine/execunix.c
@@ -137,6 +137,9 @@ void exec_cmd
LIST * shell
)
{
+ struct sigaction ignore, saveintr, savequit;
+ sigset_t chldmask, savemask;
+
int const slot = get_free_cmdtab_slot();
int out[ 2 ];
int err[ 2 ];
@@ -203,6 +206,21 @@ void exec_cmd
if ( globs.pipe_action )
fcntl( err[ EXECCMD_PIPE_READ ], F_SETFD, FD_CLOEXEC );
+ /* ignore SIGINT and SIGQUIT */
+ ignore.sa_handler = SIG_IGN;
+ sigemptyset(&ignore.sa_mask);
+ ignore.sa_flags = 0;
+ if (sigaction(SIGINT, &ignore, &saveintr) < 0)
+ return;
+ if (sigaction(SIGQUIT, &ignore, &savequit) < 0)
+ return;
+
+ /* block SIGCHLD */
+ sigemptyset(&chldmask);
+ sigaddset(&chldmask, SIGCHLD);
+ if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0)
+ return;
+
if ( ( cmdtab[ slot ].pid = vfork() ) == -1 )
{
perror( "vfork" );
@@ -216,6 +234,11 @@ void exec_cmd
/*****************/
int const pid = getpid();
+ /* restore previous signals */
+ sigaction(SIGINT, &saveintr, NULL);
+ sigaction(SIGQUIT, &savequit, NULL);
+ sigprocmask(SIG_SETMASK, &savemask, NULL);
+
/* Redirect stdout and stderr to pipes inherited from the parent. */
dup2( out[ EXECCMD_PIPE_WRITE ], STDOUT_FILENO );
dup2( globs.pipe_action ? err[ EXECCMD_PIPE_WRITE ] :
@@ -236,7 +259,10 @@ void exec_cmd
r_limit.rlim_max = globs.timeout;
setrlimit( RLIMIT_CPU, &r_limit );
}
- setpgid( pid, pid );
+ if (0 != setpgid( pid, pid )) {
+ perror("setpgid(child)");
+ /* exit( EXITBAD ); */
+ }
execvp( argv[ 0 ], (char * *)argv );
perror( "execvp" );
_exit( 127 );
@@ -245,7 +271,9 @@ void exec_cmd
/******************/
/* Parent process */
/******************/
- setpgid( cmdtab[ slot ].pid, cmdtab[ slot ].pid );
+
+ /* redundant call, ignore return value */
+ setpgid(cmdtab[ slot ].pid, cmdtab[ slot ].pid);
/* Parent not need the write pipe ends used by the child. */
close( out[ EXECCMD_PIPE_WRITE ] );
@@ -281,6 +309,11 @@ void exec_cmd
/* Save input data into the selected running commands table slot. */
cmdtab[ slot ].func = func;
cmdtab[ slot ].closure = closure;
+
+ /* restore previous signals */
+ sigaction(SIGINT, &saveintr, NULL);
+ sigaction(SIGQUIT, &savequit, NULL);
+ sigprocmask(SIG_SETMASK, &savemask, NULL);
}
#undef EXECCMD_PIPE_READ
@@ -448,10 +481,17 @@ void exec_wait()
/* select() will wait for I/O on a descriptor, a signal, or timeout. */
{
+ /* disable child termination signals while in select */
int ret;
+ sigset_t sigmask;
+ sigemptyset(&sigmask);
+ sigaddset(&sigmask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &sigmask, NULL);
while ( ( ret = select( fd_max + 1, &fds, 0, 0, ptv ) ) == -1 )
if ( errno != EINTR )
break;
+ /* restore original signal mask by unblocking sigchld */
+ sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
if ( ret <= 0 )
continue;
}