diff options
author | Karl Heuer <[email protected]> | 1995-12-13 01:52:07 +0000 |
---|---|---|
committer | Karl Heuer <[email protected]> | 1995-12-13 01:52:07 +0000 |
commit | 0dc70c33a073153c39a62138177d4a42946bb92d (patch) | |
tree | e5f030a21fa5339eaf5dde4c63622748b1c64045 /src/process.c | |
parent | 3ec89604c4f132d39f71f0b06d61d6e733ec2919 (diff) |
(create_process): Use Posix signal handling to
block signals, if available. If HAVE_VFORK, save and restore
signal handlers that the child might change, since in many
systems (e.g. Solaris 2.4) if the child changes the signal
handlers this munges the parent's handler.
Diffstat (limited to 'src/process.c')
-rw-r--r-- | src/process.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/src/process.c b/src/process.c index e2e337f90d..115eb8faca 100644 --- a/src/process.c +++ b/src/process.c @@ -1197,9 +1197,19 @@ create_process (process, new_argv, current_dir) { int pid, inchannel, outchannel; int sv[2]; +#ifdef POSIX_SIGNALS + sigset_t procmask; + sigset_t blocked; + struct sigaction sigint_action; + struct sigaction sigquit_action; +#ifdef AIX + struct sigaction sighup_action; +#endif +#else /* !POSIX_SIGNALS */ #ifdef SIGCHLD SIGTYPE (*sigchld)(); #endif +#endif /* !POSIX_SIGNALS */ /* Use volatile to protect variables from being clobbered by longjmp. */ volatile int forkin, forkout; volatile int pty_flag = 0; @@ -1298,6 +1308,24 @@ create_process (process, new_argv, current_dir) /* Delay interrupts until we have a chance to store the new fork's pid in its process structure */ +#ifdef POSIX_SIGNALS + sigemptyset (&blocked); +#ifdef SIGCHLD + sigaddset (&blocked, SIGCHLD); +#endif +#ifdef HAVE_VFORK + /* On many hosts (e.g. Solaris 2.4), if a vforked child calls `signal', + this sets the parent's signal handlers as well as the child's. + So delay all interrupts whose handlers the child might munge, + and record the current handlers so they can be restored later. */ + sigaddset (&blocked, SIGINT ); sigaction (SIGINT , 0, &sigint_action ); + sigaddset (&blocked, SIGQUIT); sigaction (SIGQUIT, 0, &sigquit_action); +#ifdef AIX + sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action ); +#endif +#endif /* HAVE_VFORK */ + sigprocmask (SIG_BLOCK, &blocked, &procmask); +#else /* !POSIX_SIGNALS */ #ifdef SIGCHLD #ifdef BSD4_1 sighold (SIGCHLD); @@ -1312,6 +1340,7 @@ create_process (process, new_argv, current_dir) #endif /* ordinary USG */ #endif /* not BSD4_1 */ #endif /* SIGCHLD */ +#endif /* !POSIX_SIGNALS */ FD_SET (inchannel, &input_wait_mask); FD_SET (inchannel, &non_keyboard_wait_mask); @@ -1455,6 +1484,13 @@ create_process (process, new_argv, current_dir) #endif #endif /* HAVE_PTYS */ + signal (SIGINT, SIG_DFL); + signal (SIGQUIT, SIG_DFL); + + /* Stop blocking signals in the child. */ +#ifdef POSIX_SIGNALS + sigprocmask (SIG_SETMASK, &procmask, 0); +#else /* !POSIX_SIGNALS */ #ifdef SIGCHLD #ifdef BSD4_1 sigrelse (SIGCHLD); @@ -1468,9 +1504,7 @@ create_process (process, new_argv, current_dir) #endif /* ordinary USG */ #endif /* not BSD4_1 */ #endif /* SIGCHLD */ - - signal (SIGINT, SIG_DFL); - signal (SIGQUIT, SIG_DFL); +#endif /* !POSIX_SIGNALS */ if (pty_flag) child_setup_tty (xforkout); @@ -1521,6 +1555,18 @@ create_process (process, new_argv, current_dir) #endif XPROCESS (process)->tty_name = Qnil; +#ifdef POSIX_SIGNALS +#ifdef HAVE_VFORK + /* Restore the parent's signal handlers. */ + sigaction (SIGINT, &sigint_action, 0); + sigaction (SIGQUIT, &sigquit_action, 0); +#ifdef AIX + sigaction (SIGHUP, &sighup_action, 0); +#endif +#endif /* HAVE_VFORK */ + /* Stop blocking signals in the parent. */ + sigprocmask (SIG_SETMASK, &procmask, 0); +#else /* !POSIX_SIGNALS */ #ifdef SIGCHLD #ifdef BSD4_1 sigrelse (SIGCHLD); @@ -1538,6 +1584,7 @@ create_process (process, new_argv, current_dir) #endif /* ordinary USG */ #endif /* not BSD4_1 */ #endif /* SIGCHLD */ +#endif /* !POSIX_SIGNALS */ } #endif /* not VMS */ |