diff options
| author | Joakim Verona | 2013-07-02 22:46:17 +0200 |
|---|---|---|
| committer | Joakim Verona | 2013-07-02 22:46:17 +0200 |
| commit | 3718127221fbbc31f8ebd027ab7c95403dbe9118 (patch) | |
| tree | ef422898f3344c8f94f6ecf63eb583122bbf2bd8 /src/process.c | |
| parent | 1ce45b902c67b8a0dda8d71bd2812de29a9988a6 (diff) | |
| parent | a3b49114c186d84404226af75ae7905bd1cd018f (diff) | |
| download | emacs-3718127221fbbc31f8ebd027ab7c95403dbe9118.tar.gz emacs-3718127221fbbc31f8ebd027ab7c95403dbe9118.zip | |
Merge branch 'trunk' into xwidget
Conflicts:
src/window.c
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 98 |
1 files changed, 66 insertions, 32 deletions
diff --git a/src/process.c b/src/process.c index a873dd0cdb2..9961697e671 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -124,8 +124,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 124 | #include TERM_HEADER | 124 | #include TERM_HEADER |
| 125 | #endif /* HAVE_WINDOW_SYSTEM */ | 125 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 126 | 126 | ||
| 127 | #if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) | 127 | #ifdef HAVE_GLIB |
| 128 | #include "xgselect.h" | 128 | #include "xgselect.h" |
| 129 | #ifndef WINDOWSNT | ||
| 130 | #include <glib.h> | ||
| 131 | #endif | ||
| 129 | #endif | 132 | #endif |
| 130 | 133 | ||
| 131 | #ifdef WINDOWSNT | 134 | #ifdef WINDOWSNT |
| @@ -1587,12 +1590,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1587 | #ifndef WINDOWSNT | 1590 | #ifndef WINDOWSNT |
| 1588 | int wait_child_setup[2]; | 1591 | int wait_child_setup[2]; |
| 1589 | #endif | 1592 | #endif |
| 1590 | sigset_t blocked; | 1593 | int forkin, forkout; |
| 1591 | /* Use volatile to protect variables from being clobbered by vfork. */ | 1594 | bool pty_flag = 0; |
| 1592 | volatile int forkin, forkout; | 1595 | Lisp_Object lisp_pty_name = Qnil; |
| 1593 | volatile bool pty_flag = 0; | 1596 | Lisp_Object encoded_current_dir; |
| 1594 | volatile Lisp_Object lisp_pty_name = Qnil; | ||
| 1595 | volatile Lisp_Object encoded_current_dir; | ||
| 1596 | 1597 | ||
| 1597 | inchannel = outchannel = -1; | 1598 | inchannel = outchannel = -1; |
| 1598 | 1599 | ||
| @@ -1683,15 +1684,34 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1683 | encoded_current_dir = ENCODE_FILE (current_dir); | 1684 | encoded_current_dir = ENCODE_FILE (current_dir); |
| 1684 | 1685 | ||
| 1685 | block_input (); | 1686 | block_input (); |
| 1686 | 1687 | block_child_signal (); | |
| 1687 | /* Block SIGCHLD until we have a chance to store the new fork's | ||
| 1688 | pid in its process structure. */ | ||
| 1689 | sigemptyset (&blocked); | ||
| 1690 | sigaddset (&blocked, SIGCHLD); | ||
| 1691 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | ||
| 1692 | 1688 | ||
| 1693 | #ifndef WINDOWSNT | 1689 | #ifndef WINDOWSNT |
| 1694 | pid = vfork (); | 1690 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| 1691 | { | ||
| 1692 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; | ||
| 1693 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; | ||
| 1694 | Lisp_Object volatile process_volatile = process; | ||
| 1695 | bool volatile pty_flag_volatile = pty_flag; | ||
| 1696 | char **volatile new_argv_volatile = new_argv; | ||
| 1697 | int volatile forkin_volatile = forkin; | ||
| 1698 | int volatile forkout_volatile = forkout; | ||
| 1699 | int volatile wait_child_setup_0_volatile = wait_child_setup[0]; | ||
| 1700 | int volatile wait_child_setup_1_volatile = wait_child_setup[1]; | ||
| 1701 | |||
| 1702 | pid = vfork (); | ||
| 1703 | |||
| 1704 | encoded_current_dir = encoded_current_dir_volatile; | ||
| 1705 | lisp_pty_name = lisp_pty_name_volatile; | ||
| 1706 | process = process_volatile; | ||
| 1707 | pty_flag = pty_flag_volatile; | ||
| 1708 | new_argv = new_argv_volatile; | ||
| 1709 | forkin = forkin_volatile; | ||
| 1710 | forkout = forkout_volatile; | ||
| 1711 | wait_child_setup[0] = wait_child_setup_0_volatile; | ||
| 1712 | wait_child_setup[1] = wait_child_setup_1_volatile; | ||
| 1713 | } | ||
| 1714 | |||
| 1695 | if (pid == 0) | 1715 | if (pid == 0) |
| 1696 | #endif /* not WINDOWSNT */ | 1716 | #endif /* not WINDOWSNT */ |
| 1697 | { | 1717 | { |
| @@ -1796,8 +1816,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1796 | /* Emacs ignores SIGPIPE, but the child should not. */ | 1816 | /* Emacs ignores SIGPIPE, but the child should not. */ |
| 1797 | signal (SIGPIPE, SIG_DFL); | 1817 | signal (SIGPIPE, SIG_DFL); |
| 1798 | 1818 | ||
| 1799 | /* Stop blocking signals in the child. */ | 1819 | /* Stop blocking SIGCHLD in the child. */ |
| 1800 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 1820 | unblock_child_signal (); |
| 1801 | 1821 | ||
| 1802 | if (pty_flag) | 1822 | if (pty_flag) |
| 1803 | child_setup_tty (xforkout); | 1823 | child_setup_tty (xforkout); |
| @@ -1817,8 +1837,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1817 | if (pid >= 0) | 1837 | if (pid >= 0) |
| 1818 | XPROCESS (process)->alive = 1; | 1838 | XPROCESS (process)->alive = 1; |
| 1819 | 1839 | ||
| 1820 | /* Stop blocking signals in the parent. */ | 1840 | /* Stop blocking in the parent. */ |
| 1821 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 1841 | unblock_child_signal (); |
| 1822 | unblock_input (); | 1842 | unblock_input (); |
| 1823 | 1843 | ||
| 1824 | if (pid < 0) | 1844 | if (pid < 0) |
| @@ -2524,7 +2544,7 @@ usage: (make-serial-process &rest ARGS) */) | |||
| 2524 | struct gcpro gcpro1; | 2544 | struct gcpro gcpro1; |
| 2525 | Lisp_Object name, buffer; | 2545 | Lisp_Object name, buffer; |
| 2526 | Lisp_Object tem, val; | 2546 | Lisp_Object tem, val; |
| 2527 | ptrdiff_t specpdl_count = -1; | 2547 | ptrdiff_t specpdl_count; |
| 2528 | 2548 | ||
| 2529 | if (nargs == 0) | 2549 | if (nargs == 0) |
| 2530 | return Qnil; | 2550 | return Qnil; |
| @@ -4404,7 +4424,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4404 | && ! EQ (wait_proc->status, Qrun) | 4424 | && ! EQ (wait_proc->status, Qrun) |
| 4405 | && ! EQ (wait_proc->status, Qconnect)) | 4425 | && ! EQ (wait_proc->status, Qconnect)) |
| 4406 | { | 4426 | { |
| 4407 | int nread, total_nread = 0; | 4427 | bool read_some_bytes = 0; |
| 4408 | 4428 | ||
| 4409 | clear_waiting_for_input (); | 4429 | clear_waiting_for_input (); |
| 4410 | XSETPROCESS (proc, wait_proc); | 4430 | XSETPROCESS (proc, wait_proc); |
| @@ -4412,16 +4432,13 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4412 | /* Read data from the process, until we exhaust it. */ | 4432 | /* Read data from the process, until we exhaust it. */ |
| 4413 | while (wait_proc->infd >= 0) | 4433 | while (wait_proc->infd >= 0) |
| 4414 | { | 4434 | { |
| 4415 | nread = read_process_output (proc, wait_proc->infd); | 4435 | int nread = read_process_output (proc, wait_proc->infd); |
| 4416 | 4436 | ||
| 4417 | if (nread == 0) | 4437 | if (nread == 0) |
| 4418 | break; | 4438 | break; |
| 4419 | 4439 | ||
| 4420 | if (nread > 0) | 4440 | if (nread > 0) |
| 4421 | { | 4441 | got_some_input = read_some_bytes = 1; |
| 4422 | total_nread += nread; | ||
| 4423 | got_some_input = 1; | ||
| 4424 | } | ||
| 4425 | else if (nread == -1 && (errno == EIO || errno == EAGAIN)) | 4442 | else if (nread == -1 && (errno == EIO || errno == EAGAIN)) |
| 4426 | break; | 4443 | break; |
| 4427 | #ifdef EWOULDBLOCK | 4444 | #ifdef EWOULDBLOCK |
| @@ -4429,7 +4446,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4429 | break; | 4446 | break; |
| 4430 | #endif | 4447 | #endif |
| 4431 | } | 4448 | } |
| 4432 | if (total_nread > 0 && do_display) | 4449 | if (read_some_bytes && do_display) |
| 4433 | redisplay_preserve_echo_area (10); | 4450 | redisplay_preserve_echo_area (10); |
| 4434 | 4451 | ||
| 4435 | break; | 4452 | break; |
| @@ -6102,9 +6119,10 @@ process has been transmitted to the serial port. */) | |||
| 6102 | 6119 | ||
| 6103 | /* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing | 6120 | /* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing |
| 6104 | its own SIGCHLD handling. On POSIXish systems, glib needs this to | 6121 | its own SIGCHLD handling. On POSIXish systems, glib needs this to |
| 6105 | keep track of its own children. The default handler does nothing. */ | 6122 | keep track of its own children. GNUstep is similar. */ |
| 6123 | |||
| 6106 | static void dummy_handler (int sig) {} | 6124 | static void dummy_handler (int sig) {} |
| 6107 | static signal_handler_t volatile lib_child_handler = dummy_handler; | 6125 | static signal_handler_t volatile lib_child_handler; |
| 6108 | 6126 | ||
| 6109 | /* Handle a SIGCHLD signal by looking for known child processes of | 6127 | /* Handle a SIGCHLD signal by looking for known child processes of |
| 6110 | Emacs whose status have changed. For each one found, record its | 6128 | Emacs whose status have changed. For each one found, record its |
| @@ -6192,6 +6210,11 @@ handle_child_signal (int sig) | |||
| 6192 | } | 6210 | } |
| 6193 | 6211 | ||
| 6194 | lib_child_handler (sig); | 6212 | lib_child_handler (sig); |
| 6213 | #ifdef NS_IMPL_GNUSTEP | ||
| 6214 | /* NSTask in GNUStep sets its child handler each time it is called. | ||
| 6215 | So we must re-set ours. */ | ||
| 6216 | catch_child_signal(); | ||
| 6217 | #endif | ||
| 6195 | } | 6218 | } |
| 6196 | 6219 | ||
| 6197 | static void | 6220 | static void |
| @@ -7037,6 +7060,11 @@ integer or floating point values. | |||
| 7037 | return system_process_attributes (pid); | 7060 | return system_process_attributes (pid); |
| 7038 | } | 7061 | } |
| 7039 | 7062 | ||
| 7063 | /* Arrange to catch SIGCHLD if this hasn't already been arranged. | ||
| 7064 | Invoke this after init_process_emacs, and after glib and/or GNUstep | ||
| 7065 | futz with the SIGCHLD handler, but before Emacs forks any children. | ||
| 7066 | This function's caller should block SIGCHLD. */ | ||
| 7067 | |||
| 7040 | #ifndef NS_IMPL_GNUSTEP | 7068 | #ifndef NS_IMPL_GNUSTEP |
| 7041 | static | 7069 | static |
| 7042 | #endif | 7070 | #endif |
| @@ -7045,11 +7073,16 @@ catch_child_signal (void) | |||
| 7045 | { | 7073 | { |
| 7046 | struct sigaction action, old_action; | 7074 | struct sigaction action, old_action; |
| 7047 | emacs_sigaction_init (&action, deliver_child_signal); | 7075 | emacs_sigaction_init (&action, deliver_child_signal); |
| 7076 | block_child_signal (); | ||
| 7048 | sigaction (SIGCHLD, &action, &old_action); | 7077 | sigaction (SIGCHLD, &action, &old_action); |
| 7049 | eassert (! (old_action.sa_flags & SA_SIGINFO)); | 7078 | eassert (! (old_action.sa_flags & SA_SIGINFO)); |
| 7050 | if (old_action.sa_handler != SIG_DFL && old_action.sa_handler != SIG_IGN | 7079 | |
| 7051 | && old_action.sa_handler != deliver_child_signal) | 7080 | if (old_action.sa_handler != deliver_child_signal) |
| 7052 | lib_child_handler = old_action.sa_handler; | 7081 | lib_child_handler |
| 7082 | = (old_action.sa_handler == SIG_DFL || old_action.sa_handler == SIG_IGN | ||
| 7083 | ? dummy_handler | ||
| 7084 | : old_action.sa_handler); | ||
| 7085 | unblock_child_signal (); | ||
| 7053 | } | 7086 | } |
| 7054 | 7087 | ||
| 7055 | 7088 | ||
| @@ -7070,7 +7103,8 @@ init_process_emacs (void) | |||
| 7070 | #if defined HAVE_GLIB && !defined WINDOWSNT | 7103 | #if defined HAVE_GLIB && !defined WINDOWSNT |
| 7071 | /* Tickle glib's child-handling code. Ask glib to wait for Emacs itself; | 7104 | /* Tickle glib's child-handling code. Ask glib to wait for Emacs itself; |
| 7072 | this should always fail, but is enough to initialize glib's | 7105 | this should always fail, but is enough to initialize glib's |
| 7073 | private SIGCHLD handler. */ | 7106 | private SIGCHLD handler, allowing catch_child_signal to copy |
| 7107 | it into lib_child_handler. */ | ||
| 7074 | g_source_unref (g_child_watch_source_new (getpid ())); | 7108 | g_source_unref (g_child_watch_source_new (getpid ())); |
| 7075 | #endif | 7109 | #endif |
| 7076 | catch_child_signal (); | 7110 | catch_child_signal (); |