diff options
| author | Tom Tromey | 2013-07-12 18:44:13 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-07-12 18:44:13 -0600 |
| commit | b34a529f177a6ea32da5cb1254f91bf9d71838db (patch) | |
| tree | 477131abc15d3107b30b635223d87a22550b480b /src/process.c | |
| parent | e6f63071a3f7721f55220514b6d9a8ee8c1232d8 (diff) | |
| parent | 5e301d7651c0691bb2bc7f3fbe711fdbe26ac471 (diff) | |
| download | emacs-b34a529f177a6ea32da5cb1254f91bf9d71838db.tar.gz emacs-b34a529f177a6ea32da5cb1254f91bf9d71838db.zip | |
Merge from trunk
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 157 |
1 files changed, 61 insertions, 96 deletions
diff --git a/src/process.c b/src/process.c index 2e2610ffde4..dc37bfe7067 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -135,6 +135,37 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, | |||
| 135 | EMACS_TIME *, void *); | 135 | EMACS_TIME *, void *); |
| 136 | #endif | 136 | #endif |
| 137 | 137 | ||
| 138 | #ifndef SOCK_CLOEXEC | ||
| 139 | # define SOCK_CLOEXEC 0 | ||
| 140 | #endif | ||
| 141 | |||
| 142 | #ifndef HAVE_ACCEPT4 | ||
| 143 | |||
| 144 | /* Emulate GNU/Linux accept4 and socket well enough for this module. */ | ||
| 145 | |||
| 146 | static int | ||
| 147 | close_on_exec (int fd) | ||
| 148 | { | ||
| 149 | if (0 <= fd) | ||
| 150 | fcntl (fd, F_SETFD, FD_CLOEXEC); | ||
| 151 | return fd; | ||
| 152 | } | ||
| 153 | |||
| 154 | static int | ||
| 155 | accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) | ||
| 156 | { | ||
| 157 | return close_on_exec (accept (sockfd, addr, addrlen)); | ||
| 158 | } | ||
| 159 | |||
| 160 | static int | ||
| 161 | process_socket (int domain, int type, int protocol) | ||
| 162 | { | ||
| 163 | return close_on_exec (socket (domain, type, protocol)); | ||
| 164 | } | ||
| 165 | # undef socket | ||
| 166 | # define socket(domain, type, protocol) process_socket (domain, type, protocol) | ||
| 167 | #endif | ||
| 168 | |||
| 138 | /* Work around GCC 4.7.0 bug with strict overflow checking; see | 169 | /* Work around GCC 4.7.0 bug with strict overflow checking; see |
| 139 | <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>. | 170 | <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>. |
| 140 | These lines can be removed once the GCC bug is fixed. */ | 171 | These lines can be removed once the GCC bug is fixed. */ |
| @@ -1782,6 +1813,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1782 | { | 1813 | { |
| 1783 | int inchannel, outchannel; | 1814 | int inchannel, outchannel; |
| 1784 | pid_t pid; | 1815 | pid_t pid; |
| 1816 | int vfork_errno; | ||
| 1785 | int sv[2]; | 1817 | int sv[2]; |
| 1786 | #ifndef WINDOWSNT | 1818 | #ifndef WINDOWSNT |
| 1787 | int wait_child_setup[2]; | 1819 | int wait_child_setup[2]; |
| @@ -1816,47 +1848,30 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1816 | else | 1848 | else |
| 1817 | #endif /* HAVE_PTYS */ | 1849 | #endif /* HAVE_PTYS */ |
| 1818 | { | 1850 | { |
| 1819 | int tem; | 1851 | if (pipe2 (sv, O_CLOEXEC) != 0) |
| 1820 | tem = pipe (sv); | ||
| 1821 | if (tem < 0) | ||
| 1822 | report_file_error ("Creating pipe", Qnil); | 1852 | report_file_error ("Creating pipe", Qnil); |
| 1823 | inchannel = sv[0]; | 1853 | inchannel = sv[0]; |
| 1824 | forkout = sv[1]; | 1854 | forkout = sv[1]; |
| 1825 | tem = pipe (sv); | 1855 | if (pipe2 (sv, O_CLOEXEC) != 0) |
| 1826 | if (tem < 0) | ||
| 1827 | { | 1856 | { |
| 1857 | int pipe_errno = errno; | ||
| 1828 | emacs_close (inchannel); | 1858 | emacs_close (inchannel); |
| 1829 | emacs_close (forkout); | 1859 | emacs_close (forkout); |
| 1830 | report_file_error ("Creating pipe", Qnil); | 1860 | report_file_errno ("Creating pipe", Qnil, pipe_errno); |
| 1831 | } | 1861 | } |
| 1832 | outchannel = sv[1]; | 1862 | outchannel = sv[1]; |
| 1833 | forkin = sv[0]; | 1863 | forkin = sv[0]; |
| 1834 | } | 1864 | } |
| 1835 | 1865 | ||
| 1836 | #ifndef WINDOWSNT | 1866 | #ifndef WINDOWSNT |
| 1837 | { | 1867 | if (pipe2 (wait_child_setup, O_CLOEXEC) != 0) |
| 1838 | int tem; | 1868 | report_file_error ("Creating pipe", Qnil); |
| 1839 | |||
| 1840 | tem = pipe (wait_child_setup); | ||
| 1841 | if (tem < 0) | ||
| 1842 | report_file_error ("Creating pipe", Qnil); | ||
| 1843 | tem = fcntl (wait_child_setup[1], F_GETFD, 0); | ||
| 1844 | if (tem >= 0) | ||
| 1845 | tem = fcntl (wait_child_setup[1], F_SETFD, tem | FD_CLOEXEC); | ||
| 1846 | if (tem < 0) | ||
| 1847 | { | ||
| 1848 | emacs_close (wait_child_setup[0]); | ||
| 1849 | emacs_close (wait_child_setup[1]); | ||
| 1850 | report_file_error ("Setting file descriptor flags", Qnil); | ||
| 1851 | } | ||
| 1852 | } | ||
| 1853 | #endif | 1869 | #endif |
| 1854 | 1870 | ||
| 1855 | fcntl (inchannel, F_SETFL, O_NONBLOCK); | 1871 | fcntl (inchannel, F_SETFL, O_NONBLOCK); |
| 1856 | fcntl (outchannel, F_SETFL, O_NONBLOCK); | 1872 | fcntl (outchannel, F_SETFL, O_NONBLOCK); |
| 1857 | 1873 | ||
| 1858 | /* Record this as an active process, with its channels. | 1874 | /* Record this as an active process, with its channels. */ |
| 1859 | As a result, child_setup will close Emacs's side of the pipes. */ | ||
| 1860 | chan_process[inchannel] = process; | 1875 | chan_process[inchannel] = process; |
| 1861 | XPROCESS (process)->infd = inchannel; | 1876 | XPROCESS (process)->infd = inchannel; |
| 1862 | XPROCESS (process)->outfd = outchannel; | 1877 | XPROCESS (process)->outfd = outchannel; |
| @@ -1933,7 +1948,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1933 | tcgetattr (xforkin, &t); | 1948 | tcgetattr (xforkin, &t); |
| 1934 | t.c_lflag = LDISC1; | 1949 | t.c_lflag = LDISC1; |
| 1935 | if (tcsetattr (xforkin, TCSANOW, &t) < 0) | 1950 | if (tcsetattr (xforkin, TCSANOW, &t) < 0) |
| 1936 | emacs_write (1, "create_process/tcsetattr LDISC1 failed\n", 39); | 1951 | emacs_perror ("create_process/tcsetattr LDISC1"); |
| 1937 | } | 1952 | } |
| 1938 | #else | 1953 | #else |
| 1939 | #if defined (NTTYDISC) && defined (TIOCSETD) | 1954 | #if defined (NTTYDISC) && defined (TIOCSETD) |
| @@ -1980,10 +1995,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1980 | 1995 | ||
| 1981 | if (xforkin < 0) | 1996 | if (xforkin < 0) |
| 1982 | { | 1997 | { |
| 1983 | emacs_write (1, "Couldn't open the pty terminal ", 31); | 1998 | emacs_perror (pty_name); |
| 1984 | emacs_write (1, pty_name, strlen (pty_name)); | 1999 | _exit (EXIT_CANCELED); |
| 1985 | emacs_write (1, "\n", 1); | ||
| 1986 | _exit (1); | ||
| 1987 | } | 2000 | } |
| 1988 | 2001 | ||
| 1989 | } | 2002 | } |
| @@ -1995,12 +2008,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1995 | SETUP_SLAVE_PTY; | 2008 | SETUP_SLAVE_PTY; |
| 1996 | } | 2009 | } |
| 1997 | #endif /* SETUP_SLAVE_PTY */ | 2010 | #endif /* SETUP_SLAVE_PTY */ |
| 1998 | #ifdef AIX | ||
| 1999 | /* On AIX, we've disabled SIGHUP above once we start a child on a pty. | ||
| 2000 | Now reenable it in the child, so it will die when we want it to. */ | ||
| 2001 | if (pty_flag) | ||
| 2002 | signal (SIGHUP, SIG_DFL); | ||
| 2003 | #endif | ||
| 2004 | #endif /* HAVE_PTYS */ | 2011 | #endif /* HAVE_PTYS */ |
| 2005 | 2012 | ||
| 2006 | signal (SIGINT, SIG_DFL); | 2013 | signal (SIGINT, SIG_DFL); |
| @@ -2026,6 +2033,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2026 | 2033 | ||
| 2027 | /* Back in the parent process. */ | 2034 | /* Back in the parent process. */ |
| 2028 | 2035 | ||
| 2036 | vfork_errno = errno; | ||
| 2029 | XPROCESS (process)->pid = pid; | 2037 | XPROCESS (process)->pid = pid; |
| 2030 | if (pid >= 0) | 2038 | if (pid >= 0) |
| 2031 | XPROCESS (process)->alive = 1; | 2039 | XPROCESS (process)->alive = 1; |
| @@ -2040,6 +2048,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2040 | emacs_close (forkin); | 2048 | emacs_close (forkin); |
| 2041 | if (forkin != forkout && forkout >= 0) | 2049 | if (forkin != forkout && forkout >= 0) |
| 2042 | emacs_close (forkout); | 2050 | emacs_close (forkout); |
| 2051 | report_file_errno ("Doing vfork", Qnil, vfork_errno); | ||
| 2043 | } | 2052 | } |
| 2044 | else | 2053 | else |
| 2045 | { | 2054 | { |
| @@ -2085,10 +2094,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2085 | } | 2094 | } |
| 2086 | #endif | 2095 | #endif |
| 2087 | } | 2096 | } |
| 2088 | |||
| 2089 | /* Now generate the error if vfork failed. */ | ||
| 2090 | if (pid < 0) | ||
| 2091 | report_file_error ("Doing vfork", Qnil); | ||
| 2092 | } | 2097 | } |
| 2093 | 2098 | ||
| 2094 | void | 2099 | void |
| @@ -3323,7 +3328,8 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3323 | retry_connect: | 3328 | retry_connect: |
| 3324 | #endif | 3329 | #endif |
| 3325 | 3330 | ||
| 3326 | s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); | 3331 | s = socket (lres->ai_family, lres->ai_socktype | SOCK_CLOEXEC, |
| 3332 | lres->ai_protocol); | ||
| 3327 | if (s < 0) | 3333 | if (s < 0) |
| 3328 | { | 3334 | { |
| 3329 | xerrno = errno; | 3335 | xerrno = errno; |
| @@ -3447,12 +3453,11 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3447 | 3453 | ||
| 3448 | len = sizeof xerrno; | 3454 | len = sizeof xerrno; |
| 3449 | eassert (FD_ISSET (s, &fdset)); | 3455 | eassert (FD_ISSET (s, &fdset)); |
| 3450 | if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) == -1) | 3456 | if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0) |
| 3451 | report_file_error ("getsockopt failed", Qnil); | 3457 | report_file_error ("getsockopt failed", Qnil); |
| 3452 | if (xerrno) | 3458 | if (xerrno) |
| 3453 | errno = xerrno, report_file_error ("error during connect", Qnil); | 3459 | report_file_errno ("error during connect", Qnil, xerrno); |
| 3454 | else | 3460 | break; |
| 3455 | break; | ||
| 3456 | } | 3461 | } |
| 3457 | #endif /* !WINDOWSNT */ | 3462 | #endif /* !WINDOWSNT */ |
| 3458 | 3463 | ||
| @@ -3536,11 +3541,10 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3536 | if (is_non_blocking_client) | 3541 | if (is_non_blocking_client) |
| 3537 | return Qnil; | 3542 | return Qnil; |
| 3538 | 3543 | ||
| 3539 | errno = xerrno; | 3544 | report_file_errno ((is_server |
| 3540 | if (is_server) | 3545 | ? "make server process failed" |
| 3541 | report_file_error ("make server process failed", contact); | 3546 | : "make client process failed"), |
| 3542 | else | 3547 | contact, xerrno); |
| 3543 | report_file_error ("make client process failed", contact); | ||
| 3544 | } | 3548 | } |
| 3545 | 3549 | ||
| 3546 | inch = s; | 3550 | inch = s; |
| @@ -3713,7 +3717,7 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3713 | int s; | 3717 | int s; |
| 3714 | Lisp_Object res; | 3718 | Lisp_Object res; |
| 3715 | 3719 | ||
| 3716 | s = socket (AF_INET, SOCK_STREAM, 0); | 3720 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); |
| 3717 | if (s < 0) | 3721 | if (s < 0) |
| 3718 | return Qnil; | 3722 | return Qnil; |
| 3719 | 3723 | ||
| @@ -3724,14 +3728,14 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3724 | ifconf.ifc_len = buf_size; | 3728 | ifconf.ifc_len = buf_size; |
| 3725 | if (ioctl (s, SIOCGIFCONF, &ifconf)) | 3729 | if (ioctl (s, SIOCGIFCONF, &ifconf)) |
| 3726 | { | 3730 | { |
| 3727 | close (s); | 3731 | emacs_close (s); |
| 3728 | xfree (buf); | 3732 | xfree (buf); |
| 3729 | return Qnil; | 3733 | return Qnil; |
| 3730 | } | 3734 | } |
| 3731 | } | 3735 | } |
| 3732 | while (ifconf.ifc_len == buf_size); | 3736 | while (ifconf.ifc_len == buf_size); |
| 3733 | 3737 | ||
| 3734 | close (s); | 3738 | emacs_close (s); |
| 3735 | 3739 | ||
| 3736 | res = Qnil; | 3740 | res = Qnil; |
| 3737 | ifreq = ifconf.ifc_req; | 3741 | ifreq = ifconf.ifc_req; |
| @@ -3869,7 +3873,7 @@ FLAGS is the current flags of the interface. */) | |||
| 3869 | error ("interface name too long"); | 3873 | error ("interface name too long"); |
| 3870 | strcpy (rq.ifr_name, SSDATA (ifname)); | 3874 | strcpy (rq.ifr_name, SSDATA (ifname)); |
| 3871 | 3875 | ||
| 3872 | s = socket (AF_INET, SOCK_STREAM, 0); | 3876 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); |
| 3873 | if (s < 0) | 3877 | if (s < 0) |
| 3874 | return Qnil; | 3878 | return Qnil; |
| 3875 | 3879 | ||
| @@ -3988,7 +3992,7 @@ FLAGS is the current flags of the interface. */) | |||
| 3988 | #endif | 3992 | #endif |
| 3989 | res = Fcons (elt, res); | 3993 | res = Fcons (elt, res); |
| 3990 | 3994 | ||
| 3991 | close (s); | 3995 | emacs_close (s); |
| 3992 | 3996 | ||
| 3993 | return any ? res : Qnil; | 3997 | return any ? res : Qnil; |
| 3994 | } | 3998 | } |
| @@ -4161,7 +4165,7 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4161 | } saddr; | 4165 | } saddr; |
| 4162 | socklen_t len = sizeof saddr; | 4166 | socklen_t len = sizeof saddr; |
| 4163 | 4167 | ||
| 4164 | s = accept (channel, &saddr.sa, &len); | 4168 | s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC); |
| 4165 | 4169 | ||
| 4166 | if (s < 0) | 4170 | if (s < 0) |
| 4167 | { | 4171 | { |
| @@ -4785,20 +4789,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4785 | if (xerrno == EINTR) | 4789 | if (xerrno == EINTR) |
| 4786 | no_avail = 1; | 4790 | no_avail = 1; |
| 4787 | else if (xerrno == EBADF) | 4791 | else if (xerrno == EBADF) |
| 4788 | { | 4792 | emacs_abort (); |
| 4789 | #ifdef AIX | ||
| 4790 | /* AIX doesn't handle PTY closure the same way BSD does. On AIX, | ||
| 4791 | the child's closure of the pts gives the parent a SIGHUP, and | ||
| 4792 | the ptc file descriptor is automatically closed, | ||
| 4793 | yielding EBADF here or at select() call above. | ||
| 4794 | So, SIGHUP is ignored (see def of PTY_TTY_NAME_SPRINTF | ||
| 4795 | in m/ibmrt-aix.h), and here we just ignore the select error. | ||
| 4796 | Cleanup occurs c/o status_notify after SIGCHLD. */ | ||
| 4797 | no_avail = 1; /* Cannot depend on values returned */ | ||
| 4798 | #else | ||
| 4799 | emacs_abort (); | ||
| 4800 | #endif | ||
| 4801 | } | ||
| 4802 | else | 4793 | else |
| 4803 | error ("select error: %s", emacs_strerror (xerrno)); | 4794 | error ("select error: %s", emacs_strerror (xerrno)); |
| 4804 | } | 4795 | } |
| @@ -5648,7 +5639,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, | |||
| 5648 | written = emacs_gnutls_write (p, cur_buf, cur_len); | 5639 | written = emacs_gnutls_write (p, cur_buf, cur_len); |
| 5649 | else | 5640 | else |
| 5650 | #endif | 5641 | #endif |
| 5651 | written = emacs_write (outfd, cur_buf, cur_len); | 5642 | written = emacs_write_sig (outfd, cur_buf, cur_len); |
| 5652 | rv = (written ? 0 : -1); | 5643 | rv = (written ? 0 : -1); |
| 5653 | #ifdef ADAPTIVE_READ_BUFFERING | 5644 | #ifdef ADAPTIVE_READ_BUFFERING |
| 5654 | if (p->read_output_delay > 0 | 5645 | if (p->read_output_delay > 0 |
| @@ -7010,32 +7001,6 @@ setup_process_coding_systems (Lisp_Object process) | |||
| 7010 | #endif | 7001 | #endif |
| 7011 | } | 7002 | } |
| 7012 | 7003 | ||
| 7013 | /* Close all descriptors currently in use for communication | ||
| 7014 | with subprocess. This is used in a newly-forked subprocess | ||
| 7015 | to get rid of irrelevant descriptors. */ | ||
| 7016 | |||
| 7017 | void | ||
| 7018 | close_process_descs (void) | ||
| 7019 | { | ||
| 7020 | #ifndef DOS_NT | ||
| 7021 | int i; | ||
| 7022 | for (i = 0; i < MAXDESC; i++) | ||
| 7023 | { | ||
| 7024 | Lisp_Object process; | ||
| 7025 | process = chan_process[i]; | ||
| 7026 | if (!NILP (process)) | ||
| 7027 | { | ||
| 7028 | int in = XPROCESS (process)->infd; | ||
| 7029 | int out = XPROCESS (process)->outfd; | ||
| 7030 | if (in >= 0) | ||
| 7031 | emacs_close (in); | ||
| 7032 | if (out >= 0 && in != out) | ||
| 7033 | emacs_close (out); | ||
| 7034 | } | ||
| 7035 | } | ||
| 7036 | #endif | ||
| 7037 | } | ||
| 7038 | |||
| 7039 | DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, | 7004 | DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, |
| 7040 | doc: /* Return the (or a) process associated with BUFFER. | 7005 | doc: /* Return the (or a) process associated with BUFFER. |
| 7041 | BUFFER may be a buffer or the name of one. */) | 7006 | BUFFER may be a buffer or the name of one. */) |