From: Paul Eggert Date: Thu, 27 Jun 2013 14:47:52 +0000 (-0700) Subject: Do not tickle glib SIGCHLD handling if Cygwin. X-Git-Tag: emacs-24.3.90~173^2^2~42^2~45^2~387^2~1992^2~8 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=dae2f5ef41cd81c4feeddb3667c03d1f27df7743;p=emacs.git Do not tickle glib SIGCHLD handling if Cygwin. This mostly consists of undoing recent changes. * callproc.c (Fcall_process): * process.c (create_process): Do not worry about catching SIGCHLD here, undoing previous change. * nsterm.m (ns_term_init): Re-catch SIGCHLD, undoing previous change. * process.c, process.h (catch_child_signal): No longer extern if !NS_IMPL_GNUSTEP, undoing 06-22 change. * process.c (catch_child_handler): Don't worry about being called lazily and do not assume caller has blocked SIGCHLD, undoing previous change. Move first-time stuff back to init_process_emacs, undoing 06-22 change. If CYGWIN, do not tickle glib, as that causes Cygwin bootstrap to fail. Do not set lib_child_handler if it's already initialized, which may help avoid problems on GNUStep. --- diff --git a/src/ChangeLog b/src/ChangeLog index 6357491725d..837d946a26e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,21 @@ +2013-06-27 Paul Eggert + + Do not tickle glib SIGCHLD handling if Cygwin (Bug#14569). + This mostly consists of undoing recent changes. + * callproc.c (Fcall_process): + * process.c (create_process): + Do not worry about catching SIGCHLD here, undoing previous change. + * nsterm.m (ns_term_init): Re-catch SIGCHLD, undoing previous change. + * process.c, process.h (catch_child_signal): + No longer extern if !NS_IMPL_GNUSTEP, undoing 06-22 change. + * process.c (catch_child_handler): Don't worry about being called + lazily and do not assume caller has blocked SIGCHLD, undoing + previous change. Move first-time stuff back to + init_process_emacs, undoing 06-22 change. If CYGWIN, do not + tickle glib, as that causes Cygwin bootstrap to fail. Do not + set lib_child_handler if it's already initialized, which may + help avoid problems on GNUStep. + 2013-06-23 Paul Eggert A more-conservative workaround for Cygwin SIGCHLD issues (Bug#14569). diff --git a/src/callproc.c b/src/callproc.c index 7db984fa71c..f0aa8222342 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -613,7 +613,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * block_input (); block_child_signal (); - catch_child_signal (); #ifdef WINDOWSNT pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); diff --git a/src/nsterm.m b/src/nsterm.m index c88e5034d39..93f693fe55e 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -4360,6 +4360,12 @@ ns_term_init (Lisp_Object display_name) [NSApp run]; ns_do_open_file = YES; + +#ifdef NS_IMPL_GNUSTEP + /* GNUstep steals SIGCHLD for use in NSTask, but we don't use NSTask. + We must re-catch it so subprocess works. */ + catch_child_signal (); +#endif return dpyinfo; } diff --git a/src/process.c b/src/process.c index 3f062b6db16..b63a985fcec 100644 --- a/src/process.c +++ b/src/process.c @@ -1685,7 +1685,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) block_input (); block_child_signal (); - catch_child_signal (); #ifndef WINDOWSNT /* vfork, and prevent local vars from being clobbered by the vfork. */ @@ -7061,48 +7060,24 @@ integer or floating point values. futz with the SIGCHLD handler, but before Emacs forks any children. This function's caller should block SIGCHLD. */ +#ifndef NS_IMPL_GNUSTEP +static +#endif void catch_child_signal (void) { struct sigaction action, old_action; - -#if !defined CANNOT_DUMP - if (noninteractive && !initialized) - return; -#endif - -#ifndef NS_IMPL_GNUSTEP - if (lib_child_handler) - return; -#endif - -#if defined HAVE_GLIB && !defined WINDOWSNT - /* Tickle glib's child-handling code. Ask glib to wait for Emacs itself; - this should always fail, but is enough to initialize glib's - private SIGCHLD handler, allowing the code below to copy it into - LIB_CHILD_HANDLER. - - Do this here, rather than early in Emacs initialization where it - might make more sense, to try to avoid bugs in Cygwin glib (Bug#14569). */ - { - GSource *source = g_child_watch_source_new (getpid ()); - g_source_unref (source); - } -#endif - emacs_sigaction_init (&action, deliver_child_signal); + block_child_signal (); sigaction (SIGCHLD, &action, &old_action); eassert (! (old_action.sa_flags & SA_SIGINFO)); -#ifdef NS_IMPL_GNUSTEP - if (old_action.sa_handler == deliver_child_signal) - return; -#endif - - lib_child_handler - = (old_action.sa_handler == SIG_DFL || old_action.sa_handler == SIG_IGN - ? dummy_handler - : old_action.sa_handler); + if (old_action.sa_handler != deliver_child_signal) + lib_child_handler + = (old_action.sa_handler == SIG_DFL || old_action.sa_handler == SIG_IGN + ? dummy_handler + : old_action.sa_handler); + unblock_child_signal (); } @@ -7116,6 +7091,24 @@ init_process_emacs (void) inhibit_sentinels = 0; +#ifndef CANNOT_DUMP + if (! noninteractive || initialized) +#endif + { +#if defined HAVE_GLIB && !defined WINDOWSNT && !defined CYGWIN + /* Tickle glib's child-handling code. Ask glib to wait for Emacs itself; + this should always fail, but is enough to initialize glib's + private SIGCHLD handler, allowing the code below to copy it into + LIB_CHILD_HANDLER. + + For some reason tickling causes Cygwin bootstrap to fail, so it's + skipped under Cygwin. FIXME: Skipping the tickling likely causes + bugs in subprocess handling under Cygwin (Bug#14569). */ + g_source_unref (g_child_watch_source_new (getpid ())); +#endif + catch_child_signal (); + } + FD_ZERO (&input_wait_mask); FD_ZERO (&non_keyboard_wait_mask); FD_ZERO (&non_process_wait_mask); diff --git a/src/process.h b/src/process.h index 3f86e5f3945..e7ee5f9adde 100644 --- a/src/process.h +++ b/src/process.h @@ -219,6 +219,8 @@ extern void add_read_fd (int fd, fd_callback func, void *data); extern void delete_read_fd (int fd); extern void add_write_fd (int fd, fd_callback func, void *data); extern void delete_write_fd (int fd); +#ifdef NS_IMPL_GNUSTEP extern void catch_child_signal (void); +#endif INLINE_HEADER_END