summaryrefslogtreecommitdiff
path: root/src/callproc.c
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@linux-m68k.org>2011-02-12 19:53:24 +0100
committerAndreas Schwab <schwab@linux-m68k.org>2011-02-12 19:53:24 +0100
commitc0ad4ea54c2df6ab594c10ec581e30543b8b0df1 (patch)
tree689102bee9424c03fb1c7b01fed4cd21134be7c9 /src/callproc.c
parente2784c87183787f8d5bffb0cf10e08fabe02ff91 (diff)
downloademacs-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.c32
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. */