diff options
| author | Tom Tromey | 2013-08-19 21:53:07 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-08-19 21:53:07 -0600 |
| commit | 6d75555c5cc3d2a629646cee7629e67530fa7a36 (patch) | |
| tree | 3852804dd234ad613ea8691332e10b92c027e87d /src/process.c | |
| parent | cc231cbe45d27a1906d268fb72d3b4105a2e9c65 (diff) | |
| parent | 8c2f38aaab7a7a2f0605416fc2ee38701e41ab61 (diff) | |
| download | emacs-6d75555c5cc3d2a629646cee7629e67530fa7a36.tar.gz emacs-6d75555c5cc3d2a629646cee7629e67530fa7a36.zip | |
merge from trunk
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 289 |
1 files changed, 168 insertions, 121 deletions
diff --git a/src/process.c b/src/process.c index 33d8ccbbc35..91483e5839f 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 | ||
| @@ -301,7 +302,7 @@ static void exec_sentinel (Lisp_Object proc, Lisp_Object reason); | |||
| 301 | static int num_pending_connects; | 302 | static int num_pending_connects; |
| 302 | #endif /* NON_BLOCKING_CONNECT */ | 303 | #endif /* NON_BLOCKING_CONNECT */ |
| 303 | 304 | ||
| 304 | /* The largest descriptor currently in use for input. */ | 305 | /* The largest descriptor currently in use; -1 if none. */ |
| 305 | static int max_desc; | 306 | static int max_desc; |
| 306 | 307 | ||
| 307 | /* Indexed by descriptor, gives the process (if any) for that descriptor */ | 308 | /* Indexed by descriptor, gives the process (if any) for that descriptor */ |
| @@ -335,6 +336,12 @@ static struct sockaddr_and_len { | |||
| 335 | #define DATAGRAM_CONN_P(proc) (0) | 336 | #define DATAGRAM_CONN_P(proc) (0) |
| 336 | #endif | 337 | #endif |
| 337 | 338 | ||
| 339 | /* FOR_EACH_PROCESS (LIST_VAR, PROC_VAR) followed by a statement is | ||
| 340 | a `for' loop which iterates over processes from Vprocess_alist. */ | ||
| 341 | |||
| 342 | #define FOR_EACH_PROCESS(list_var, proc_var) \ | ||
| 343 | FOR_EACH_ALIST_VALUE (Vprocess_alist, list_var, proc_var) | ||
| 344 | |||
| 338 | /* These setters are used only in this file, so they can be private. */ | 345 | /* These setters are used only in this file, so they can be private. */ |
| 339 | static void | 346 | static void |
| 340 | pset_buffer (struct Lisp_Process *p, Lisp_Object val) | 347 | pset_buffer (struct Lisp_Process *p, Lisp_Object val) |
| @@ -543,6 +550,22 @@ recompute_max_desc (void) | |||
| 543 | } | 550 | } |
| 544 | } | 551 | } |
| 545 | 552 | ||
| 553 | /* FD is no longer an input descriptor; update max_input_desc accordingly. */ | ||
| 554 | |||
| 555 | static void | ||
| 556 | delete_input_desc (int fd) | ||
| 557 | { | ||
| 558 | if (fd == max_input_desc) | ||
| 559 | { | ||
| 560 | do | ||
| 561 | fd--; | ||
| 562 | while (0 <= fd && ! (FD_ISSET (fd, &input_wait_mask) | ||
| 563 | || FD_ISSET (fd, &write_mask))); | ||
| 564 | |||
| 565 | max_input_desc = fd; | ||
| 566 | } | ||
| 567 | } | ||
| 568 | |||
| 546 | /* Stop monitoring file descriptor FD for when write is possible. */ | 569 | /* Stop monitoring file descriptor FD for when write is possible. */ |
| 547 | 570 | ||
| 548 | void | 571 | void |
| @@ -862,6 +885,8 @@ make_process (Lisp_Object name) | |||
| 862 | non-Lisp data, so do it only for slots which should not be zero. */ | 885 | non-Lisp data, so do it only for slots which should not be zero. */ |
| 863 | p->infd = -1; | 886 | p->infd = -1; |
| 864 | p->outfd = -1; | 887 | p->outfd = -1; |
| 888 | for (i = 0; i < PROCESS_OPEN_FDS; i++) | ||
| 889 | p->open_fd[i] = -1; | ||
| 865 | 890 | ||
| 866 | #ifdef HAVE_GNUTLS | 891 | #ifdef HAVE_GNUTLS |
| 867 | p->gnutls_initstage = GNUTLS_STAGE_EMPTY; | 892 | p->gnutls_initstage = GNUTLS_STAGE_EMPTY; |
| @@ -979,13 +1004,17 @@ get_process (register Lisp_Object name) | |||
| 979 | treated by the SIGCHLD handler and waitpid has been invoked on them; | 1004 | treated by the SIGCHLD handler and waitpid has been invoked on them; |
| 980 | otherwise they might fill up the kernel's process table. | 1005 | otherwise they might fill up the kernel's process table. |
| 981 | 1006 | ||
| 982 | Some processes created by call-process are also put onto this list. */ | 1007 | Some processes created by call-process are also put onto this list. |
| 1008 | |||
| 1009 | Members of this list are (process-ID . filename) pairs. The | ||
| 1010 | process-ID is a number; the filename, if a string, is a file that | ||
| 1011 | needs to be removed after the process exits. */ | ||
| 983 | static Lisp_Object deleted_pid_list; | 1012 | static Lisp_Object deleted_pid_list; |
| 984 | 1013 | ||
| 985 | void | 1014 | void |
| 986 | record_deleted_pid (pid_t pid) | 1015 | record_deleted_pid (pid_t pid, Lisp_Object filename) |
| 987 | { | 1016 | { |
| 988 | deleted_pid_list = Fcons (make_fixnum_or_float (pid), | 1017 | deleted_pid_list = Fcons (Fcons (make_fixnum_or_float (pid), filename), |
| 989 | /* GC treated elements set to nil. */ | 1018 | /* GC treated elements set to nil. */ |
| 990 | Fdelq (Qnil, deleted_pid_list)); | 1019 | Fdelq (Qnil, deleted_pid_list)); |
| 991 | 1020 | ||
| @@ -1013,7 +1042,7 @@ nil, indicating the current buffer's process. */) | |||
| 1013 | else | 1042 | else |
| 1014 | { | 1043 | { |
| 1015 | if (p->alive) | 1044 | if (p->alive) |
| 1016 | record_kill_process (p); | 1045 | record_kill_process (p, Qnil); |
| 1017 | 1046 | ||
| 1018 | if (p->infd >= 0) | 1047 | if (p->infd >= 0) |
| 1019 | { | 1048 | { |
| @@ -1796,17 +1825,45 @@ start_process_unwind (Lisp_Object proc) | |||
| 1796 | remove_process (proc); | 1825 | remove_process (proc); |
| 1797 | } | 1826 | } |
| 1798 | 1827 | ||
| 1828 | /* If *FD_ADDR is nonnegative, close it, and mark it as closed. */ | ||
| 1829 | |||
| 1830 | static void | ||
| 1831 | close_process_fd (int *fd_addr) | ||
| 1832 | { | ||
| 1833 | int fd = *fd_addr; | ||
| 1834 | if (0 <= fd) | ||
| 1835 | { | ||
| 1836 | *fd_addr = -1; | ||
| 1837 | emacs_close (fd); | ||
| 1838 | } | ||
| 1839 | } | ||
| 1840 | |||
| 1841 | /* Indexes of file descriptors in open_fds. */ | ||
| 1842 | enum | ||
| 1843 | { | ||
| 1844 | /* The pipe from Emacs to its subprocess. */ | ||
| 1845 | SUBPROCESS_STDIN, | ||
| 1846 | WRITE_TO_SUBPROCESS, | ||
| 1847 | |||
| 1848 | /* The main pipe from the subprocess to Emacs. */ | ||
| 1849 | READ_FROM_SUBPROCESS, | ||
| 1850 | SUBPROCESS_STDOUT, | ||
| 1851 | |||
| 1852 | /* The pipe from the subprocess to Emacs that is closed when the | ||
| 1853 | subprocess execs. */ | ||
| 1854 | READ_FROM_EXEC_MONITOR, | ||
| 1855 | EXEC_MONITOR_OUTPUT | ||
| 1856 | }; | ||
| 1857 | |||
| 1858 | verify (PROCESS_OPEN_FDS == EXEC_MONITOR_OUTPUT + 1); | ||
| 1799 | 1859 | ||
| 1800 | static void | 1860 | static void |
| 1801 | create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | 1861 | create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) |
| 1802 | { | 1862 | { |
| 1863 | struct Lisp_Process *p = XPROCESS (process); | ||
| 1803 | int inchannel, outchannel; | 1864 | int inchannel, outchannel; |
| 1804 | pid_t pid; | 1865 | pid_t pid; |
| 1805 | int vfork_errno; | 1866 | int vfork_errno; |
| 1806 | int sv[2]; | ||
| 1807 | #ifndef WINDOWSNT | ||
| 1808 | int wait_child_setup[2]; | ||
| 1809 | #endif | ||
| 1810 | int forkin, forkout; | 1867 | int forkin, forkout; |
| 1811 | bool pty_flag = 0; | 1868 | bool pty_flag = 0; |
| 1812 | char pty_name[PTY_NAME_SIZE]; | 1869 | char pty_name[PTY_NAME_SIZE]; |
| @@ -1820,6 +1877,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1820 | 1877 | ||
| 1821 | if (inchannel >= 0) | 1878 | if (inchannel >= 0) |
| 1822 | { | 1879 | { |
| 1880 | p->open_fd[READ_FROM_SUBPROCESS] = inchannel; | ||
| 1823 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) | 1881 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) |
| 1824 | /* On most USG systems it does not work to open the pty's tty here, | 1882 | /* On most USG systems it does not work to open the pty's tty here, |
| 1825 | then close it and reopen it in the child. */ | 1883 | then close it and reopen it in the child. */ |
| @@ -1828,6 +1886,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1828 | forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); | 1886 | forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); |
| 1829 | if (forkin < 0) | 1887 | if (forkin < 0) |
| 1830 | report_file_error ("Opening pty", Qnil); | 1888 | report_file_error ("Opening pty", Qnil); |
| 1889 | p->open_fd[SUBPROCESS_STDIN] = forkin; | ||
| 1831 | #else | 1890 | #else |
| 1832 | forkin = forkout = -1; | 1891 | forkin = forkout = -1; |
| 1833 | #endif /* not USG, or USG_SUBTTY_WORKS */ | 1892 | #endif /* not USG, or USG_SUBTTY_WORKS */ |
| @@ -1836,23 +1895,17 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1836 | } | 1895 | } |
| 1837 | else | 1896 | else |
| 1838 | { | 1897 | { |
| 1839 | if (emacs_pipe (sv) != 0) | 1898 | if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0 |
| 1899 | || emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0) | ||
| 1840 | report_file_error ("Creating pipe", Qnil); | 1900 | report_file_error ("Creating pipe", Qnil); |
| 1841 | inchannel = sv[0]; | 1901 | forkin = p->open_fd[SUBPROCESS_STDIN]; |
| 1842 | forkout = sv[1]; | 1902 | outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; |
| 1843 | if (emacs_pipe (sv) != 0) | 1903 | inchannel = p->open_fd[READ_FROM_SUBPROCESS]; |
| 1844 | { | 1904 | forkout = p->open_fd[SUBPROCESS_STDOUT]; |
| 1845 | int pipe_errno = errno; | ||
| 1846 | emacs_close (inchannel); | ||
| 1847 | emacs_close (forkout); | ||
| 1848 | report_file_errno ("Creating pipe", Qnil, pipe_errno); | ||
| 1849 | } | ||
| 1850 | outchannel = sv[1]; | ||
| 1851 | forkin = sv[0]; | ||
| 1852 | } | 1905 | } |
| 1853 | 1906 | ||
| 1854 | #ifndef WINDOWSNT | 1907 | #ifndef WINDOWSNT |
| 1855 | if (emacs_pipe (wait_child_setup) != 0) | 1908 | if (emacs_pipe (p->open_fd + READ_FROM_EXEC_MONITOR) != 0) |
| 1856 | report_file_error ("Creating pipe", Qnil); | 1909 | report_file_error ("Creating pipe", Qnil); |
| 1857 | #endif | 1910 | #endif |
| 1858 | 1911 | ||
| @@ -1861,16 +1914,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1861 | 1914 | ||
| 1862 | /* Record this as an active process, with its channels. */ | 1915 | /* Record this as an active process, with its channels. */ |
| 1863 | chan_process[inchannel] = process; | 1916 | chan_process[inchannel] = process; |
| 1864 | XPROCESS (process)->infd = inchannel; | 1917 | p->infd = inchannel; |
| 1865 | XPROCESS (process)->outfd = outchannel; | 1918 | p->outfd = outchannel; |
| 1866 | 1919 | ||
| 1867 | /* Previously we recorded the tty descriptor used in the subprocess. | 1920 | /* Previously we recorded the tty descriptor used in the subprocess. |
| 1868 | It was only used for getting the foreground tty process, so now | 1921 | It was only used for getting the foreground tty process, so now |
| 1869 | we just reopen the device (see emacs_get_tty_pgrp) as this is | 1922 | we just reopen the device (see emacs_get_tty_pgrp) as this is |
| 1870 | more portable (see USG_SUBTTY_WORKS above). */ | 1923 | more portable (see USG_SUBTTY_WORKS above). */ |
| 1871 | 1924 | ||
| 1872 | XPROCESS (process)->pty_flag = pty_flag; | 1925 | p->pty_flag = pty_flag; |
| 1873 | pset_status (XPROCESS (process), Qrun); | 1926 | pset_status (p, Qrun); |
| 1874 | 1927 | ||
| 1875 | add_process_read_fd (inchannel); | 1928 | add_process_read_fd (inchannel); |
| 1876 | 1929 | ||
| @@ -1887,25 +1940,21 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1887 | { | 1940 | { |
| 1888 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; | 1941 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; |
| 1889 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; | 1942 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; |
| 1890 | Lisp_Object volatile process_volatile = process; | ||
| 1891 | char **volatile new_argv_volatile = new_argv; | 1943 | char **volatile new_argv_volatile = new_argv; |
| 1892 | int volatile forkin_volatile = forkin; | 1944 | int volatile forkin_volatile = forkin; |
| 1893 | int volatile forkout_volatile = forkout; | 1945 | int volatile forkout_volatile = forkout; |
| 1894 | int volatile wait_child_setup_0_volatile = wait_child_setup[0]; | 1946 | struct Lisp_Process *p_volatile = p; |
| 1895 | int volatile wait_child_setup_1_volatile = wait_child_setup[1]; | ||
| 1896 | 1947 | ||
| 1897 | pid = vfork (); | 1948 | pid = vfork (); |
| 1898 | 1949 | ||
| 1899 | encoded_current_dir = encoded_current_dir_volatile; | 1950 | encoded_current_dir = encoded_current_dir_volatile; |
| 1900 | lisp_pty_name = lisp_pty_name_volatile; | 1951 | lisp_pty_name = lisp_pty_name_volatile; |
| 1901 | process = process_volatile; | ||
| 1902 | new_argv = new_argv_volatile; | 1952 | new_argv = new_argv_volatile; |
| 1903 | forkin = forkin_volatile; | 1953 | forkin = forkin_volatile; |
| 1904 | forkout = forkout_volatile; | 1954 | forkout = forkout_volatile; |
| 1905 | wait_child_setup[0] = wait_child_setup_0_volatile; | 1955 | p = p_volatile; |
| 1906 | wait_child_setup[1] = wait_child_setup_1_volatile; | ||
| 1907 | 1956 | ||
| 1908 | pty_flag = XPROCESS (process)->pty_flag; | 1957 | pty_flag = p->pty_flag; |
| 1909 | } | 1958 | } |
| 1910 | 1959 | ||
| 1911 | if (pid == 0) | 1960 | if (pid == 0) |
| @@ -2021,42 +2070,42 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2021 | /* Back in the parent process. */ | 2070 | /* Back in the parent process. */ |
| 2022 | 2071 | ||
| 2023 | vfork_errno = errno; | 2072 | vfork_errno = errno; |
| 2024 | XPROCESS (process)->pid = pid; | 2073 | p->pid = pid; |
| 2025 | if (pid >= 0) | 2074 | if (pid >= 0) |
| 2026 | XPROCESS (process)->alive = 1; | 2075 | p->alive = 1; |
| 2027 | 2076 | ||
| 2028 | /* Stop blocking in the parent. */ | 2077 | /* Stop blocking in the parent. */ |
| 2029 | unblock_child_signal (); | 2078 | unblock_child_signal (); |
| 2030 | unblock_input (); | 2079 | unblock_input (); |
| 2031 | 2080 | ||
| 2032 | if (forkin >= 0) | ||
| 2033 | emacs_close (forkin); | ||
| 2034 | if (forkin != forkout && forkout >= 0) | ||
| 2035 | emacs_close (forkout); | ||
| 2036 | |||
| 2037 | if (pid < 0) | 2081 | if (pid < 0) |
| 2038 | report_file_errno ("Doing vfork", Qnil, vfork_errno); | 2082 | report_file_errno ("Doing vfork", Qnil, vfork_errno); |
| 2039 | else | 2083 | else |
| 2040 | { | 2084 | { |
| 2041 | /* vfork succeeded. */ | 2085 | /* vfork succeeded. */ |
| 2042 | 2086 | ||
| 2087 | /* Close the pipe ends that the child uses, or the child's pty. */ | ||
| 2088 | close_process_fd (&p->open_fd[SUBPROCESS_STDIN]); | ||
| 2089 | close_process_fd (&p->open_fd[SUBPROCESS_STDOUT]); | ||
| 2090 | |||
| 2043 | #ifdef WINDOWSNT | 2091 | #ifdef WINDOWSNT |
| 2044 | register_child (pid, inchannel); | 2092 | register_child (pid, inchannel); |
| 2045 | #endif /* WINDOWSNT */ | 2093 | #endif /* WINDOWSNT */ |
| 2046 | 2094 | ||
| 2047 | pset_tty_name (XPROCESS (process), lisp_pty_name); | 2095 | pset_tty_name (p, lisp_pty_name); |
| 2048 | 2096 | ||
| 2049 | #ifndef WINDOWSNT | 2097 | #ifndef WINDOWSNT |
| 2050 | /* Wait for child_setup to complete in case that vfork is | 2098 | /* Wait for child_setup to complete in case that vfork is |
| 2051 | actually defined as fork. The descriptor wait_child_setup[1] | 2099 | actually defined as fork. The descriptor |
| 2100 | XPROCESS (proc)->open_fd[EXEC_MONITOR_OUTPUT] | ||
| 2052 | of a pipe is closed at the child side either by close-on-exec | 2101 | of a pipe is closed at the child side either by close-on-exec |
| 2053 | on successful execve or the _exit call in child_setup. */ | 2102 | on successful execve or the _exit call in child_setup. */ |
| 2054 | { | 2103 | { |
| 2055 | char dummy; | 2104 | char dummy; |
| 2056 | 2105 | ||
| 2057 | emacs_close (wait_child_setup[1]); | 2106 | close_process_fd (&p->open_fd[EXEC_MONITOR_OUTPUT]); |
| 2058 | emacs_read (wait_child_setup[0], &dummy, 1); | 2107 | emacs_read (p->open_fd[READ_FROM_EXEC_MONITOR], &dummy, 1); |
| 2059 | emacs_close (wait_child_setup[0]); | 2108 | close_process_fd (&p->open_fd[READ_FROM_EXEC_MONITOR]); |
| 2060 | } | 2109 | } |
| 2061 | #endif | 2110 | #endif |
| 2062 | } | 2111 | } |
| @@ -2065,16 +2114,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2065 | static void | 2114 | static void |
| 2066 | create_pty (Lisp_Object process) | 2115 | create_pty (Lisp_Object process) |
| 2067 | { | 2116 | { |
| 2117 | struct Lisp_Process *p = XPROCESS (process); | ||
| 2068 | char pty_name[PTY_NAME_SIZE]; | 2118 | char pty_name[PTY_NAME_SIZE]; |
| 2069 | int inchannel, outchannel; | 2119 | int pty_fd = NILP (Vprocess_connection_type) ? -1 : allocate_pty (pty_name); |
| 2070 | |||
| 2071 | inchannel = outchannel = -1; | ||
| 2072 | |||
| 2073 | if (!NILP (Vprocess_connection_type)) | ||
| 2074 | outchannel = inchannel = allocate_pty (pty_name); | ||
| 2075 | 2120 | ||
| 2076 | if (inchannel >= 0) | 2121 | if (pty_fd >= 0) |
| 2077 | { | 2122 | { |
| 2123 | p->open_fd[SUBPROCESS_STDIN] = pty_fd; | ||
| 2078 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) | 2124 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) |
| 2079 | /* On most USG systems it does not work to open the pty's tty here, | 2125 | /* On most USG systems it does not work to open the pty's tty here, |
| 2080 | then close it and reopen it in the child. */ | 2126 | then close it and reopen it in the child. */ |
| @@ -2083,6 +2129,7 @@ create_pty (Lisp_Object process) | |||
| 2083 | int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); | 2129 | int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); |
| 2084 | if (forkout < 0) | 2130 | if (forkout < 0) |
| 2085 | report_file_error ("Opening pty", Qnil); | 2131 | report_file_error ("Opening pty", Qnil); |
| 2132 | p->open_fd[WRITE_TO_SUBPROCESS] = forkout; | ||
| 2086 | #if defined (DONT_REOPEN_PTY) | 2133 | #if defined (DONT_REOPEN_PTY) |
| 2087 | /* In the case that vfork is defined as fork, the parent process | 2134 | /* In the case that vfork is defined as fork, the parent process |
| 2088 | (Emacs) may send some data before the child process completes | 2135 | (Emacs) may send some data before the child process completes |
| @@ -2091,28 +2138,29 @@ create_pty (Lisp_Object process) | |||
| 2091 | #endif /* DONT_REOPEN_PTY */ | 2138 | #endif /* DONT_REOPEN_PTY */ |
| 2092 | #endif /* not USG, or USG_SUBTTY_WORKS */ | 2139 | #endif /* not USG, or USG_SUBTTY_WORKS */ |
| 2093 | 2140 | ||
| 2094 | fcntl (inchannel, F_SETFL, O_NONBLOCK); | 2141 | fcntl (pty_fd, F_SETFL, O_NONBLOCK); |
| 2095 | fcntl (outchannel, F_SETFL, O_NONBLOCK); | ||
| 2096 | 2142 | ||
| 2097 | /* Record this as an active process, with its channels. | 2143 | /* Record this as an active process, with its channels. |
| 2098 | As a result, child_setup will close Emacs's side of the pipes. */ | 2144 | As a result, child_setup will close Emacs's side of the pipes. */ |
| 2099 | chan_process[inchannel] = process; | 2145 | chan_process[pty_fd] = process; |
| 2100 | XPROCESS (process)->infd = inchannel; | 2146 | p->infd = pty_fd; |
| 2101 | XPROCESS (process)->outfd = outchannel; | 2147 | p->outfd = pty_fd; |
| 2102 | 2148 | ||
| 2103 | /* Previously we recorded the tty descriptor used in the subprocess. | 2149 | /* Previously we recorded the tty descriptor used in the subprocess. |
| 2104 | It was only used for getting the foreground tty process, so now | 2150 | It was only used for getting the foreground tty process, so now |
| 2105 | we just reopen the device (see emacs_get_tty_pgrp) as this is | 2151 | we just reopen the device (see emacs_get_tty_pgrp) as this is |
| 2106 | more portable (see USG_SUBTTY_WORKS above). */ | 2152 | more portable (see USG_SUBTTY_WORKS above). */ |
| 2107 | 2153 | ||
| 2108 | XPROCESS (process)->pty_flag = 1; | 2154 | p->pty_flag = 1; |
| 2109 | pset_status (XPROCESS (process), Qrun); | 2155 | pset_status (p, Qrun); |
| 2110 | setup_process_coding_systems (process); | 2156 | setup_process_coding_systems (process); |
| 2111 | 2157 | ||
| 2112 | pset_tty_name (XPROCESS (process), build_string (pty_name)); | 2158 | fixme; |
| 2159 | |||
| 2160 | pset_tty_name (p, build_string (pty_name)); | ||
| 2113 | } | 2161 | } |
| 2114 | 2162 | ||
| 2115 | XPROCESS (process)->pid = -2; | 2163 | p->pid = -2; |
| 2116 | } | 2164 | } |
| 2117 | 2165 | ||
| 2118 | 2166 | ||
| @@ -2718,6 +2766,7 @@ usage: (make-serial-process &rest ARGS) */) | |||
| 2718 | p = XPROCESS (proc); | 2766 | p = XPROCESS (proc); |
| 2719 | 2767 | ||
| 2720 | fd = serial_open (port); | 2768 | fd = serial_open (port); |
| 2769 | p->open_fd[SUBPROCESS_STDIN] = fd; | ||
| 2721 | p->infd = fd; | 2770 | p->infd = fd; |
| 2722 | p->outfd = fd; | 2771 | p->outfd = fd; |
| 2723 | if (fd > max_desc) | 2772 | if (fd > max_desc) |
| @@ -3477,12 +3526,6 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3477 | } | 3526 | } |
| 3478 | #endif | 3527 | #endif |
| 3479 | 3528 | ||
| 3480 | /* Discard the unwind protect for closing S, if any. */ | ||
| 3481 | specpdl_ptr = specpdl + count1; | ||
| 3482 | |||
| 3483 | /* Unwind bind_polling_period and request_sigio. */ | ||
| 3484 | unbind_to (count, Qnil); | ||
| 3485 | |||
| 3486 | if (s < 0) | 3529 | if (s < 0) |
| 3487 | { | 3530 | { |
| 3488 | /* If non-blocking got this far - and failed - assume non-blocking is | 3531 | /* If non-blocking got this far - and failed - assume non-blocking is |
| @@ -3524,8 +3567,17 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3524 | if ((tem = Fplist_get (contact, QCstop), !NILP (tem))) | 3567 | if ((tem = Fplist_get (contact, QCstop), !NILP (tem))) |
| 3525 | pset_command (p, Qt); | 3568 | pset_command (p, Qt); |
| 3526 | p->pid = 0; | 3569 | p->pid = 0; |
| 3570 | |||
| 3571 | p->open_fd[SUBPROCESS_STDIN] = inch; | ||
| 3527 | p->infd = inch; | 3572 | p->infd = inch; |
| 3528 | p->outfd = outch; | 3573 | p->outfd = outch; |
| 3574 | |||
| 3575 | /* Discard the unwind protect for closing S, if any. */ | ||
| 3576 | specpdl_ptr = specpdl + count1; | ||
| 3577 | |||
| 3578 | /* Unwind bind_polling_period and request_sigio. */ | ||
| 3579 | unbind_to (count, Qnil); | ||
| 3580 | |||
| 3529 | if (is_server && socktype != SOCK_DGRAM) | 3581 | if (is_server && socktype != SOCK_DGRAM) |
| 3530 | pset_status (p, Qlisten); | 3582 | pset_status (p, Qlisten); |
| 3531 | 3583 | ||
| @@ -3957,17 +4009,15 @@ FLAGS is the current flags of the interface. */) | |||
| 3957 | static void | 4009 | static void |
| 3958 | deactivate_process (Lisp_Object proc) | 4010 | deactivate_process (Lisp_Object proc) |
| 3959 | { | 4011 | { |
| 3960 | register int inchannel, outchannel; | 4012 | int inchannel; |
| 3961 | register struct Lisp_Process *p = XPROCESS (proc); | 4013 | struct Lisp_Process *p = XPROCESS (proc); |
| 4014 | int i; | ||
| 3962 | 4015 | ||
| 3963 | #ifdef HAVE_GNUTLS | 4016 | #ifdef HAVE_GNUTLS |
| 3964 | /* Delete GnuTLS structures in PROC, if any. */ | 4017 | /* Delete GnuTLS structures in PROC, if any. */ |
| 3965 | emacs_gnutls_deinit (proc); | 4018 | emacs_gnutls_deinit (proc); |
| 3966 | #endif /* HAVE_GNUTLS */ | 4019 | #endif /* HAVE_GNUTLS */ |
| 3967 | 4020 | ||
| 3968 | inchannel = p->infd; | ||
| 3969 | outchannel = p->outfd; | ||
| 3970 | |||
| 3971 | #ifdef ADAPTIVE_READ_BUFFERING | 4021 | #ifdef ADAPTIVE_READ_BUFFERING |
| 3972 | if (p->read_output_delay > 0) | 4022 | if (p->read_output_delay > 0) |
| 3973 | { | 4023 | { |
| @@ -3978,14 +4028,17 @@ deactivate_process (Lisp_Object proc) | |||
| 3978 | } | 4028 | } |
| 3979 | #endif | 4029 | #endif |
| 3980 | 4030 | ||
| 4031 | inchannel = p->infd; | ||
| 4032 | |||
| 4033 | /* Beware SIGCHLD hereabouts. */ | ||
| 3981 | if (inchannel >= 0) | 4034 | if (inchannel >= 0) |
| 3982 | { | 4035 | flush_pending_output (inchannel); |
| 3983 | /* Beware SIGCHLD hereabouts. */ | ||
| 3984 | flush_pending_output (inchannel); | ||
| 3985 | emacs_close (inchannel); | ||
| 3986 | if (outchannel >= 0 && outchannel != inchannel) | ||
| 3987 | emacs_close (outchannel); | ||
| 3988 | 4036 | ||
| 4037 | for (i = 0; i < PROCESS_OPEN_FDS; i++) | ||
| 4038 | close_process_fd (&p->open_fd[i]); | ||
| 4039 | |||
| 4040 | if (inchannel >= 0) | ||
| 4041 | { | ||
| 3989 | p->infd = -1; | 4042 | p->infd = -1; |
| 3990 | p->outfd = -1; | 4043 | p->outfd = -1; |
| 3991 | #ifdef DATAGRAM_SOCKETS | 4044 | #ifdef DATAGRAM_SOCKETS |
| @@ -4263,6 +4316,7 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4263 | /* Discard the unwind protect for closing S. */ | 4316 | /* Discard the unwind protect for closing S. */ |
| 4264 | specpdl_ptr = specpdl + count; | 4317 | specpdl_ptr = specpdl + count; |
| 4265 | 4318 | ||
| 4319 | p->open_fd[SUBPROCESS_STDIN] = s; | ||
| 4266 | p->infd = s; | 4320 | p->infd = s; |
| 4267 | p->outfd = s; | 4321 | p->outfd = s; |
| 4268 | pset_status (p, Qrun); | 4322 | pset_status (p, Qrun); |
| @@ -4682,7 +4736,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4682 | #endif | 4736 | #endif |
| 4683 | , max_desc + 1, | 4737 | , max_desc + 1, |
| 4684 | &Available, | 4738 | &Available, |
| 4685 | (check_write ? &Writeok : (SELECT_TYPE *)0), | 4739 | (check_write ? &Writeok : 0), |
| 4686 | NULL, &timeout, NULL); | 4740 | NULL, &timeout, NULL); |
| 4687 | 4741 | ||
| 4688 | #ifdef HAVE_GNUTLS | 4742 | #ifdef HAVE_GNUTLS |
| @@ -6160,7 +6214,8 @@ process has been transmitted to the serial port. */) | |||
| 6160 | } | 6214 | } |
| 6161 | else | 6215 | else |
| 6162 | { | 6216 | { |
| 6163 | int old_outfd, new_outfd; | 6217 | int old_outfd = XPROCESS (proc)->outfd; |
| 6218 | int new_outfd; | ||
| 6164 | 6219 | ||
| 6165 | #ifdef HAVE_SHUTDOWN | 6220 | #ifdef HAVE_SHUTDOWN |
| 6166 | /* If this is a network connection, or socketpair is used | 6221 | /* If this is a network connection, or socketpair is used |
| @@ -6168,18 +6223,15 @@ process has been transmitted to the serial port. */) | |||
| 6168 | (In some old system, shutdown to socketpair doesn't work. | 6223 | (In some old system, shutdown to socketpair doesn't work. |
| 6169 | Then we just can't win.) */ | 6224 | Then we just can't win.) */ |
| 6170 | if (EQ (XPROCESS (proc)->type, Qnetwork) | 6225 | if (EQ (XPROCESS (proc)->type, Qnetwork) |
| 6171 | || XPROCESS (proc)->outfd == XPROCESS (proc)->infd) | 6226 | || XPROCESS (proc)->infd == old_outfd) |
| 6172 | shutdown (XPROCESS (proc)->outfd, 1); | 6227 | shutdown (old_outfd, 1); |
| 6173 | /* In case of socketpair, outfd == infd, so don't close it. */ | 6228 | #endif |
| 6174 | if (XPROCESS (proc)->outfd != XPROCESS (proc)->infd) | 6229 | close_process_fd (&XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS]); |
| 6175 | emacs_close (XPROCESS (proc)->outfd); | ||
| 6176 | #else /* not HAVE_SHUTDOWN */ | ||
| 6177 | emacs_close (XPROCESS (proc)->outfd); | ||
| 6178 | #endif /* not HAVE_SHUTDOWN */ | ||
| 6179 | new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0); | 6230 | new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0); |
| 6180 | if (new_outfd < 0) | 6231 | if (new_outfd < 0) |
| 6181 | emacs_abort (); | 6232 | report_file_error ("Opening null device", Qnil); |
| 6182 | old_outfd = XPROCESS (proc)->outfd; | 6233 | XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS] = new_outfd; |
| 6234 | XPROCESS (proc)->outfd = new_outfd; | ||
| 6183 | 6235 | ||
| 6184 | if (!proc_encode_coding_system[new_outfd]) | 6236 | if (!proc_encode_coding_system[new_outfd]) |
| 6185 | proc_encode_coding_system[new_outfd] | 6237 | proc_encode_coding_system[new_outfd] |
| @@ -6188,8 +6240,6 @@ process has been transmitted to the serial port. */) | |||
| 6188 | = *proc_encode_coding_system[old_outfd]; | 6240 | = *proc_encode_coding_system[old_outfd]; |
| 6189 | memset (proc_encode_coding_system[old_outfd], 0, | 6241 | memset (proc_encode_coding_system[old_outfd], 0, |
| 6190 | sizeof (struct coding_system)); | 6242 | sizeof (struct coding_system)); |
| 6191 | |||
| 6192 | XPROCESS (proc)->outfd = new_outfd; | ||
| 6193 | } | 6243 | } |
| 6194 | return process; | 6244 | return process; |
| 6195 | } | 6245 | } |
| @@ -6255,7 +6305,7 @@ static signal_handler_t volatile lib_child_handler; | |||
| 6255 | static void | 6305 | static void |
| 6256 | handle_child_signal (int sig) | 6306 | handle_child_signal (int sig) |
| 6257 | { | 6307 | { |
| 6258 | Lisp_Object tail; | 6308 | Lisp_Object tail, proc; |
| 6259 | 6309 | ||
| 6260 | /* Find the process that signaled us, and record its status. */ | 6310 | /* Find the process that signaled us, and record its status. */ |
| 6261 | 6311 | ||
| @@ -6266,7 +6316,11 @@ handle_child_signal (int sig) | |||
| 6266 | bool all_pids_are_fixnums | 6316 | bool all_pids_are_fixnums |
| 6267 | = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t) | 6317 | = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t) |
| 6268 | && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM); | 6318 | && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM); |
| 6269 | Lisp_Object xpid = XCAR (tail); | 6319 | Lisp_Object head = XCAR (tail); |
| 6320 | Lisp_Object xpid; | ||
| 6321 | if (! CONSP (head)) | ||
| 6322 | continue; | ||
| 6323 | xpid = XCAR (head); | ||
| 6270 | if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid)) | 6324 | if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid)) |
| 6271 | { | 6325 | { |
| 6272 | pid_t deleted_pid; | 6326 | pid_t deleted_pid; |
| @@ -6275,14 +6329,17 @@ handle_child_signal (int sig) | |||
| 6275 | else | 6329 | else |
| 6276 | deleted_pid = XFLOAT_DATA (xpid); | 6330 | deleted_pid = XFLOAT_DATA (xpid); |
| 6277 | if (child_status_changed (deleted_pid, 0, 0)) | 6331 | if (child_status_changed (deleted_pid, 0, 0)) |
| 6278 | XSETCAR (tail, Qnil); | 6332 | { |
| 6333 | if (STRINGP (XCDR (head))) | ||
| 6334 | unlink (SSDATA (XCDR (head))); | ||
| 6335 | XSETCAR (tail, Qnil); | ||
| 6336 | } | ||
| 6279 | } | 6337 | } |
| 6280 | } | 6338 | } |
| 6281 | 6339 | ||
| 6282 | /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ | 6340 | /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ |
| 6283 | for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) | 6341 | FOR_EACH_PROCESS (tail, proc) |
| 6284 | { | 6342 | { |
| 6285 | Lisp_Object proc = XCDR (XCAR (tail)); | ||
| 6286 | struct Lisp_Process *p = XPROCESS (proc); | 6343 | struct Lisp_Process *p = XPROCESS (proc); |
| 6287 | int status; | 6344 | int status; |
| 6288 | 6345 | ||
| @@ -6434,13 +6491,10 @@ status_notify (struct Lisp_Process *deleting_process) | |||
| 6434 | that we run, we get called again to handle their status changes. */ | 6491 | that we run, we get called again to handle their status changes. */ |
| 6435 | update_tick = process_tick; | 6492 | update_tick = process_tick; |
| 6436 | 6493 | ||
| 6437 | for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) | 6494 | FOR_EACH_PROCESS (tail, proc) |
| 6438 | { | 6495 | { |
| 6439 | Lisp_Object symbol; | 6496 | Lisp_Object symbol; |
| 6440 | register struct Lisp_Process *p; | 6497 | register struct Lisp_Process *p = XPROCESS (proc); |
| 6441 | |||
| 6442 | proc = Fcdr (XCAR (tail)); | ||
| 6443 | p = XPROCESS (proc); | ||
| 6444 | 6498 | ||
| 6445 | if (p->tick != p->update_tick) | 6499 | if (p->tick != p->update_tick) |
| 6446 | { | 6500 | { |
| @@ -6970,12 +7024,9 @@ BUFFER may be a buffer or the name of one. */) | |||
| 6970 | buf = Fget_buffer (buffer); | 7024 | buf = Fget_buffer (buffer); |
| 6971 | if (NILP (buf)) return Qnil; | 7025 | if (NILP (buf)) return Qnil; |
| 6972 | 7026 | ||
| 6973 | for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) | 7027 | FOR_EACH_PROCESS (tail, proc) |
| 6974 | { | 7028 | if (EQ (XPROCESS (proc)->buffer, buf)) |
| 6975 | proc = Fcdr (XCAR (tail)); | 7029 | return proc; |
| 6976 | if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf)) | ||
| 6977 | return proc; | ||
| 6978 | } | ||
| 6979 | #endif /* subprocesses */ | 7030 | #endif /* subprocesses */ |
| 6980 | return Qnil; | 7031 | return Qnil; |
| 6981 | } | 7032 | } |
| @@ -7008,18 +7059,14 @@ kill_buffer_processes (Lisp_Object buffer) | |||
| 7008 | #ifdef subprocesses | 7059 | #ifdef subprocesses |
| 7009 | Lisp_Object tail, proc; | 7060 | Lisp_Object tail, proc; |
| 7010 | 7061 | ||
| 7011 | for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) | 7062 | FOR_EACH_PROCESS (tail, proc) |
| 7012 | { | 7063 | if (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)) |
| 7013 | proc = XCDR (XCAR (tail)); | 7064 | { |
| 7014 | if (PROCESSP (proc) | 7065 | if (NETCONN_P (proc) || SERIALCONN_P (proc)) |
| 7015 | && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer))) | 7066 | Fdelete_process (proc); |
| 7016 | { | 7067 | else if (XPROCESS (proc)->infd >= 0) |
| 7017 | if (NETCONN_P (proc) || SERIALCONN_P (proc)) | 7068 | process_send_signal (proc, SIGHUP, Qnil, 1); |
| 7018 | Fdelete_process (proc); | 7069 | } |
| 7019 | else if (XPROCESS (proc)->infd >= 0) | ||
| 7020 | process_send_signal (proc, SIGHUP, Qnil, 1); | ||
| 7021 | } | ||
| 7022 | } | ||
| 7023 | #else /* subprocesses */ | 7070 | #else /* subprocesses */ |
| 7024 | /* Since we have no subprocesses, this does nothing. */ | 7071 | /* Since we have no subprocesses, this does nothing. */ |
| 7025 | #endif /* subprocesses */ | 7072 | #endif /* subprocesses */ |
| @@ -7183,7 +7230,7 @@ init_process_emacs (void) | |||
| 7183 | catch_child_signal (); | 7230 | catch_child_signal (); |
| 7184 | } | 7231 | } |
| 7185 | 7232 | ||
| 7186 | max_desc = 0; | 7233 | max_desc = -1; |
| 7187 | memset (fd_callback_info, 0, sizeof (fd_callback_info)); | 7234 | memset (fd_callback_info, 0, sizeof (fd_callback_info)); |
| 7188 | 7235 | ||
| 7189 | #ifdef NON_BLOCKING_CONNECT | 7236 | #ifdef NON_BLOCKING_CONNECT |