Mercurial > emacs
changeset 13709:d16f31ae8adf
(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.
author | Karl Heuer <kwzh@gnu.org> |
---|---|
date | Wed, 13 Dec 1995 01:52:07 +0000 |
parents | a3b8903f3de0 |
children | 8b76d57dd26d |
files | src/process.c |
diffstat | 1 files changed, 50 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/process.c Wed Dec 13 01:51:37 1995 +0000 +++ b/src/process.c Wed Dec 13 01:52:07 1995 +0000 @@ -1197,9 +1197,19 @@ { 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 @@ /* 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 @@ #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 @@ #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 @@ #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 @@ #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 @@ #endif /* ordinary USG */ #endif /* not BSD4_1 */ #endif /* SIGCHLD */ +#endif /* !POSIX_SIGNALS */ } #endif /* not VMS */