diff options
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 56 |
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 | |||
| 6129 | static void dummy_handler (int sig) {} | 6125 | static void dummy_handler (int sig) {} |
| 6130 | static signal_handler_t volatile lib_child_handler = dummy_handler; | 6126 | static 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 | ||
| 7065 | void | 7064 | void |
| 7066 | catch_child_signal (void) | 7065 | catch_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 | ||