aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-06-23 17:31:31 -0700
committerPaul Eggert2013-06-23 17:31:31 -0700
commitfa55d2aaa23d5916b87a6980c9606466e07df124 (patch)
tree673a2d3e86802766c2183a8d6f5744722fd73737 /src
parent5e400cb3ed7b0ffc5f166e4cd9c4e18f4e58c14e (diff)
downloademacs-fa55d2aaa23d5916b87a6980c9606466e07df124.tar.gz
emacs-fa55d2aaa23d5916b87a6980c9606466e07df124.zip
A more-conservative workaround for Cygwin SIGCHLD issues.
* callproc.c (Fcall_process): * process.c (create_process): Make sure SIGCHLD is caught before we fork, since Emacs startup no arranges to catch SIGCHLD. * process.c (lib_child_handler): Initialize to null, not to dummy_handler. (catch_child_signal): Allow self to be called lazily. Do nothing if it's already been called. Assume caller has blocked SIGCHLD (all callers do now). * emacs.c (main): Do not catch SIGCHLD here; defer it until just before it's really needed. * nsterm.m (ns_term_init): No need to re-catch SIGCHLD here, since it hasn't been caught yet. Fixes: debbugs:14569
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog17
-rw-r--r--src/callproc.c1
-rw-r--r--src/emacs.c7
-rw-r--r--src/nsterm.m6
-rw-r--r--src/process.c56
5 files changed, 52 insertions, 35 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index f9451711f32..6357491725d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,20 @@
12013-06-23 Paul Eggert <eggert@cs.ucla.edu>
2
3 A more-conservative workaround for Cygwin SIGCHLD issues (Bug#14569).
4 * callproc.c (Fcall_process):
5 * process.c (create_process):
6 Make sure SIGCHLD is caught before we fork,
7 since Emacs startup no arranges to catch SIGCHLD.
8 * process.c (lib_child_handler): Initialize to null, not to
9 dummy_handler.
10 (catch_child_signal): Allow self to be called lazily.
11 Do nothing if it's already been called.
12 Assume caller has blocked SIGCHLD (all callers do now).
13 * emacs.c (main): Do not catch SIGCHLD here; defer it until
14 just before it's really needed.
15 * nsterm.m (ns_term_init): No need to re-catch SIGCHLD here,
16 since it hasn't been caught yet.
17
12013-06-23 Lars Magne Ingebrigtsen <larsi@gnus.org> 182013-06-23 Lars Magne Ingebrigtsen <larsi@gnus.org>
2 19
3 * image.c (compute_image_size): New function to implement 20 * image.c (compute_image_size): New function to implement
diff --git a/src/callproc.c b/src/callproc.c
index f0aa8222342..7db984fa71c 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -613,6 +613,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
613 613
614 block_input (); 614 block_input ();
615 block_child_signal (); 615 block_child_signal ();
616 catch_child_signal ();
616 617
617#ifdef WINDOWSNT 618#ifdef WINDOWSNT
618 pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); 619 pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir);
diff --git a/src/emacs.c b/src/emacs.c
index c5b32c7c0e7..13f6d117ebc 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1257,13 +1257,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1257 tzset (); 1257 tzset ();
1258#endif /* MSDOS */ 1258#endif /* MSDOS */
1259 1259
1260 /* Do this after initializing the memory allocator, since it uses
1261 glib and glib uses malloc. And do it before anything else that
1262 invokes glib, to avoid potential races among glib subthreads in
1263 Cygwin glib. gfilenotify invokes glib, so this can't be delayed
1264 further. */
1265 catch_child_signal ();
1266
1267#ifdef HAVE_GFILENOTIFY 1260#ifdef HAVE_GFILENOTIFY
1268 globals_of_gfilenotify (); 1261 globals_of_gfilenotify ();
1269#endif 1262#endif
diff --git a/src/nsterm.m b/src/nsterm.m
index 93f693fe55e..c88e5034d39 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -4360,12 +4360,6 @@ ns_term_init (Lisp_Object display_name)
4360 4360
4361 [NSApp run]; 4361 [NSApp run];
4362 ns_do_open_file = YES; 4362 ns_do_open_file = YES;
4363
4364#ifdef NS_IMPL_GNUSTEP
4365 /* GNUstep steals SIGCHLD for use in NSTask, but we don't use NSTask.
4366 We must re-catch it so subprocess works. */
4367 catch_child_signal ();
4368#endif
4369 return dpyinfo; 4363 return dpyinfo;
4370} 4364}
4371 4365
diff --git a/src/process.c b/src/process.c
index 6df1bf7eff7..3f062b6db16 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1590,7 +1590,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1590#ifndef WINDOWSNT 1590#ifndef WINDOWSNT
1591 int wait_child_setup[2]; 1591 int wait_child_setup[2];
1592#endif 1592#endif
1593 sigset_t blocked;
1594 int forkin, forkout; 1593 int forkin, forkout;
1595 bool pty_flag = 0; 1594 bool pty_flag = 0;
1596 Lisp_Object lisp_pty_name = Qnil; 1595 Lisp_Object lisp_pty_name = Qnil;
@@ -1685,12 +1684,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1685 encoded_current_dir = ENCODE_FILE (current_dir); 1684 encoded_current_dir = ENCODE_FILE (current_dir);
1686 1685
1687 block_input (); 1686 block_input ();
1688 1687 block_child_signal ();
1689 /* Block SIGCHLD until we have a chance to store the new fork's 1688 catch_child_signal ();
1690 pid in its process structure. */
1691 sigemptyset (&blocked);
1692 sigaddset (&blocked, SIGCHLD);
1693 pthread_sigmask (SIG_BLOCK, &blocked, 0);
1694 1689
1695#ifndef WINDOWSNT 1690#ifndef WINDOWSNT
1696 /* vfork, and prevent local vars from being clobbered by the vfork. */ 1691 /* vfork, and prevent local vars from being clobbered by the vfork. */
@@ -1822,8 +1817,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1822 /* Emacs ignores SIGPIPE, but the child should not. */ 1817 /* Emacs ignores SIGPIPE, but the child should not. */
1823 signal (SIGPIPE, SIG_DFL); 1818 signal (SIGPIPE, SIG_DFL);
1824 1819
1825 /* Stop blocking signals in the child. */ 1820 /* Stop blocking SIGCHLD in the child. */
1826 pthread_sigmask (SIG_SETMASK, &empty_mask, 0); 1821 unblock_child_signal ();
1827 1822
1828 if (pty_flag) 1823 if (pty_flag)
1829 child_setup_tty (xforkout); 1824 child_setup_tty (xforkout);
@@ -1843,8 +1838,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1843 if (pid >= 0) 1838 if (pid >= 0)
1844 XPROCESS (process)->alive = 1; 1839 XPROCESS (process)->alive = 1;
1845 1840
1846 /* Stop blocking signals in the parent. */ 1841 /* Stop blocking in the parent. */
1847 pthread_sigmask (SIG_SETMASK, &empty_mask, 0); 1842 unblock_child_signal ();
1848 unblock_input (); 1843 unblock_input ();
1849 1844
1850 if (pid < 0) 1845 if (pid < 0)
@@ -6125,9 +6120,10 @@ process has been transmitted to the serial port. */)
6125 6120
6126/* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing 6121/* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing
6127 its own SIGCHLD handling. On POSIXish systems, glib needs this to 6122 its own SIGCHLD handling. On POSIXish systems, glib needs this to
6128 keep track of its own children. The default handler does nothing. */ 6123 keep track of its own children. GNUstep is similar. */
6124
6129static void dummy_handler (int sig) {} 6125static void dummy_handler (int sig) {}
6130static signal_handler_t volatile lib_child_handler = dummy_handler; 6126static signal_handler_t volatile lib_child_handler;
6131 6127
6132/* Handle a SIGCHLD signal by looking for known child processes of 6128/* Handle a SIGCHLD signal by looking for known child processes of
6133 Emacs whose status have changed. For each one found, record its 6129 Emacs whose status have changed. For each one found, record its
@@ -7060,7 +7056,10 @@ integer or floating point values.
7060 return system_process_attributes (pid); 7056 return system_process_attributes (pid);
7061} 7057}
7062 7058
7063/* Arrange to catch SIGCHLD if needed. */ 7059/* Arrange to catch SIGCHLD if this hasn't already been arranged.
7060 Invoke this after init_process_emacs, and after glib and/or GNUstep
7061 futz with the SIGCHLD handler, but before Emacs forks any children.
7062 This function's caller should block SIGCHLD. */
7064 7063
7065void 7064void
7066catch_child_signal (void) 7065catch_child_signal (void)
@@ -7072,25 +7071,38 @@ catch_child_signal (void)
7072 return; 7071 return;
7073#endif 7072#endif
7074 7073
7074#ifndef NS_IMPL_GNUSTEP
7075 if (lib_child_handler)
7076 return;
7077#endif
7078
7075#if defined HAVE_GLIB && !defined WINDOWSNT 7079#if defined HAVE_GLIB && !defined WINDOWSNT
7076 /* Tickle glib's child-handling code. Ask glib to wait for Emacs itself; 7080 /* Tickle glib's child-handling code. Ask glib to wait for Emacs itself;
7077 this should always fail, but is enough to initialize glib's 7081 this should always fail, but is enough to initialize glib's
7078 private SIGCHLD handler, allowing the code below to copy it into 7082 private SIGCHLD handler, allowing the code below to copy it into
7079 LIB_CHILD_HANDLER. 7083 LIB_CHILD_HANDLER.
7080 7084
7081 Do this early in Emacs initialization, before glib creates 7085 Do this here, rather than early in Emacs initialization where it
7082 threads, to avoid race condition bugs in Cygwin glib. */ 7086 might make more sense, to try to avoid bugs in Cygwin glib (Bug#14569). */
7083 g_source_unref (g_child_watch_source_new (getpid ())); 7087 {
7088 GSource *source = g_child_watch_source_new (getpid ());
7089 g_source_unref (source);
7090 }
7084#endif 7091#endif
7085 7092
7086 emacs_sigaction_init (&action, deliver_child_signal); 7093 emacs_sigaction_init (&action, deliver_child_signal);
7087 block_child_signal ();
7088 sigaction (SIGCHLD, &action, &old_action); 7094 sigaction (SIGCHLD, &action, &old_action);
7089 eassert (! (old_action.sa_flags & SA_SIGINFO)); 7095 eassert (! (old_action.sa_flags & SA_SIGINFO));
7090 if (old_action.sa_handler != SIG_DFL && old_action.sa_handler != SIG_IGN 7096
7091 && old_action.sa_handler != deliver_child_signal) 7097#ifdef NS_IMPL_GNUSTEP
7092 lib_child_handler = old_action.sa_handler; 7098 if (old_action.sa_handler == deliver_child_signal)
7093 unblock_child_signal (); 7099 return;
7100#endif
7101
7102 lib_child_handler
7103 = (old_action.sa_handler == SIG_DFL || old_action.sa_handler == SIG_IGN
7104 ? dummy_handler
7105 : old_action.sa_handler);
7094} 7106}
7095 7107
7096 7108