aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c56
1 files changed, 34 insertions, 22 deletions
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