diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2015-04-08 03:09:47 +0000 |
---|---|---|
committer | <> | 2015-05-05 14:37:32 +0000 |
commit | f2541bb90af059680aa7036f315f052175999355 (patch) | |
tree | a5b214744b256f07e1dc2bd7273035a7808c659f /tools/build/src/engine/execunix.c | |
parent | ed232fdd34968697a68783b3195b1da4226915b5 (diff) | |
download | boost-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.c | 44 |
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; } |