diff options
author | Andreas Schwab <schwab@linux-m68k.org> | 2011-02-12 19:53:24 +0100 |
---|---|---|
committer | Andreas Schwab <schwab@linux-m68k.org> | 2011-02-12 19:53:24 +0100 |
commit | c0ad4ea54c2df6ab594c10ec581e30543b8b0df1 (patch) | |
tree | 689102bee9424c03fb1c7b01fed4cd21134be7c9 /src/callproc.c | |
parent | e2784c87183787f8d5bffb0cf10e08fabe02ff91 (diff) | |
download | emacs-c0ad4ea54c2df6ab594c10ec581e30543b8b0df1.tar.gz |
Make sure SIGPIPE is reset in child processes
* process.c (create_process): Reset SIGPIPE handler in the child.
* callproc.c (Fcall_process): Likewise. (Bug#5238)
Diffstat (limited to 'src/callproc.c')
-rw-r--r-- | src/callproc.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/callproc.c b/src/callproc.c index 925eefb4b02..27e8493bcf1 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -445,6 +445,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) register char **save_environ = environ; register int fd1 = fd[1]; int fd_error = fd1; +#ifdef HAVE_WORKING_VFORK + sigset_t procmask; + sigset_t blocked; + struct sigaction sigpipe_action; +#endif #if 0 /* Some systems don't have sigblock. */ mask = sigblock (sigmask (SIGCHLD)); @@ -525,6 +530,18 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) pid = child_setup (filefd, fd1, fd_error, (char **) new_argv, 0, current_dir); #else /* not WINDOWSNT */ + +#ifdef HAVE_WORKING_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. */ + sigemptyset (&blocked); + sigaddset (&blocked, SIGPIPE); + sigaction (SIGPIPE, 0, &sigpipe_action); + sigprocmask (SIG_BLOCK, &blocked, &procmask); +#endif + BLOCK_INPUT; pid = vfork (); @@ -541,11 +558,26 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) #else setpgrp (pid, pid); #endif /* USG */ + + /* GTK causes us to ignore SIGPIPE, make sure it is restored + in the child. */ + signal (SIGPIPE, SIG_DFL); +#ifdef HAVE_WORKING_VFORK + sigprocmask (SIG_SETMASK, &procmask, 0); +#endif + child_setup (filefd, fd1, fd_error, (char **) new_argv, 0, current_dir); } UNBLOCK_INPUT; + +#ifdef HAVE_WORKING_VFORK + /* Restore the signal state. */ + sigaction (SIGPIPE, &sigpipe_action, 0); + sigprocmask (SIG_SETMASK, &procmask, 0); +#endif + #endif /* not WINDOWSNT */ /* The MSDOS case did this already. */ |