diff options
| author | Joakim Verona | 2013-07-14 11:04:49 +0200 |
|---|---|---|
| committer | Joakim Verona | 2013-07-14 11:04:49 +0200 |
| commit | 0bb9bb0841d89fff09820a57369df4cb01b16b43 (patch) | |
| tree | 832bf9fa8415eef0ce464d22b3ee1300cfa90bb1 /src/process.c | |
| parent | 3718127221fbbc31f8ebd027ab7c95403dbe9118 (diff) | |
| parent | 3af1c8684ed6e48fbc21481d129e9aa164752c6e (diff) | |
| download | emacs-0bb9bb0841d89fff09820a57369df4cb01b16b43.tar.gz emacs-0bb9bb0841d89fff09820a57369df4cb01b16b43.zip | |
Merge branch 'trunk' into xwidget
Conflicts:
src/xdisp.c
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 159 |
1 files changed, 61 insertions, 98 deletions
diff --git a/src/process.c b/src/process.c index 9961697e671..8589acaa8b5 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -78,7 +78,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 78 | #endif | 78 | #endif |
| 79 | 79 | ||
| 80 | #ifdef HAVE_RES_INIT | 80 | #ifdef HAVE_RES_INIT |
| 81 | #include <netinet/in.h> | ||
| 82 | #include <arpa/nameser.h> | 81 | #include <arpa/nameser.h> |
| 83 | #include <resolv.h> | 82 | #include <resolv.h> |
| 84 | #endif | 83 | #endif |
| @@ -136,6 +135,37 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, | |||
| 136 | EMACS_TIME *, void *); | 135 | EMACS_TIME *, void *); |
| 137 | #endif | 136 | #endif |
| 138 | 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 | |||
| 139 | /* 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 |
| 140 | <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>. | 170 | <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>. |
| 141 | These lines can be removed once the GCC bug is fixed. */ | 171 | These lines can be removed once the GCC bug is fixed. */ |
| @@ -1586,6 +1616,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1586 | { | 1616 | { |
| 1587 | int inchannel, outchannel; | 1617 | int inchannel, outchannel; |
| 1588 | pid_t pid; | 1618 | pid_t pid; |
| 1619 | int vfork_errno; | ||
| 1589 | int sv[2]; | 1620 | int sv[2]; |
| 1590 | #ifndef WINDOWSNT | 1621 | #ifndef WINDOWSNT |
| 1591 | int wait_child_setup[2]; | 1622 | int wait_child_setup[2]; |
| @@ -1620,47 +1651,30 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1620 | else | 1651 | else |
| 1621 | #endif /* HAVE_PTYS */ | 1652 | #endif /* HAVE_PTYS */ |
| 1622 | { | 1653 | { |
| 1623 | int tem; | 1654 | if (pipe2 (sv, O_CLOEXEC) != 0) |
| 1624 | tem = pipe (sv); | ||
| 1625 | if (tem < 0) | ||
| 1626 | report_file_error ("Creating pipe", Qnil); | 1655 | report_file_error ("Creating pipe", Qnil); |
| 1627 | inchannel = sv[0]; | 1656 | inchannel = sv[0]; |
| 1628 | forkout = sv[1]; | 1657 | forkout = sv[1]; |
| 1629 | tem = pipe (sv); | 1658 | if (pipe2 (sv, O_CLOEXEC) != 0) |
| 1630 | if (tem < 0) | ||
| 1631 | { | 1659 | { |
| 1660 | int pipe_errno = errno; | ||
| 1632 | emacs_close (inchannel); | 1661 | emacs_close (inchannel); |
| 1633 | emacs_close (forkout); | 1662 | emacs_close (forkout); |
| 1634 | report_file_error ("Creating pipe", Qnil); | 1663 | report_file_errno ("Creating pipe", Qnil, pipe_errno); |
| 1635 | } | 1664 | } |
| 1636 | outchannel = sv[1]; | 1665 | outchannel = sv[1]; |
| 1637 | forkin = sv[0]; | 1666 | forkin = sv[0]; |
| 1638 | } | 1667 | } |
| 1639 | 1668 | ||
| 1640 | #ifndef WINDOWSNT | 1669 | #ifndef WINDOWSNT |
| 1641 | { | 1670 | if (pipe2 (wait_child_setup, O_CLOEXEC) != 0) |
| 1642 | int tem; | 1671 | report_file_error ("Creating pipe", Qnil); |
| 1643 | |||
| 1644 | tem = pipe (wait_child_setup); | ||
| 1645 | if (tem < 0) | ||
| 1646 | report_file_error ("Creating pipe", Qnil); | ||
| 1647 | tem = fcntl (wait_child_setup[1], F_GETFD, 0); | ||
| 1648 | if (tem >= 0) | ||
| 1649 | tem = fcntl (wait_child_setup[1], F_SETFD, tem | FD_CLOEXEC); | ||
| 1650 | if (tem < 0) | ||
| 1651 | { | ||
| 1652 | emacs_close (wait_child_setup[0]); | ||
| 1653 | emacs_close (wait_child_setup[1]); | ||
| 1654 | report_file_error ("Setting file descriptor flags", Qnil); | ||
| 1655 | } | ||
| 1656 | } | ||
| 1657 | #endif | 1672 | #endif |
| 1658 | 1673 | ||
| 1659 | fcntl (inchannel, F_SETFL, O_NONBLOCK); | 1674 | fcntl (inchannel, F_SETFL, O_NONBLOCK); |
| 1660 | fcntl (outchannel, F_SETFL, O_NONBLOCK); | 1675 | fcntl (outchannel, F_SETFL, O_NONBLOCK); |
| 1661 | 1676 | ||
| 1662 | /* Record this as an active process, with its channels. | 1677 | /* Record this as an active process, with its channels. */ |
| 1663 | As a result, child_setup will close Emacs's side of the pipes. */ | ||
| 1664 | chan_process[inchannel] = process; | 1678 | chan_process[inchannel] = process; |
| 1665 | XPROCESS (process)->infd = inchannel; | 1679 | XPROCESS (process)->infd = inchannel; |
| 1666 | XPROCESS (process)->outfd = outchannel; | 1680 | XPROCESS (process)->outfd = outchannel; |
| @@ -1740,7 +1754,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1740 | tcgetattr (xforkin, &t); | 1754 | tcgetattr (xforkin, &t); |
| 1741 | t.c_lflag = LDISC1; | 1755 | t.c_lflag = LDISC1; |
| 1742 | if (tcsetattr (xforkin, TCSANOW, &t) < 0) | 1756 | if (tcsetattr (xforkin, TCSANOW, &t) < 0) |
| 1743 | emacs_write (1, "create_process/tcsetattr LDISC1 failed\n", 39); | 1757 | emacs_perror ("create_process/tcsetattr LDISC1"); |
| 1744 | } | 1758 | } |
| 1745 | #else | 1759 | #else |
| 1746 | #if defined (NTTYDISC) && defined (TIOCSETD) | 1760 | #if defined (NTTYDISC) && defined (TIOCSETD) |
| @@ -1787,10 +1801,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1787 | 1801 | ||
| 1788 | if (xforkin < 0) | 1802 | if (xforkin < 0) |
| 1789 | { | 1803 | { |
| 1790 | emacs_write (1, "Couldn't open the pty terminal ", 31); | 1804 | emacs_perror (pty_name); |
| 1791 | emacs_write (1, pty_name, strlen (pty_name)); | 1805 | _exit (EXIT_CANCELED); |
| 1792 | emacs_write (1, "\n", 1); | ||
| 1793 | _exit (1); | ||
| 1794 | } | 1806 | } |
| 1795 | 1807 | ||
| 1796 | } | 1808 | } |
| @@ -1802,12 +1814,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1802 | SETUP_SLAVE_PTY; | 1814 | SETUP_SLAVE_PTY; |
| 1803 | } | 1815 | } |
| 1804 | #endif /* SETUP_SLAVE_PTY */ | 1816 | #endif /* SETUP_SLAVE_PTY */ |
| 1805 | #ifdef AIX | ||
| 1806 | /* On AIX, we've disabled SIGHUP above once we start a child on a pty. | ||
| 1807 | Now reenable it in the child, so it will die when we want it to. */ | ||
| 1808 | if (pty_flag) | ||
| 1809 | signal (SIGHUP, SIG_DFL); | ||
| 1810 | #endif | ||
| 1811 | #endif /* HAVE_PTYS */ | 1817 | #endif /* HAVE_PTYS */ |
| 1812 | 1818 | ||
| 1813 | signal (SIGINT, SIG_DFL); | 1819 | signal (SIGINT, SIG_DFL); |
| @@ -1825,7 +1831,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1825 | pid = child_setup (xforkin, xforkout, xforkout, | 1831 | pid = child_setup (xforkin, xforkout, xforkout, |
| 1826 | new_argv, 1, encoded_current_dir); | 1832 | new_argv, 1, encoded_current_dir); |
| 1827 | #else /* not WINDOWSNT */ | 1833 | #else /* not WINDOWSNT */ |
| 1828 | emacs_close (wait_child_setup[0]); | ||
| 1829 | child_setup (xforkin, xforkout, xforkout, | 1834 | child_setup (xforkin, xforkout, xforkout, |
| 1830 | new_argv, 1, encoded_current_dir); | 1835 | new_argv, 1, encoded_current_dir); |
| 1831 | #endif /* not WINDOWSNT */ | 1836 | #endif /* not WINDOWSNT */ |
| @@ -1833,6 +1838,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1833 | 1838 | ||
| 1834 | /* Back in the parent process. */ | 1839 | /* Back in the parent process. */ |
| 1835 | 1840 | ||
| 1841 | vfork_errno = errno; | ||
| 1836 | XPROCESS (process)->pid = pid; | 1842 | XPROCESS (process)->pid = pid; |
| 1837 | if (pid >= 0) | 1843 | if (pid >= 0) |
| 1838 | XPROCESS (process)->alive = 1; | 1844 | XPROCESS (process)->alive = 1; |
| @@ -1847,6 +1853,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1847 | emacs_close (forkin); | 1853 | emacs_close (forkin); |
| 1848 | if (forkin != forkout && forkout >= 0) | 1854 | if (forkin != forkout && forkout >= 0) |
| 1849 | emacs_close (forkout); | 1855 | emacs_close (forkout); |
| 1856 | report_file_errno ("Doing vfork", Qnil, vfork_errno); | ||
| 1850 | } | 1857 | } |
| 1851 | else | 1858 | else |
| 1852 | { | 1859 | { |
| @@ -1892,10 +1899,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1892 | } | 1899 | } |
| 1893 | #endif | 1900 | #endif |
| 1894 | } | 1901 | } |
| 1895 | |||
| 1896 | /* Now generate the error if vfork failed. */ | ||
| 1897 | if (pid < 0) | ||
| 1898 | report_file_error ("Doing vfork", Qnil); | ||
| 1899 | } | 1902 | } |
| 1900 | 1903 | ||
| 1901 | void | 1904 | void |
| @@ -3136,7 +3139,8 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3136 | retry_connect: | 3139 | retry_connect: |
| 3137 | #endif | 3140 | #endif |
| 3138 | 3141 | ||
| 3139 | s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); | 3142 | s = socket (lres->ai_family, lres->ai_socktype | SOCK_CLOEXEC, |
| 3143 | lres->ai_protocol); | ||
| 3140 | if (s < 0) | 3144 | if (s < 0) |
| 3141 | { | 3145 | { |
| 3142 | xerrno = errno; | 3146 | xerrno = errno; |
| @@ -3260,12 +3264,11 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3260 | 3264 | ||
| 3261 | len = sizeof xerrno; | 3265 | len = sizeof xerrno; |
| 3262 | eassert (FD_ISSET (s, &fdset)); | 3266 | eassert (FD_ISSET (s, &fdset)); |
| 3263 | if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) == -1) | 3267 | if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0) |
| 3264 | report_file_error ("getsockopt failed", Qnil); | 3268 | report_file_error ("getsockopt failed", Qnil); |
| 3265 | if (xerrno) | 3269 | if (xerrno) |
| 3266 | errno = xerrno, report_file_error ("error during connect", Qnil); | 3270 | report_file_errno ("error during connect", Qnil, xerrno); |
| 3267 | else | 3271 | break; |
| 3268 | break; | ||
| 3269 | } | 3272 | } |
| 3270 | #endif /* !WINDOWSNT */ | 3273 | #endif /* !WINDOWSNT */ |
| 3271 | 3274 | ||
| @@ -3349,11 +3352,10 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3349 | if (is_non_blocking_client) | 3352 | if (is_non_blocking_client) |
| 3350 | return Qnil; | 3353 | return Qnil; |
| 3351 | 3354 | ||
| 3352 | errno = xerrno; | 3355 | report_file_errno ((is_server |
| 3353 | if (is_server) | 3356 | ? "make server process failed" |
| 3354 | report_file_error ("make server process failed", contact); | 3357 | : "make client process failed"), |
| 3355 | else | 3358 | contact, xerrno); |
| 3356 | report_file_error ("make client process failed", contact); | ||
| 3357 | } | 3359 | } |
| 3358 | 3360 | ||
| 3359 | inch = s; | 3361 | inch = s; |
| @@ -3533,7 +3535,7 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3533 | int s; | 3535 | int s; |
| 3534 | Lisp_Object res; | 3536 | Lisp_Object res; |
| 3535 | 3537 | ||
| 3536 | s = socket (AF_INET, SOCK_STREAM, 0); | 3538 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); |
| 3537 | if (s < 0) | 3539 | if (s < 0) |
| 3538 | return Qnil; | 3540 | return Qnil; |
| 3539 | 3541 | ||
| @@ -3544,14 +3546,14 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3544 | ifconf.ifc_len = buf_size; | 3546 | ifconf.ifc_len = buf_size; |
| 3545 | if (ioctl (s, SIOCGIFCONF, &ifconf)) | 3547 | if (ioctl (s, SIOCGIFCONF, &ifconf)) |
| 3546 | { | 3548 | { |
| 3547 | close (s); | 3549 | emacs_close (s); |
| 3548 | xfree (buf); | 3550 | xfree (buf); |
| 3549 | return Qnil; | 3551 | return Qnil; |
| 3550 | } | 3552 | } |
| 3551 | } | 3553 | } |
| 3552 | while (ifconf.ifc_len == buf_size); | 3554 | while (ifconf.ifc_len == buf_size); |
| 3553 | 3555 | ||
| 3554 | close (s); | 3556 | emacs_close (s); |
| 3555 | 3557 | ||
| 3556 | res = Qnil; | 3558 | res = Qnil; |
| 3557 | ifreq = ifconf.ifc_req; | 3559 | ifreq = ifconf.ifc_req; |
| @@ -3689,7 +3691,7 @@ FLAGS is the current flags of the interface. */) | |||
| 3689 | error ("interface name too long"); | 3691 | error ("interface name too long"); |
| 3690 | strcpy (rq.ifr_name, SSDATA (ifname)); | 3692 | strcpy (rq.ifr_name, SSDATA (ifname)); |
| 3691 | 3693 | ||
| 3692 | s = socket (AF_INET, SOCK_STREAM, 0); | 3694 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); |
| 3693 | if (s < 0) | 3695 | if (s < 0) |
| 3694 | return Qnil; | 3696 | return Qnil; |
| 3695 | 3697 | ||
| @@ -3808,7 +3810,7 @@ FLAGS is the current flags of the interface. */) | |||
| 3808 | #endif | 3810 | #endif |
| 3809 | res = Fcons (elt, res); | 3811 | res = Fcons (elt, res); |
| 3810 | 3812 | ||
| 3811 | close (s); | 3813 | emacs_close (s); |
| 3812 | 3814 | ||
| 3813 | return any ? res : Qnil; | 3815 | return any ? res : Qnil; |
| 3814 | } | 3816 | } |
| @@ -3985,7 +3987,7 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 3985 | } saddr; | 3987 | } saddr; |
| 3986 | socklen_t len = sizeof saddr; | 3988 | socklen_t len = sizeof saddr; |
| 3987 | 3989 | ||
| 3988 | s = accept (channel, &saddr.sa, &len); | 3990 | s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC); |
| 3989 | 3991 | ||
| 3990 | if (s < 0) | 3992 | if (s < 0) |
| 3991 | { | 3993 | { |
| @@ -4621,20 +4623,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4621 | if (xerrno == EINTR) | 4623 | if (xerrno == EINTR) |
| 4622 | no_avail = 1; | 4624 | no_avail = 1; |
| 4623 | else if (xerrno == EBADF) | 4625 | else if (xerrno == EBADF) |
| 4624 | { | 4626 | emacs_abort (); |
| 4625 | #ifdef AIX | ||
| 4626 | /* AIX doesn't handle PTY closure the same way BSD does. On AIX, | ||
| 4627 | the child's closure of the pts gives the parent a SIGHUP, and | ||
| 4628 | the ptc file descriptor is automatically closed, | ||
| 4629 | yielding EBADF here or at select() call above. | ||
| 4630 | So, SIGHUP is ignored (see def of PTY_TTY_NAME_SPRINTF | ||
| 4631 | in m/ibmrt-aix.h), and here we just ignore the select error. | ||
| 4632 | Cleanup occurs c/o status_notify after SIGCHLD. */ | ||
| 4633 | no_avail = 1; /* Cannot depend on values returned */ | ||
| 4634 | #else | ||
| 4635 | emacs_abort (); | ||
| 4636 | #endif | ||
| 4637 | } | ||
| 4638 | else | 4627 | else |
| 4639 | error ("select error: %s", emacs_strerror (xerrno)); | 4628 | error ("select error: %s", emacs_strerror (xerrno)); |
| 4640 | } | 4629 | } |
| @@ -5490,7 +5479,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, | |||
| 5490 | written = emacs_gnutls_write (p, cur_buf, cur_len); | 5479 | written = emacs_gnutls_write (p, cur_buf, cur_len); |
| 5491 | else | 5480 | else |
| 5492 | #endif | 5481 | #endif |
| 5493 | written = emacs_write (outfd, cur_buf, cur_len); | 5482 | written = emacs_write_sig (outfd, cur_buf, cur_len); |
| 5494 | rv = (written ? 0 : -1); | 5483 | rv = (written ? 0 : -1); |
| 5495 | #ifdef ADAPTIVE_READ_BUFFERING | 5484 | #ifdef ADAPTIVE_READ_BUFFERING |
| 5496 | if (p->read_output_delay > 0 | 5485 | if (p->read_output_delay > 0 |
| @@ -6859,32 +6848,6 @@ setup_process_coding_systems (Lisp_Object process) | |||
| 6859 | #endif | 6848 | #endif |
| 6860 | } | 6849 | } |
| 6861 | 6850 | ||
| 6862 | /* Close all descriptors currently in use for communication | ||
| 6863 | with subprocess. This is used in a newly-forked subprocess | ||
| 6864 | to get rid of irrelevant descriptors. */ | ||
| 6865 | |||
| 6866 | void | ||
| 6867 | close_process_descs (void) | ||
| 6868 | { | ||
| 6869 | #ifndef DOS_NT | ||
| 6870 | int i; | ||
| 6871 | for (i = 0; i < MAXDESC; i++) | ||
| 6872 | { | ||
| 6873 | Lisp_Object process; | ||
| 6874 | process = chan_process[i]; | ||
| 6875 | if (!NILP (process)) | ||
| 6876 | { | ||
| 6877 | int in = XPROCESS (process)->infd; | ||
| 6878 | int out = XPROCESS (process)->outfd; | ||
| 6879 | if (in >= 0) | ||
| 6880 | emacs_close (in); | ||
| 6881 | if (out >= 0 && in != out) | ||
| 6882 | emacs_close (out); | ||
| 6883 | } | ||
| 6884 | } | ||
| 6885 | #endif | ||
| 6886 | } | ||
| 6887 | |||
| 6888 | DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, | 6851 | DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, |
| 6889 | doc: /* Return the (or a) process associated with BUFFER. | 6852 | doc: /* Return the (or a) process associated with BUFFER. |
| 6890 | BUFFER may be a buffer or the name of one. */) | 6853 | BUFFER may be a buffer or the name of one. */) |