From c0ad4ea54c2df6ab594c10ec581e30543b8b0df1 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sat, 12 Feb 2011 19:53:24 +0100 Subject: [PATCH] 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) --- src/ChangeLog | 5 +++++ src/callproc.c | 32 ++++++++++++++++++++++++++++++++ src/process.c | 6 ++++++ 3 files changed, 43 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index 04b0a34d513..8ba7b61290e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2011-02-12 Andreas Schwab + + * process.c (create_process): Reset SIGPIPE handler in the child. + * callproc.c (Fcall_process): Likewise. (Bug#5238) + 2011-02-12 Eli Zaretskii * xdisp.c : New variable. 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. */ diff --git a/src/process.c b/src/process.c index 80e70e49f8e..d026b9d030b 100644 --- a/src/process.c +++ b/src/process.c @@ -1786,6 +1786,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) sigset_t blocked; struct sigaction sigint_action; struct sigaction sigquit_action; + struct sigaction sigpipe_action; #ifdef AIX struct sigaction sighup_action; #endif @@ -1898,6 +1899,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) 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); + sigaddset (&blocked, SIGPIPE); sigaction (SIGPIPE, 0, &sigpipe_action); #ifdef AIX sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action ); #endif @@ -2054,6 +2056,9 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) signal (SIGINT, SIG_DFL); signal (SIGQUIT, SIG_DFL); + /* GTK causes us to ignore SIGPIPE, make sure it is restored + in the child. */ + signal (SIGPIPE, SIG_DFL); /* Stop blocking signals in the child. */ sigprocmask (SIG_SETMASK, &procmask, 0); @@ -2142,6 +2147,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) /* Restore the parent's signal handlers. */ sigaction (SIGINT, &sigint_action, 0); sigaction (SIGQUIT, &sigquit_action, 0); + sigaction (SIGPIPE, &sigpipe_action, 0); #ifdef AIX sigaction (SIGHUP, &sighup_action, 0); #endif -- 2.39.5