aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorJoakim Verona2013-07-02 22:46:17 +0200
committerJoakim Verona2013-07-02 22:46:17 +0200
commit3718127221fbbc31f8ebd027ab7c95403dbe9118 (patch)
treeef422898f3344c8f94f6ecf63eb583122bbf2bd8 /src/process.c
parent1ce45b902c67b8a0dda8d71bd2812de29a9988a6 (diff)
parenta3b49114c186d84404226af75ae7905bd1cd018f (diff)
downloademacs-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.c98
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
6106static void dummy_handler (int sig) {} 6124static void dummy_handler (int sig) {}
6107static signal_handler_t volatile lib_child_handler = dummy_handler; 6125static 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
6197static void 6220static 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
7041static 7069static
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 ();