2013-06-22 Paul Eggert <eggert@cs.ucla.edu>
+ Clean up SIGCHLD handling a bit (Bug#14569).
+ * process.c, process.h (catch_child_signal):
+ Now always extern, even if !NS_IMPL_GNUSTEP.
+ * process.c (catch_child_signal): Move glib tickler here from
+ init_process_emacs, so that it's done earlier in Emacs
+ initialization. Also move the noninteractive && !initialized
+ check here from init_process_emacs. This is all a bit cleaner for
+ GNUish platforms, and I hope it works around the Cygwin bug.
+ * sysdep.c (init_signals): Invoke catch_child_signal here, so
+ that glib signal handling is tickled before glib creates threads.
+
* process.c (wait_reading_process_output): Avoid int overflow
when reading more than 2 GiB total from a process.
return system_process_attributes (pid);
}
-#ifndef NS_IMPL_GNUSTEP
-static
-#endif
+/* Arrange to catch SIGCHLD if needed. */
+
void
catch_child_signal (void)
{
struct sigaction action, old_action;
+
+#if !defined CANNOT_DUMP
+ if (noninteractive && !initialized)
+ 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 early in Emacs initialization, before glib creates
+ threads, to avoid race condition bugs in Cygwin glib. */
+ g_source_unref (g_child_watch_source_new (getpid ()));
+#endif
+
emacs_sigaction_init (&action, deliver_child_signal);
sigaction (SIGCHLD, &action, &old_action);
eassert (! (old_action.sa_flags & SA_SIGINFO));
inhibit_sentinels = 0;
-#ifndef CANNOT_DUMP
- if (! noninteractive || initialized)
-#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. */
- 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);
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