diff options
| author | Paul Eggert | 2013-08-12 00:12:07 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-08-12 00:12:07 -0700 |
| commit | 94fcd171894e3a14d3548c028c4229229e32d184 (patch) | |
| tree | 5db95055c61a05f2b4edb6d0d74cb4e2692f6533 /src/process.c | |
| parent | 4750fd7bf40585eb3956e86e521a7508eaa0f35f (diff) | |
| download | emacs-94fcd171894e3a14d3548c028c4229229e32d184.tar.gz emacs-94fcd171894e3a14d3548c028c4229229e32d184.zip | |
Fix some fd issues when running subprocesses.
Fix bugs that can leak files or file descriptors on errors.
Don't unlink open temp files, as that's hard for users to diagnose
when things go awry (e.g., temp disk exhausted).
Don't bother to lock temp files. Check for invalid recursion.
* callproc.c (synch_process_fd): Remove. All uses removed.
(synch_process_tempfile): New var or macro.
(CALLPROC_STDOUT, CALLPROC_STDERR, CALLPROC_PIPEREAD, CALLPROC_FDS):
New constants.
(record_kill_process): New arg, the temp name. All callers changed.
(delete_temp_file): Now just a simple wrapper around unlink.
(call_process_kill): New arg, the call_process_fd array.
Close them all. Clear synch_process_pid. Remove the temp file,
or arrange for it to be removed.
(call_process_cleanup) [MSDOS]: Arg no longer contains file name;
that's been moved to synch_process_tempfile. Caller changed.
Do not remove the tempfile; that's now call_process_kill's
responsibility.
(call_process_cleanup) [!MSDOS]: Do not record unwind-protect for
call_process_kill; the caller now does that.
(call_process_cleanup): Do not close the process fd; that's now
call_process_kill's responsibility.
(Fcall_process): Implement via new function call_process, which
has most of the old body of Fcall_process, but with a different API.
(call_process): New function that does not open or close filefd if
it is nonnegative. Record which fds need to be closed, and let
call_process_kill close (and remove the tempfile, on MSDOS) on error.
Signal an error if invoked recursively (could be done via a hook).
Simplify creation of the tempfile in the MSDOS case.
Don't create the output file until after checking for the executable.
Report any failure to open /dev/null.
Don't open /dev/null for writing twice; once is enough.
Don't create pipe if all output is being discarded or sent to file.
Don't worry about setting up the coding system or reading from the
pipe if all output is being discarded.
Hoist fd_error local into top level, to lessen block nesting.
Don't record deleted pid here; now done by Fcall_process_region.
(Fcall_process) [MSDOS]: Report mktemp failure immediately,
and note its success in synch_process_tempfile.
Do not leak resources when child_setup fails.
(Fcall_process) [!MSDOS && !WINDOWSNT]: Remove duplicate assignment
to child_errno. Remove unnecessary close of fd0; it's close-on-exec.
(create_temp_file): Now returns open fd, with an additional
Lisp_Object * argument to return the name. All callers changed.
Do not close the file; rewind it instead, and leave it open for
the caller. Do not lock the temp file. Unwind-protect the file
and the file-descriptor.
(Fcall_process_region): If the input is /dev/null, unwind-protect it.
If an asynchrounous process, record it here, not in call_process.
(syms_of_callproc) [MSDOS]: Initialize synch_process_tempfile.
* eval.c (set_unwind_protect): New function.
* fileio.c (write_region): New function, generalized from the
old Fwrite_region. Do not lock temp files.
(Fwrite_region): Use it.
* lisp.h (set_unwind_protect, write_region): New decls.
* process.c: Include <verify.h>.
(make_process): Mark fds as initially closed.
(deleted_pid_list): Now a list of pid-filename pairs.
All uses changed.
(close_process_fd): New function.
(SUBPROCESS_STDIN, WRITE_TO_SUBPROCESS, READ_FROM_SUBPROCESS)
(SUBPROCESS_STDOUT, READ_FROM_EXEC_MONITOR, EXEC_MONITOR_OUTPUT):
New constants. Verify that their number matches PROCESS_OPEN_FDS.
(create_process, create_pty, Fmake_serial_process)
(server_accept_connection): Record which fds need to be closed,
and let deactivate_process close them.
(Fmake_network_process): Do not discard the unwind-protect
until it's safe to do so.
(deactivate_process): Close the fds opened by create_process etc.
(Fprocess_send_eof): Adjust to new way of recording open fds.
Report an error if /dev/null can't be opened, instead of aborting.
* process.h (PROCESS_OPEN_FDS): New constant.
(struct Lisp_Process): New member open_fds.
(record_kill_process, record_deleted_pid): Adjust signatures.
(record_deleted_pid): Move decl here ...
* syswait.h (record_deleted_pid): ... from here.
Fixes: debbugs:15035
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 225 |
1 files changed, 127 insertions, 98 deletions
diff --git a/src/process.c b/src/process.c index 99c707ff97b..a2bcffe5160 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -92,6 +92,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 92 | 92 | ||
| 93 | #include <c-ctype.h> | 93 | #include <c-ctype.h> |
| 94 | #include <sig2str.h> | 94 | #include <sig2str.h> |
| 95 | #include <verify.h> | ||
| 95 | 96 | ||
| 96 | #endif /* subprocesses */ | 97 | #endif /* subprocesses */ |
| 97 | 98 | ||
| @@ -722,6 +723,8 @@ make_process (Lisp_Object name) | |||
| 722 | non-Lisp data, so do it only for slots which should not be zero. */ | 723 | non-Lisp data, so do it only for slots which should not be zero. */ |
| 723 | p->infd = -1; | 724 | p->infd = -1; |
| 724 | p->outfd = -1; | 725 | p->outfd = -1; |
| 726 | for (i = 0; i < PROCESS_OPEN_FDS; i++) | ||
| 727 | p->open_fd[i] = -1; | ||
| 725 | 728 | ||
| 726 | #ifdef HAVE_GNUTLS | 729 | #ifdef HAVE_GNUTLS |
| 727 | p->gnutls_initstage = GNUTLS_STAGE_EMPTY; | 730 | p->gnutls_initstage = GNUTLS_STAGE_EMPTY; |
| @@ -818,13 +821,17 @@ get_process (register Lisp_Object name) | |||
| 818 | treated by the SIGCHLD handler and waitpid has been invoked on them; | 821 | treated by the SIGCHLD handler and waitpid has been invoked on them; |
| 819 | otherwise they might fill up the kernel's process table. | 822 | otherwise they might fill up the kernel's process table. |
| 820 | 823 | ||
| 821 | Some processes created by call-process are also put onto this list. */ | 824 | Some processes created by call-process are also put onto this list. |
| 825 | |||
| 826 | Members of this list are (process-ID . filename) pairs. The | ||
| 827 | process-ID is a number; the filename, if a string, is a file that | ||
| 828 | needs to be removed after the process exits. */ | ||
| 822 | static Lisp_Object deleted_pid_list; | 829 | static Lisp_Object deleted_pid_list; |
| 823 | 830 | ||
| 824 | void | 831 | void |
| 825 | record_deleted_pid (pid_t pid) | 832 | record_deleted_pid (pid_t pid, Lisp_Object filename) |
| 826 | { | 833 | { |
| 827 | deleted_pid_list = Fcons (make_fixnum_or_float (pid), | 834 | deleted_pid_list = Fcons (Fcons (make_fixnum_or_float (pid), filename), |
| 828 | /* GC treated elements set to nil. */ | 835 | /* GC treated elements set to nil. */ |
| 829 | Fdelq (Qnil, deleted_pid_list)); | 836 | Fdelq (Qnil, deleted_pid_list)); |
| 830 | 837 | ||
| @@ -852,7 +859,7 @@ nil, indicating the current buffer's process. */) | |||
| 852 | else | 859 | else |
| 853 | { | 860 | { |
| 854 | if (p->alive) | 861 | if (p->alive) |
| 855 | record_kill_process (p); | 862 | record_kill_process (p, Qnil); |
| 856 | 863 | ||
| 857 | if (p->infd >= 0) | 864 | if (p->infd >= 0) |
| 858 | { | 865 | { |
| @@ -1605,17 +1612,45 @@ start_process_unwind (Lisp_Object proc) | |||
| 1605 | remove_process (proc); | 1612 | remove_process (proc); |
| 1606 | } | 1613 | } |
| 1607 | 1614 | ||
| 1615 | /* If *FD_ADDR is nonnegative, close it, and mark it as closed. */ | ||
| 1616 | |||
| 1617 | static void | ||
| 1618 | close_process_fd (int *fd_addr) | ||
| 1619 | { | ||
| 1620 | int fd = *fd_addr; | ||
| 1621 | if (0 <= fd) | ||
| 1622 | { | ||
| 1623 | *fd_addr = -1; | ||
| 1624 | emacs_close (fd); | ||
| 1625 | } | ||
| 1626 | } | ||
| 1627 | |||
| 1628 | /* Indexes of file descriptors in open_fds. */ | ||
| 1629 | enum | ||
| 1630 | { | ||
| 1631 | /* The pipe from Emacs to its subprocess. */ | ||
| 1632 | SUBPROCESS_STDIN, | ||
| 1633 | WRITE_TO_SUBPROCESS, | ||
| 1634 | |||
| 1635 | /* The main pipe from the subprocess to Emacs. */ | ||
| 1636 | READ_FROM_SUBPROCESS, | ||
| 1637 | SUBPROCESS_STDOUT, | ||
| 1638 | |||
| 1639 | /* The pipe from the subprocess to Emacs that is closed when the | ||
| 1640 | subprocess execs. */ | ||
| 1641 | READ_FROM_EXEC_MONITOR, | ||
| 1642 | EXEC_MONITOR_OUTPUT | ||
| 1643 | }; | ||
| 1644 | |||
| 1645 | verify (PROCESS_OPEN_FDS == EXEC_MONITOR_OUTPUT + 1); | ||
| 1608 | 1646 | ||
| 1609 | static void | 1647 | static void |
| 1610 | create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | 1648 | create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) |
| 1611 | { | 1649 | { |
| 1650 | struct Lisp_Process *p = XPROCESS (process); | ||
| 1612 | int inchannel, outchannel; | 1651 | int inchannel, outchannel; |
| 1613 | pid_t pid; | 1652 | pid_t pid; |
| 1614 | int vfork_errno; | 1653 | int vfork_errno; |
| 1615 | int sv[2]; | ||
| 1616 | #ifndef WINDOWSNT | ||
| 1617 | int wait_child_setup[2]; | ||
| 1618 | #endif | ||
| 1619 | int forkin, forkout; | 1654 | int forkin, forkout; |
| 1620 | bool pty_flag = 0; | 1655 | bool pty_flag = 0; |
| 1621 | char pty_name[PTY_NAME_SIZE]; | 1656 | char pty_name[PTY_NAME_SIZE]; |
| @@ -1629,6 +1664,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1629 | 1664 | ||
| 1630 | if (inchannel >= 0) | 1665 | if (inchannel >= 0) |
| 1631 | { | 1666 | { |
| 1667 | p->open_fd[READ_FROM_SUBPROCESS] = inchannel; | ||
| 1632 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) | 1668 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) |
| 1633 | /* On most USG systems it does not work to open the pty's tty here, | 1669 | /* On most USG systems it does not work to open the pty's tty here, |
| 1634 | then close it and reopen it in the child. */ | 1670 | then close it and reopen it in the child. */ |
| @@ -1637,6 +1673,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1637 | forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); | 1673 | forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); |
| 1638 | if (forkin < 0) | 1674 | if (forkin < 0) |
| 1639 | report_file_error ("Opening pty", Qnil); | 1675 | report_file_error ("Opening pty", Qnil); |
| 1676 | p->open_fd[SUBPROCESS_STDIN] = forkin; | ||
| 1640 | #else | 1677 | #else |
| 1641 | forkin = forkout = -1; | 1678 | forkin = forkout = -1; |
| 1642 | #endif /* not USG, or USG_SUBTTY_WORKS */ | 1679 | #endif /* not USG, or USG_SUBTTY_WORKS */ |
| @@ -1645,23 +1682,17 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1645 | } | 1682 | } |
| 1646 | else | 1683 | else |
| 1647 | { | 1684 | { |
| 1648 | if (emacs_pipe (sv) != 0) | 1685 | if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0 |
| 1686 | || emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0) | ||
| 1649 | report_file_error ("Creating pipe", Qnil); | 1687 | report_file_error ("Creating pipe", Qnil); |
| 1650 | inchannel = sv[0]; | 1688 | forkin = p->open_fd[SUBPROCESS_STDIN]; |
| 1651 | forkout = sv[1]; | 1689 | outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; |
| 1652 | if (emacs_pipe (sv) != 0) | 1690 | inchannel = p->open_fd[READ_FROM_SUBPROCESS]; |
| 1653 | { | 1691 | forkout = p->open_fd[SUBPROCESS_STDOUT]; |
| 1654 | int pipe_errno = errno; | ||
| 1655 | emacs_close (inchannel); | ||
| 1656 | emacs_close (forkout); | ||
| 1657 | report_file_errno ("Creating pipe", Qnil, pipe_errno); | ||
| 1658 | } | ||
| 1659 | outchannel = sv[1]; | ||
| 1660 | forkin = sv[0]; | ||
| 1661 | } | 1692 | } |
| 1662 | 1693 | ||
| 1663 | #ifndef WINDOWSNT | 1694 | #ifndef WINDOWSNT |
| 1664 | if (emacs_pipe (wait_child_setup) != 0) | 1695 | if (emacs_pipe (p->open_fd + READ_FROM_EXEC_MONITOR) != 0) |
| 1665 | report_file_error ("Creating pipe", Qnil); | 1696 | report_file_error ("Creating pipe", Qnil); |
| 1666 | #endif | 1697 | #endif |
| 1667 | 1698 | ||
| @@ -1670,16 +1701,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1670 | 1701 | ||
| 1671 | /* Record this as an active process, with its channels. */ | 1702 | /* Record this as an active process, with its channels. */ |
| 1672 | chan_process[inchannel] = process; | 1703 | chan_process[inchannel] = process; |
| 1673 | XPROCESS (process)->infd = inchannel; | 1704 | p->infd = inchannel; |
| 1674 | XPROCESS (process)->outfd = outchannel; | 1705 | p->outfd = outchannel; |
| 1675 | 1706 | ||
| 1676 | /* Previously we recorded the tty descriptor used in the subprocess. | 1707 | /* Previously we recorded the tty descriptor used in the subprocess. |
| 1677 | It was only used for getting the foreground tty process, so now | 1708 | It was only used for getting the foreground tty process, so now |
| 1678 | we just reopen the device (see emacs_get_tty_pgrp) as this is | 1709 | we just reopen the device (see emacs_get_tty_pgrp) as this is |
| 1679 | more portable (see USG_SUBTTY_WORKS above). */ | 1710 | more portable (see USG_SUBTTY_WORKS above). */ |
| 1680 | 1711 | ||
| 1681 | XPROCESS (process)->pty_flag = pty_flag; | 1712 | p->pty_flag = pty_flag; |
| 1682 | pset_status (XPROCESS (process), Qrun); | 1713 | pset_status (p, Qrun); |
| 1683 | 1714 | ||
| 1684 | FD_SET (inchannel, &input_wait_mask); | 1715 | FD_SET (inchannel, &input_wait_mask); |
| 1685 | FD_SET (inchannel, &non_keyboard_wait_mask); | 1716 | FD_SET (inchannel, &non_keyboard_wait_mask); |
| @@ -1699,25 +1730,21 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1699 | { | 1730 | { |
| 1700 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; | 1731 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; |
| 1701 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; | 1732 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; |
| 1702 | Lisp_Object volatile process_volatile = process; | ||
| 1703 | char **volatile new_argv_volatile = new_argv; | 1733 | char **volatile new_argv_volatile = new_argv; |
| 1704 | int volatile forkin_volatile = forkin; | 1734 | int volatile forkin_volatile = forkin; |
| 1705 | int volatile forkout_volatile = forkout; | 1735 | int volatile forkout_volatile = forkout; |
| 1706 | int volatile wait_child_setup_0_volatile = wait_child_setup[0]; | 1736 | struct Lisp_Process *p_volatile = p; |
| 1707 | int volatile wait_child_setup_1_volatile = wait_child_setup[1]; | ||
| 1708 | 1737 | ||
| 1709 | pid = vfork (); | 1738 | pid = vfork (); |
| 1710 | 1739 | ||
| 1711 | encoded_current_dir = encoded_current_dir_volatile; | 1740 | encoded_current_dir = encoded_current_dir_volatile; |
| 1712 | lisp_pty_name = lisp_pty_name_volatile; | 1741 | lisp_pty_name = lisp_pty_name_volatile; |
| 1713 | process = process_volatile; | ||
| 1714 | new_argv = new_argv_volatile; | 1742 | new_argv = new_argv_volatile; |
| 1715 | forkin = forkin_volatile; | 1743 | forkin = forkin_volatile; |
| 1716 | forkout = forkout_volatile; | 1744 | forkout = forkout_volatile; |
| 1717 | wait_child_setup[0] = wait_child_setup_0_volatile; | 1745 | p = p_volatile; |
| 1718 | wait_child_setup[1] = wait_child_setup_1_volatile; | ||
| 1719 | 1746 | ||
| 1720 | pty_flag = XPROCESS (process)->pty_flag; | 1747 | pty_flag = p->pty_flag; |
| 1721 | } | 1748 | } |
| 1722 | 1749 | ||
| 1723 | if (pid == 0) | 1750 | if (pid == 0) |
| @@ -1833,42 +1860,42 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1833 | /* Back in the parent process. */ | 1860 | /* Back in the parent process. */ |
| 1834 | 1861 | ||
| 1835 | vfork_errno = errno; | 1862 | vfork_errno = errno; |
| 1836 | XPROCESS (process)->pid = pid; | 1863 | p->pid = pid; |
| 1837 | if (pid >= 0) | 1864 | if (pid >= 0) |
| 1838 | XPROCESS (process)->alive = 1; | 1865 | p->alive = 1; |
| 1839 | 1866 | ||
| 1840 | /* Stop blocking in the parent. */ | 1867 | /* Stop blocking in the parent. */ |
| 1841 | unblock_child_signal (); | 1868 | unblock_child_signal (); |
| 1842 | unblock_input (); | 1869 | unblock_input (); |
| 1843 | 1870 | ||
| 1844 | if (forkin >= 0) | ||
| 1845 | emacs_close (forkin); | ||
| 1846 | if (forkin != forkout && forkout >= 0) | ||
| 1847 | emacs_close (forkout); | ||
| 1848 | |||
| 1849 | if (pid < 0) | 1871 | if (pid < 0) |
| 1850 | report_file_errno ("Doing vfork", Qnil, vfork_errno); | 1872 | report_file_errno ("Doing vfork", Qnil, vfork_errno); |
| 1851 | else | 1873 | else |
| 1852 | { | 1874 | { |
| 1853 | /* vfork succeeded. */ | 1875 | /* vfork succeeded. */ |
| 1854 | 1876 | ||
| 1877 | /* Close the pipe ends that the child uses, or the child's pty. */ | ||
| 1878 | close_process_fd (&p->open_fd[SUBPROCESS_STDIN]); | ||
| 1879 | close_process_fd (&p->open_fd[SUBPROCESS_STDOUT]); | ||
| 1880 | |||
| 1855 | #ifdef WINDOWSNT | 1881 | #ifdef WINDOWSNT |
| 1856 | register_child (pid, inchannel); | 1882 | register_child (pid, inchannel); |
| 1857 | #endif /* WINDOWSNT */ | 1883 | #endif /* WINDOWSNT */ |
| 1858 | 1884 | ||
| 1859 | pset_tty_name (XPROCESS (process), lisp_pty_name); | 1885 | pset_tty_name (p, lisp_pty_name); |
| 1860 | 1886 | ||
| 1861 | #ifndef WINDOWSNT | 1887 | #ifndef WINDOWSNT |
| 1862 | /* Wait for child_setup to complete in case that vfork is | 1888 | /* Wait for child_setup to complete in case that vfork is |
| 1863 | actually defined as fork. The descriptor wait_child_setup[1] | 1889 | actually defined as fork. The descriptor |
| 1890 | XPROCESS (proc)->open_fd[EXEC_MOINTOR_OUTPUT] | ||
| 1864 | of a pipe is closed at the child side either by close-on-exec | 1891 | of a pipe is closed at the child side either by close-on-exec |
| 1865 | on successful execve or the _exit call in child_setup. */ | 1892 | on successful execve or the _exit call in child_setup. */ |
| 1866 | { | 1893 | { |
| 1867 | char dummy; | 1894 | char dummy; |
| 1868 | 1895 | ||
| 1869 | emacs_close (wait_child_setup[1]); | 1896 | close_process_fd (&p->open_fd[EXEC_MONITOR_OUTPUT]); |
| 1870 | emacs_read (wait_child_setup[0], &dummy, 1); | 1897 | emacs_read (p->open_fd[READ_FROM_EXEC_MONITOR], &dummy, 1); |
| 1871 | emacs_close (wait_child_setup[0]); | 1898 | close_process_fd (&p->open_fd[READ_FROM_EXEC_MONITOR]); |
| 1872 | } | 1899 | } |
| 1873 | #endif | 1900 | #endif |
| 1874 | } | 1901 | } |
| @@ -1877,16 +1904,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1877 | static void | 1904 | static void |
| 1878 | create_pty (Lisp_Object process) | 1905 | create_pty (Lisp_Object process) |
| 1879 | { | 1906 | { |
| 1907 | struct Lisp_Process *p = XPROCESS (process); | ||
| 1880 | char pty_name[PTY_NAME_SIZE]; | 1908 | char pty_name[PTY_NAME_SIZE]; |
| 1881 | int inchannel, outchannel; | 1909 | int pty_fd = NILP (Vprocess_connection_type) ? -1 : allocate_pty (pty_name); |
| 1882 | 1910 | ||
| 1883 | inchannel = outchannel = -1; | 1911 | if (pty_fd >= 0) |
| 1884 | |||
| 1885 | if (!NILP (Vprocess_connection_type)) | ||
| 1886 | outchannel = inchannel = allocate_pty (pty_name); | ||
| 1887 | |||
| 1888 | if (inchannel >= 0) | ||
| 1889 | { | 1912 | { |
| 1913 | p->open_fd[SUBPROCESS_STDIN] = pty_fd; | ||
| 1890 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) | 1914 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) |
| 1891 | /* On most USG systems it does not work to open the pty's tty here, | 1915 | /* On most USG systems it does not work to open the pty's tty here, |
| 1892 | then close it and reopen it in the child. */ | 1916 | then close it and reopen it in the child. */ |
| @@ -1895,6 +1919,7 @@ create_pty (Lisp_Object process) | |||
| 1895 | int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); | 1919 | int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); |
| 1896 | if (forkout < 0) | 1920 | if (forkout < 0) |
| 1897 | report_file_error ("Opening pty", Qnil); | 1921 | report_file_error ("Opening pty", Qnil); |
| 1922 | p->open_fd[WRITE_TO_SUBPROCESS] = forkout; | ||
| 1898 | #if defined (DONT_REOPEN_PTY) | 1923 | #if defined (DONT_REOPEN_PTY) |
| 1899 | /* In the case that vfork is defined as fork, the parent process | 1924 | /* In the case that vfork is defined as fork, the parent process |
| 1900 | (Emacs) may send some data before the child process completes | 1925 | (Emacs) may send some data before the child process completes |
| @@ -1903,33 +1928,32 @@ create_pty (Lisp_Object process) | |||
| 1903 | #endif /* DONT_REOPEN_PTY */ | 1928 | #endif /* DONT_REOPEN_PTY */ |
| 1904 | #endif /* not USG, or USG_SUBTTY_WORKS */ | 1929 | #endif /* not USG, or USG_SUBTTY_WORKS */ |
| 1905 | 1930 | ||
| 1906 | fcntl (inchannel, F_SETFL, O_NONBLOCK); | 1931 | fcntl (pty_fd, F_SETFL, O_NONBLOCK); |
| 1907 | fcntl (outchannel, F_SETFL, O_NONBLOCK); | ||
| 1908 | 1932 | ||
| 1909 | /* Record this as an active process, with its channels. | 1933 | /* Record this as an active process, with its channels. |
| 1910 | As a result, child_setup will close Emacs's side of the pipes. */ | 1934 | As a result, child_setup will close Emacs's side of the pipes. */ |
| 1911 | chan_process[inchannel] = process; | 1935 | chan_process[pty_fd] = process; |
| 1912 | XPROCESS (process)->infd = inchannel; | 1936 | p->infd = pty_fd; |
| 1913 | XPROCESS (process)->outfd = outchannel; | 1937 | p->outfd = pty_fd; |
| 1914 | 1938 | ||
| 1915 | /* Previously we recorded the tty descriptor used in the subprocess. | 1939 | /* Previously we recorded the tty descriptor used in the subprocess. |
| 1916 | It was only used for getting the foreground tty process, so now | 1940 | It was only used for getting the foreground tty process, so now |
| 1917 | we just reopen the device (see emacs_get_tty_pgrp) as this is | 1941 | we just reopen the device (see emacs_get_tty_pgrp) as this is |
| 1918 | more portable (see USG_SUBTTY_WORKS above). */ | 1942 | more portable (see USG_SUBTTY_WORKS above). */ |
| 1919 | 1943 | ||
| 1920 | XPROCESS (process)->pty_flag = 1; | 1944 | p->pty_flag = 1; |
| 1921 | pset_status (XPROCESS (process), Qrun); | 1945 | pset_status (p, Qrun); |
| 1922 | setup_process_coding_systems (process); | 1946 | setup_process_coding_systems (process); |
| 1923 | 1947 | ||
| 1924 | FD_SET (inchannel, &input_wait_mask); | 1948 | FD_SET (pty_fd, &input_wait_mask); |
| 1925 | FD_SET (inchannel, &non_keyboard_wait_mask); | 1949 | FD_SET (pty_fd, &non_keyboard_wait_mask); |
| 1926 | if (inchannel > max_process_desc) | 1950 | if (pty_fd > max_process_desc) |
| 1927 | max_process_desc = inchannel; | 1951 | max_process_desc = pty_fd; |
| 1928 | 1952 | ||
| 1929 | pset_tty_name (XPROCESS (process), build_string (pty_name)); | 1953 | pset_tty_name (p, build_string (pty_name)); |
| 1930 | } | 1954 | } |
| 1931 | 1955 | ||
| 1932 | XPROCESS (process)->pid = -2; | 1956 | p->pid = -2; |
| 1933 | } | 1957 | } |
| 1934 | 1958 | ||
| 1935 | 1959 | ||
| @@ -2535,6 +2559,7 @@ usage: (make-serial-process &rest ARGS) */) | |||
| 2535 | p = XPROCESS (proc); | 2559 | p = XPROCESS (proc); |
| 2536 | 2560 | ||
| 2537 | fd = serial_open (port); | 2561 | fd = serial_open (port); |
| 2562 | p->open_fd[SUBPROCESS_STDIN] = fd; | ||
| 2538 | p->infd = fd; | 2563 | p->infd = fd; |
| 2539 | p->outfd = fd; | 2564 | p->outfd = fd; |
| 2540 | if (fd > max_process_desc) | 2565 | if (fd > max_process_desc) |
| @@ -3297,12 +3322,6 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3297 | } | 3322 | } |
| 3298 | #endif | 3323 | #endif |
| 3299 | 3324 | ||
| 3300 | /* Discard the unwind protect for closing S, if any. */ | ||
| 3301 | specpdl_ptr = specpdl + count1; | ||
| 3302 | |||
| 3303 | /* Unwind bind_polling_period and request_sigio. */ | ||
| 3304 | unbind_to (count, Qnil); | ||
| 3305 | |||
| 3306 | if (s < 0) | 3325 | if (s < 0) |
| 3307 | { | 3326 | { |
| 3308 | /* If non-blocking got this far - and failed - assume non-blocking is | 3327 | /* If non-blocking got this far - and failed - assume non-blocking is |
| @@ -3344,8 +3363,17 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3344 | if ((tem = Fplist_get (contact, QCstop), !NILP (tem))) | 3363 | if ((tem = Fplist_get (contact, QCstop), !NILP (tem))) |
| 3345 | pset_command (p, Qt); | 3364 | pset_command (p, Qt); |
| 3346 | p->pid = 0; | 3365 | p->pid = 0; |
| 3366 | |||
| 3367 | p->open_fd[SUBPROCESS_STDIN] = inch; | ||
| 3347 | p->infd = inch; | 3368 | p->infd = inch; |
| 3348 | p->outfd = outch; | 3369 | p->outfd = outch; |
| 3370 | |||
| 3371 | /* Discard the unwind protect for closing S, if any. */ | ||
| 3372 | specpdl_ptr = specpdl + count1; | ||
| 3373 | |||
| 3374 | /* Unwind bind_polling_period and request_sigio. */ | ||
| 3375 | unbind_to (count, Qnil); | ||
| 3376 | |||
| 3349 | if (is_server && socktype != SOCK_DGRAM) | 3377 | if (is_server && socktype != SOCK_DGRAM) |
| 3350 | pset_status (p, Qlisten); | 3378 | pset_status (p, Qlisten); |
| 3351 | 3379 | ||
| @@ -3784,17 +3812,15 @@ FLAGS is the current flags of the interface. */) | |||
| 3784 | static void | 3812 | static void |
| 3785 | deactivate_process (Lisp_Object proc) | 3813 | deactivate_process (Lisp_Object proc) |
| 3786 | { | 3814 | { |
| 3787 | register int inchannel, outchannel; | 3815 | int inchannel; |
| 3788 | register struct Lisp_Process *p = XPROCESS (proc); | 3816 | struct Lisp_Process *p = XPROCESS (proc); |
| 3817 | int i; | ||
| 3789 | 3818 | ||
| 3790 | #ifdef HAVE_GNUTLS | 3819 | #ifdef HAVE_GNUTLS |
| 3791 | /* Delete GnuTLS structures in PROC, if any. */ | 3820 | /* Delete GnuTLS structures in PROC, if any. */ |
| 3792 | emacs_gnutls_deinit (proc); | 3821 | emacs_gnutls_deinit (proc); |
| 3793 | #endif /* HAVE_GNUTLS */ | 3822 | #endif /* HAVE_GNUTLS */ |
| 3794 | 3823 | ||
| 3795 | inchannel = p->infd; | ||
| 3796 | outchannel = p->outfd; | ||
| 3797 | |||
| 3798 | #ifdef ADAPTIVE_READ_BUFFERING | 3824 | #ifdef ADAPTIVE_READ_BUFFERING |
| 3799 | if (p->read_output_delay > 0) | 3825 | if (p->read_output_delay > 0) |
| 3800 | { | 3826 | { |
| @@ -3805,16 +3831,17 @@ deactivate_process (Lisp_Object proc) | |||
| 3805 | } | 3831 | } |
| 3806 | #endif | 3832 | #endif |
| 3807 | 3833 | ||
| 3834 | inchannel = p->infd; | ||
| 3835 | |||
| 3836 | /* Beware SIGCHLD hereabouts. */ | ||
| 3837 | if (inchannel >= 0) | ||
| 3838 | flush_pending_output (inchannel); | ||
| 3839 | |||
| 3840 | for (i = 0; i < PROCESS_OPEN_FDS; i++) | ||
| 3841 | close_process_fd (&p->open_fd[i]); | ||
| 3842 | |||
| 3808 | if (inchannel >= 0) | 3843 | if (inchannel >= 0) |
| 3809 | { | 3844 | { |
| 3810 | /* Beware SIGCHLD hereabouts. */ | ||
| 3811 | flush_pending_output (inchannel); | ||
| 3812 | emacs_close (inchannel); | ||
| 3813 | if (outchannel >= 0 && outchannel != inchannel) | ||
| 3814 | emacs_close (outchannel); | ||
| 3815 | |||
| 3816 | p->infd = -1; | ||
| 3817 | p->outfd = -1; | ||
| 3818 | #ifdef DATAGRAM_SOCKETS | 3845 | #ifdef DATAGRAM_SOCKETS |
| 3819 | if (DATAGRAM_CHAN_P (inchannel)) | 3846 | if (DATAGRAM_CHAN_P (inchannel)) |
| 3820 | { | 3847 | { |
| @@ -4095,6 +4122,7 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4095 | /* Discard the unwind protect for closing S. */ | 4122 | /* Discard the unwind protect for closing S. */ |
| 4096 | specpdl_ptr = specpdl + count; | 4123 | specpdl_ptr = specpdl + count; |
| 4097 | 4124 | ||
| 4125 | p->open_fd[SUBPROCESS_STDIN] = s; | ||
| 4098 | p->infd = s; | 4126 | p->infd = s; |
| 4099 | p->outfd = s; | 4127 | p->outfd = s; |
| 4100 | pset_status (p, Qrun); | 4128 | pset_status (p, Qrun); |
| @@ -6014,7 +6042,8 @@ process has been transmitted to the serial port. */) | |||
| 6014 | } | 6042 | } |
| 6015 | else | 6043 | else |
| 6016 | { | 6044 | { |
| 6017 | int old_outfd, new_outfd; | 6045 | int old_outfd = XPROCESS (proc)->outfd; |
| 6046 | int new_outfd; | ||
| 6018 | 6047 | ||
| 6019 | #ifdef HAVE_SHUTDOWN | 6048 | #ifdef HAVE_SHUTDOWN |
| 6020 | /* If this is a network connection, or socketpair is used | 6049 | /* If this is a network connection, or socketpair is used |
| @@ -6022,18 +6051,15 @@ process has been transmitted to the serial port. */) | |||
| 6022 | (In some old system, shutdown to socketpair doesn't work. | 6051 | (In some old system, shutdown to socketpair doesn't work. |
| 6023 | Then we just can't win.) */ | 6052 | Then we just can't win.) */ |
| 6024 | if (EQ (XPROCESS (proc)->type, Qnetwork) | 6053 | if (EQ (XPROCESS (proc)->type, Qnetwork) |
| 6025 | || XPROCESS (proc)->outfd == XPROCESS (proc)->infd) | 6054 | || XPROCESS (proc)->infd == old_outfd) |
| 6026 | shutdown (XPROCESS (proc)->outfd, 1); | 6055 | shutdown (old_outfd, 1); |
| 6027 | /* In case of socketpair, outfd == infd, so don't close it. */ | 6056 | #endif |
| 6028 | if (XPROCESS (proc)->outfd != XPROCESS (proc)->infd) | 6057 | close_process_fd (&XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS]); |
| 6029 | emacs_close (XPROCESS (proc)->outfd); | ||
| 6030 | #else /* not HAVE_SHUTDOWN */ | ||
| 6031 | emacs_close (XPROCESS (proc)->outfd); | ||
| 6032 | #endif /* not HAVE_SHUTDOWN */ | ||
| 6033 | new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0); | 6058 | new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0); |
| 6034 | if (new_outfd < 0) | 6059 | if (new_outfd < 0) |
| 6035 | emacs_abort (); | 6060 | report_file_error ("Opening null device", Qnil); |
| 6036 | old_outfd = XPROCESS (proc)->outfd; | 6061 | XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS] = new_outfd; |
| 6062 | XPROCESS (proc)->outfd = new_outfd; | ||
| 6037 | 6063 | ||
| 6038 | if (!proc_encode_coding_system[new_outfd]) | 6064 | if (!proc_encode_coding_system[new_outfd]) |
| 6039 | proc_encode_coding_system[new_outfd] | 6065 | proc_encode_coding_system[new_outfd] |
| @@ -6042,8 +6068,6 @@ process has been transmitted to the serial port. */) | |||
| 6042 | = *proc_encode_coding_system[old_outfd]; | 6068 | = *proc_encode_coding_system[old_outfd]; |
| 6043 | memset (proc_encode_coding_system[old_outfd], 0, | 6069 | memset (proc_encode_coding_system[old_outfd], 0, |
| 6044 | sizeof (struct coding_system)); | 6070 | sizeof (struct coding_system)); |
| 6045 | |||
| 6046 | XPROCESS (proc)->outfd = new_outfd; | ||
| 6047 | } | 6071 | } |
| 6048 | return process; | 6072 | return process; |
| 6049 | } | 6073 | } |
| @@ -6120,7 +6144,8 @@ handle_child_signal (int sig) | |||
| 6120 | bool all_pids_are_fixnums | 6144 | bool all_pids_are_fixnums |
| 6121 | = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t) | 6145 | = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t) |
| 6122 | && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM); | 6146 | && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM); |
| 6123 | Lisp_Object xpid = XCAR (tail); | 6147 | Lisp_Object head = XCAR (tail); |
| 6148 | Lisp_Object xpid = XCAR (head); | ||
| 6124 | if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid)) | 6149 | if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid)) |
| 6125 | { | 6150 | { |
| 6126 | pid_t deleted_pid; | 6151 | pid_t deleted_pid; |
| @@ -6129,7 +6154,11 @@ handle_child_signal (int sig) | |||
| 6129 | else | 6154 | else |
| 6130 | deleted_pid = XFLOAT_DATA (xpid); | 6155 | deleted_pid = XFLOAT_DATA (xpid); |
| 6131 | if (child_status_changed (deleted_pid, 0, 0)) | 6156 | if (child_status_changed (deleted_pid, 0, 0)) |
| 6132 | XSETCAR (tail, Qnil); | 6157 | { |
| 6158 | if (STRINGP (XCDR (head))) | ||
| 6159 | unlink (SSDATA (XCDR (head))); | ||
| 6160 | XSETCAR (tail, Qnil); | ||
| 6161 | } | ||
| 6133 | } | 6162 | } |
| 6134 | } | 6163 | } |
| 6135 | 6164 | ||