diff options
author | Karl Heuer <kwzh@gnu.org> | 1995-12-13 01:52:07 +0000 |
---|---|---|
committer | Karl Heuer <kwzh@gnu.org> | 1995-12-13 01:52:07 +0000 |
commit | 44a05b4f323ccbd8af61c50d27bbb19b73bdcdb7 (patch) | |
tree | aef6a1408f62e0d36c1c2cf40f8cb69834368684 | |
parent | d02091aa57a68f77d3514934046c4f4407ea71aa (diff) | |
download | emacs-44a05b4f323ccbd8af61c50d27bbb19b73bdcdb7.tar.gz |
(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.
-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 e2e337f90df..115eb8faca4 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 */ |