diff options
| author | Tom Tromey | 2013-07-26 14:02:53 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-07-26 14:02:53 -0600 |
| commit | cc231cbe45d27a1906d268fb72d3b4105a2e9c65 (patch) | |
| tree | c011828e2a3a18e77eaa8849e3cccb805d798f42 /src/process.c | |
| parent | b34a529f177a6ea32da5cb1254f91bf9d71838db (diff) | |
| parent | fec9206062b420aca84f53d05a72c3ee43244022 (diff) | |
| download | emacs-cc231cbe45d27a1906d268fb72d3b4105a2e9c65.tar.gz emacs-cc231cbe45d27a1906d268fb72d3b4105a2e9c65.zip | |
merge from trunk
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 233 |
1 files changed, 95 insertions, 138 deletions
diff --git a/src/process.c b/src/process.c index dc37bfe7067..33d8ccbbc35 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -785,19 +785,16 @@ status_message (struct Lisp_Process *p) | |||
| 785 | return Fcopy_sequence (Fsymbol_name (symbol)); | 785 | return Fcopy_sequence (Fsymbol_name (symbol)); |
| 786 | } | 786 | } |
| 787 | 787 | ||
| 788 | #ifdef HAVE_PTYS | 788 | enum { PTY_NAME_SIZE = 24 }; |
| 789 | |||
| 790 | /* The file name of the pty opened by allocate_pty. */ | ||
| 791 | static char pty_name[24]; | ||
| 792 | 789 | ||
| 793 | /* Open an available pty, returning a file descriptor. | 790 | /* Open an available pty, returning a file descriptor. |
| 794 | Return -1 on failure. | 791 | Store into PTY_NAME the file name of the terminal corresponding to the pty. |
| 795 | The file name of the terminal corresponding to the pty | 792 | Return -1 on failure. */ |
| 796 | is left in the variable pty_name. */ | ||
| 797 | 793 | ||
| 798 | static int | 794 | static int |
| 799 | allocate_pty (void) | 795 | allocate_pty (char pty_name[PTY_NAME_SIZE]) |
| 800 | { | 796 | { |
| 797 | #ifdef HAVE_PTYS | ||
| 801 | int fd; | 798 | int fd; |
| 802 | 799 | ||
| 803 | #ifdef PTY_ITERATION | 800 | #ifdef PTY_ITERATION |
| @@ -842,9 +839,9 @@ allocate_pty (void) | |||
| 842 | return fd; | 839 | return fd; |
| 843 | } | 840 | } |
| 844 | } | 841 | } |
| 842 | #endif /* HAVE_PTYS */ | ||
| 845 | return -1; | 843 | return -1; |
| 846 | } | 844 | } |
| 847 | #endif /* HAVE_PTYS */ | ||
| 848 | 845 | ||
| 849 | static Lisp_Object | 846 | static Lisp_Object |
| 850 | make_process (Lisp_Object name) | 847 | make_process (Lisp_Object name) |
| @@ -1008,7 +1005,7 @@ nil, indicating the current buffer's process. */) | |||
| 1008 | p->raw_status_new = 0; | 1005 | p->raw_status_new = 0; |
| 1009 | if (NETCONN1_P (p) || SERIALCONN1_P (p)) | 1006 | if (NETCONN1_P (p) || SERIALCONN1_P (p)) |
| 1010 | { | 1007 | { |
| 1011 | pset_status (p, Fcons (Qexit, Fcons (make_number (0), Qnil))); | 1008 | pset_status (p, list2 (Qexit, make_number (0))); |
| 1012 | p->tick = ++process_tick; | 1009 | p->tick = ++process_tick; |
| 1013 | status_notify (p); | 1010 | status_notify (p); |
| 1014 | redisplay_preserve_echo_area (13); | 1011 | redisplay_preserve_echo_area (13); |
| @@ -1403,11 +1400,11 @@ list of keywords. */) | |||
| 1403 | if ((!NETCONN_P (process) && !SERIALCONN_P (process)) || EQ (key, Qt)) | 1400 | if ((!NETCONN_P (process) && !SERIALCONN_P (process)) || EQ (key, Qt)) |
| 1404 | return contact; | 1401 | return contact; |
| 1405 | if (NILP (key) && NETCONN_P (process)) | 1402 | if (NILP (key) && NETCONN_P (process)) |
| 1406 | return Fcons (Fplist_get (contact, QChost), | 1403 | return list2 (Fplist_get (contact, QChost), |
| 1407 | Fcons (Fplist_get (contact, QCservice), Qnil)); | 1404 | Fplist_get (contact, QCservice)); |
| 1408 | if (NILP (key) && SERIALCONN_P (process)) | 1405 | if (NILP (key) && SERIALCONN_P (process)) |
| 1409 | return Fcons (Fplist_get (contact, QCport), | 1406 | return list2 (Fplist_get (contact, QCport), |
| 1410 | Fcons (Fplist_get (contact, QCspeed), Qnil)); | 1407 | Fplist_get (contact, QCspeed)); |
| 1411 | return Fplist_get (contact, key); | 1408 | return Fplist_get (contact, key); |
| 1412 | } | 1409 | } |
| 1413 | 1410 | ||
| @@ -1530,7 +1527,7 @@ Returns nil if format of ADDRESS is invalid. */) | |||
| 1530 | } | 1527 | } |
| 1531 | 1528 | ||
| 1532 | DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0, | 1529 | DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0, |
| 1533 | doc: /* Return a list of all processes. */) | 1530 | doc: /* Return a list of all processes that are Emacs sub-processes. */) |
| 1534 | (void) | 1531 | (void) |
| 1535 | { | 1532 | { |
| 1536 | return Fmapcar (Qcdr, Vprocess_alist); | 1533 | return Fmapcar (Qcdr, Vprocess_alist); |
| @@ -1538,7 +1535,7 @@ DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0, | |||
| 1538 | 1535 | ||
| 1539 | /* Starting asynchronous inferior processes. */ | 1536 | /* Starting asynchronous inferior processes. */ |
| 1540 | 1537 | ||
| 1541 | static Lisp_Object start_process_unwind (Lisp_Object proc); | 1538 | static void start_process_unwind (Lisp_Object proc); |
| 1542 | 1539 | ||
| 1543 | DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, | 1540 | DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, |
| 1544 | doc: /* Start a program in a subprocess. Return the process object for it. | 1541 | doc: /* Start a program in a subprocess. Return the process object for it. |
| @@ -1594,7 +1591,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1594 | current_dir = expand_and_dir_to_file (current_dir, Qnil); | 1591 | current_dir = expand_and_dir_to_file (current_dir, Qnil); |
| 1595 | if (NILP (Ffile_accessible_directory_p (current_dir))) | 1592 | if (NILP (Ffile_accessible_directory_p (current_dir))) |
| 1596 | report_file_error ("Setting current directory", | 1593 | report_file_error ("Setting current directory", |
| 1597 | Fcons (BVAR (current_buffer, directory), Qnil)); | 1594 | BVAR (current_buffer, directory)); |
| 1598 | 1595 | ||
| 1599 | UNGCPRO; | 1596 | UNGCPRO; |
| 1600 | } | 1597 | } |
| @@ -1716,7 +1713,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1716 | openp (Vexec_path, program, Vexec_suffixes, &tem, make_number (X_OK)); | 1713 | openp (Vexec_path, program, Vexec_suffixes, &tem, make_number (X_OK)); |
| 1717 | UNGCPRO; | 1714 | UNGCPRO; |
| 1718 | if (NILP (tem)) | 1715 | if (NILP (tem)) |
| 1719 | report_file_error ("Searching for program", Fcons (program, Qnil)); | 1716 | report_file_error ("Searching for program", program); |
| 1720 | tem = Fexpand_file_name (tem, Qnil); | 1717 | tem = Fexpand_file_name (tem, Qnil); |
| 1721 | } | 1718 | } |
| 1722 | else | 1719 | else |
| @@ -1739,7 +1736,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1739 | 1736 | ||
| 1740 | /* Encode the file name and put it in NEW_ARGV. | 1737 | /* Encode the file name and put it in NEW_ARGV. |
| 1741 | That's where the child will use it to execute the program. */ | 1738 | That's where the child will use it to execute the program. */ |
| 1742 | tem = Fcons (ENCODE_FILE (tem), Qnil); | 1739 | tem = list1 (ENCODE_FILE (tem)); |
| 1743 | 1740 | ||
| 1744 | /* Here we encode arguments by the coding system used for sending | 1741 | /* Here we encode arguments by the coding system used for sending |
| 1745 | data to the process. We don't support using different coding | 1742 | data to the process. We don't support using different coding |
| @@ -1787,7 +1784,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1787 | PROC doesn't have its pid set, then we know someone has signaled | 1784 | PROC doesn't have its pid set, then we know someone has signaled |
| 1788 | an error and the process wasn't started successfully, so we should | 1785 | an error and the process wasn't started successfully, so we should |
| 1789 | remove it from the process list. */ | 1786 | remove it from the process list. */ |
| 1790 | static Lisp_Object | 1787 | static void |
| 1791 | start_process_unwind (Lisp_Object proc) | 1788 | start_process_unwind (Lisp_Object proc) |
| 1792 | { | 1789 | { |
| 1793 | if (!PROCESSP (proc)) | 1790 | if (!PROCESSP (proc)) |
| @@ -1797,14 +1794,6 @@ start_process_unwind (Lisp_Object proc) | |||
| 1797 | -2 is used for a pty with no process, eg for gdb. */ | 1794 | -2 is used for a pty with no process, eg for gdb. */ |
| 1798 | if (XPROCESS (proc)->pid <= 0 && XPROCESS (proc)->pid != -2) | 1795 | if (XPROCESS (proc)->pid <= 0 && XPROCESS (proc)->pid != -2) |
| 1799 | remove_process (proc); | 1796 | remove_process (proc); |
| 1800 | |||
| 1801 | return Qnil; | ||
| 1802 | } | ||
| 1803 | |||
| 1804 | static void | ||
| 1805 | create_process_1 (struct atimer *timer) | ||
| 1806 | { | ||
| 1807 | /* Nothing to do. */ | ||
| 1808 | } | 1797 | } |
| 1809 | 1798 | ||
| 1810 | 1799 | ||
| @@ -1820,14 +1809,14 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1820 | #endif | 1809 | #endif |
| 1821 | int forkin, forkout; | 1810 | int forkin, forkout; |
| 1822 | bool pty_flag = 0; | 1811 | bool pty_flag = 0; |
| 1812 | char pty_name[PTY_NAME_SIZE]; | ||
| 1823 | Lisp_Object lisp_pty_name = Qnil; | 1813 | Lisp_Object lisp_pty_name = Qnil; |
| 1824 | Lisp_Object encoded_current_dir; | 1814 | Lisp_Object encoded_current_dir; |
| 1825 | 1815 | ||
| 1826 | inchannel = outchannel = -1; | 1816 | inchannel = outchannel = -1; |
| 1827 | 1817 | ||
| 1828 | #ifdef HAVE_PTYS | ||
| 1829 | if (!NILP (Vprocess_connection_type)) | 1818 | if (!NILP (Vprocess_connection_type)) |
| 1830 | outchannel = inchannel = allocate_pty (); | 1819 | outchannel = inchannel = allocate_pty (pty_name); |
| 1831 | 1820 | ||
| 1832 | if (inchannel >= 0) | 1821 | if (inchannel >= 0) |
| 1833 | { | 1822 | { |
| @@ -1846,13 +1835,12 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1846 | lisp_pty_name = build_string (pty_name); | 1835 | lisp_pty_name = build_string (pty_name); |
| 1847 | } | 1836 | } |
| 1848 | else | 1837 | else |
| 1849 | #endif /* HAVE_PTYS */ | ||
| 1850 | { | 1838 | { |
| 1851 | if (pipe2 (sv, O_CLOEXEC) != 0) | 1839 | if (emacs_pipe (sv) != 0) |
| 1852 | report_file_error ("Creating pipe", Qnil); | 1840 | report_file_error ("Creating pipe", Qnil); |
| 1853 | inchannel = sv[0]; | 1841 | inchannel = sv[0]; |
| 1854 | forkout = sv[1]; | 1842 | forkout = sv[1]; |
| 1855 | if (pipe2 (sv, O_CLOEXEC) != 0) | 1843 | if (emacs_pipe (sv) != 0) |
| 1856 | { | 1844 | { |
| 1857 | int pipe_errno = errno; | 1845 | int pipe_errno = errno; |
| 1858 | emacs_close (inchannel); | 1846 | emacs_close (inchannel); |
| @@ -1864,7 +1852,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1864 | } | 1852 | } |
| 1865 | 1853 | ||
| 1866 | #ifndef WINDOWSNT | 1854 | #ifndef WINDOWSNT |
| 1867 | if (pipe2 (wait_child_setup, O_CLOEXEC) != 0) | 1855 | if (emacs_pipe (wait_child_setup) != 0) |
| 1868 | report_file_error ("Creating pipe", Qnil); | 1856 | report_file_error ("Creating pipe", Qnil); |
| 1869 | #endif | 1857 | #endif |
| 1870 | 1858 | ||
| @@ -1900,7 +1888,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1900 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; | 1888 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; |
| 1901 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; | 1889 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; |
| 1902 | Lisp_Object volatile process_volatile = process; | 1890 | Lisp_Object volatile process_volatile = process; |
| 1903 | bool volatile pty_flag_volatile = pty_flag; | ||
| 1904 | char **volatile new_argv_volatile = new_argv; | 1891 | char **volatile new_argv_volatile = new_argv; |
| 1905 | int volatile forkin_volatile = forkin; | 1892 | int volatile forkin_volatile = forkin; |
| 1906 | int volatile forkout_volatile = forkout; | 1893 | int volatile forkout_volatile = forkout; |
| @@ -1912,12 +1899,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1912 | encoded_current_dir = encoded_current_dir_volatile; | 1899 | encoded_current_dir = encoded_current_dir_volatile; |
| 1913 | lisp_pty_name = lisp_pty_name_volatile; | 1900 | lisp_pty_name = lisp_pty_name_volatile; |
| 1914 | process = process_volatile; | 1901 | process = process_volatile; |
| 1915 | pty_flag = pty_flag_volatile; | ||
| 1916 | new_argv = new_argv_volatile; | 1902 | new_argv = new_argv_volatile; |
| 1917 | forkin = forkin_volatile; | 1903 | forkin = forkin_volatile; |
| 1918 | forkout = forkout_volatile; | 1904 | forkout = forkout_volatile; |
| 1919 | wait_child_setup[0] = wait_child_setup_0_volatile; | 1905 | wait_child_setup[0] = wait_child_setup_0_volatile; |
| 1920 | wait_child_setup[1] = wait_child_setup_1_volatile; | 1906 | wait_child_setup[1] = wait_child_setup_1_volatile; |
| 1907 | |||
| 1908 | pty_flag = XPROCESS (process)->pty_flag; | ||
| 1921 | } | 1909 | } |
| 1922 | 1910 | ||
| 1923 | if (pid == 0) | 1911 | if (pid == 0) |
| @@ -1987,15 +1975,15 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1987 | if (pty_flag) | 1975 | if (pty_flag) |
| 1988 | { | 1976 | { |
| 1989 | 1977 | ||
| 1990 | /* I wonder if emacs_close (emacs_open (pty_name, ...)) | 1978 | /* I wonder if emacs_close (emacs_open (SSDATA (lisp_pty_name), ...)) |
| 1991 | would work? */ | 1979 | would work? */ |
| 1992 | if (xforkin >= 0) | 1980 | if (xforkin >= 0) |
| 1993 | emacs_close (xforkin); | 1981 | emacs_close (xforkin); |
| 1994 | xforkout = xforkin = emacs_open (pty_name, O_RDWR, 0); | 1982 | xforkout = xforkin = emacs_open (SSDATA (lisp_pty_name), O_RDWR, 0); |
| 1995 | 1983 | ||
| 1996 | if (xforkin < 0) | 1984 | if (xforkin < 0) |
| 1997 | { | 1985 | { |
| 1998 | emacs_perror (pty_name); | 1986 | emacs_perror (SSDATA (lisp_pty_name)); |
| 1999 | _exit (EXIT_CANCELED); | 1987 | _exit (EXIT_CANCELED); |
| 2000 | } | 1988 | } |
| 2001 | 1989 | ||
| @@ -2025,7 +2013,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2025 | pid = child_setup (xforkin, xforkout, xforkout, | 2013 | pid = child_setup (xforkin, xforkout, xforkout, |
| 2026 | new_argv, 1, encoded_current_dir); | 2014 | new_argv, 1, encoded_current_dir); |
| 2027 | #else /* not WINDOWSNT */ | 2015 | #else /* not WINDOWSNT */ |
| 2028 | emacs_close (wait_child_setup[0]); | ||
| 2029 | child_setup (xforkin, xforkout, xforkout, | 2016 | child_setup (xforkin, xforkout, xforkout, |
| 2030 | new_argv, 1, encoded_current_dir); | 2017 | new_argv, 1, encoded_current_dir); |
| 2031 | #endif /* not WINDOWSNT */ | 2018 | #endif /* not WINDOWSNT */ |
| @@ -2042,14 +2029,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2042 | unblock_child_signal (); | 2029 | unblock_child_signal (); |
| 2043 | unblock_input (); | 2030 | unblock_input (); |
| 2044 | 2031 | ||
| 2032 | if (forkin >= 0) | ||
| 2033 | emacs_close (forkin); | ||
| 2034 | if (forkin != forkout && forkout >= 0) | ||
| 2035 | emacs_close (forkout); | ||
| 2036 | |||
| 2045 | if (pid < 0) | 2037 | if (pid < 0) |
| 2046 | { | 2038 | report_file_errno ("Doing vfork", Qnil, vfork_errno); |
| 2047 | if (forkin >= 0) | ||
| 2048 | emacs_close (forkin); | ||
| 2049 | if (forkin != forkout && forkout >= 0) | ||
| 2050 | emacs_close (forkout); | ||
| 2051 | report_file_errno ("Doing vfork", Qnil, vfork_errno); | ||
| 2052 | } | ||
| 2053 | else | 2039 | else |
| 2054 | { | 2040 | { |
| 2055 | /* vfork succeeded. */ | 2041 | /* vfork succeeded. */ |
| @@ -2058,26 +2044,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2058 | register_child (pid, inchannel); | 2044 | register_child (pid, inchannel); |
| 2059 | #endif /* WINDOWSNT */ | 2045 | #endif /* WINDOWSNT */ |
| 2060 | 2046 | ||
| 2061 | /* If the subfork execv fails, and it exits, | ||
| 2062 | this close hangs. I don't know why. | ||
| 2063 | So have an interrupt jar it loose. */ | ||
| 2064 | { | ||
| 2065 | struct atimer *timer; | ||
| 2066 | EMACS_TIME offset = make_emacs_time (1, 0); | ||
| 2067 | |||
| 2068 | stop_polling (); | ||
| 2069 | timer = start_atimer (ATIMER_RELATIVE, offset, create_process_1, 0); | ||
| 2070 | |||
| 2071 | if (forkin >= 0) | ||
| 2072 | emacs_close (forkin); | ||
| 2073 | |||
| 2074 | cancel_atimer (timer); | ||
| 2075 | start_polling (); | ||
| 2076 | } | ||
| 2077 | |||
| 2078 | if (forkin != forkout && forkout >= 0) | ||
| 2079 | emacs_close (forkout); | ||
| 2080 | |||
| 2081 | pset_tty_name (XPROCESS (process), lisp_pty_name); | 2047 | pset_tty_name (XPROCESS (process), lisp_pty_name); |
| 2082 | 2048 | ||
| 2083 | #ifndef WINDOWSNT | 2049 | #ifndef WINDOWSNT |
| @@ -2096,17 +2062,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2096 | } | 2062 | } |
| 2097 | } | 2063 | } |
| 2098 | 2064 | ||
| 2099 | void | 2065 | static void |
| 2100 | create_pty (Lisp_Object process) | 2066 | create_pty (Lisp_Object process) |
| 2101 | { | 2067 | { |
| 2068 | char pty_name[PTY_NAME_SIZE]; | ||
| 2102 | int inchannel, outchannel; | 2069 | int inchannel, outchannel; |
| 2103 | bool pty_flag = 0; | ||
| 2104 | 2070 | ||
| 2105 | inchannel = outchannel = -1; | 2071 | inchannel = outchannel = -1; |
| 2106 | 2072 | ||
| 2107 | #ifdef HAVE_PTYS | ||
| 2108 | if (!NILP (Vprocess_connection_type)) | 2073 | if (!NILP (Vprocess_connection_type)) |
| 2109 | outchannel = inchannel = allocate_pty (); | 2074 | outchannel = inchannel = allocate_pty (pty_name); |
| 2110 | 2075 | ||
| 2111 | if (inchannel >= 0) | 2076 | if (inchannel >= 0) |
| 2112 | { | 2077 | { |
| @@ -2125,37 +2090,29 @@ create_pty (Lisp_Object process) | |||
| 2125 | child_setup_tty (forkout); | 2090 | child_setup_tty (forkout); |
| 2126 | #endif /* DONT_REOPEN_PTY */ | 2091 | #endif /* DONT_REOPEN_PTY */ |
| 2127 | #endif /* not USG, or USG_SUBTTY_WORKS */ | 2092 | #endif /* not USG, or USG_SUBTTY_WORKS */ |
| 2128 | pty_flag = 1; | ||
| 2129 | } | ||
| 2130 | #endif /* HAVE_PTYS */ | ||
| 2131 | 2093 | ||
| 2132 | fcntl (inchannel, F_SETFL, O_NONBLOCK); | 2094 | fcntl (inchannel, F_SETFL, O_NONBLOCK); |
| 2133 | fcntl (outchannel, F_SETFL, O_NONBLOCK); | 2095 | fcntl (outchannel, F_SETFL, O_NONBLOCK); |
| 2134 | 2096 | ||
| 2135 | /* Record this as an active process, with its channels. | 2097 | /* Record this as an active process, with its channels. |
| 2136 | As a result, child_setup will close Emacs's side of the pipes. */ | 2098 | As a result, child_setup will close Emacs's side of the pipes. */ |
| 2137 | chan_process[inchannel] = process; | 2099 | chan_process[inchannel] = process; |
| 2138 | XPROCESS (process)->infd = inchannel; | 2100 | XPROCESS (process)->infd = inchannel; |
| 2139 | XPROCESS (process)->outfd = outchannel; | 2101 | XPROCESS (process)->outfd = outchannel; |
| 2140 | 2102 | ||
| 2141 | /* Previously we recorded the tty descriptor used in the subprocess. | 2103 | /* Previously we recorded the tty descriptor used in the subprocess. |
| 2142 | It was only used for getting the foreground tty process, so now | 2104 | It was only used for getting the foreground tty process, so now |
| 2143 | we just reopen the device (see emacs_get_tty_pgrp) as this is | 2105 | we just reopen the device (see emacs_get_tty_pgrp) as this is |
| 2144 | more portable (see USG_SUBTTY_WORKS above). */ | 2106 | more portable (see USG_SUBTTY_WORKS above). */ |
| 2145 | 2107 | ||
| 2146 | XPROCESS (process)->pty_flag = pty_flag; | 2108 | XPROCESS (process)->pty_flag = 1; |
| 2147 | pset_status (XPROCESS (process), Qrun); | 2109 | pset_status (XPROCESS (process), Qrun); |
| 2148 | setup_process_coding_systems (process); | 2110 | setup_process_coding_systems (process); |
| 2149 | 2111 | ||
| 2150 | add_process_read_fd (inchannel); | 2112 | pset_tty_name (XPROCESS (process), build_string (pty_name)); |
| 2113 | } | ||
| 2151 | 2114 | ||
| 2152 | XPROCESS (process)->pid = -2; | 2115 | XPROCESS (process)->pid = -2; |
| 2153 | #ifdef HAVE_PTYS | ||
| 2154 | if (pty_flag) | ||
| 2155 | pset_tty_name (XPROCESS (process), build_string (pty_name)); | ||
| 2156 | else | ||
| 2157 | #endif | ||
| 2158 | pset_tty_name (XPROCESS (process), Qnil); | ||
| 2159 | } | 2116 | } |
| 2160 | 2117 | ||
| 2161 | 2118 | ||
| @@ -2515,8 +2472,12 @@ set_socket_option (int s, Lisp_Object opt, Lisp_Object val) | |||
| 2515 | } | 2472 | } |
| 2516 | 2473 | ||
| 2517 | if (ret < 0) | 2474 | if (ret < 0) |
| 2518 | report_file_error ("Cannot set network option", | 2475 | { |
| 2519 | Fcons (opt, Fcons (val, Qnil))); | 2476 | int setsockopt_errno = errno; |
| 2477 | report_file_errno ("Cannot set network option", list2 (opt, val), | ||
| 2478 | setsockopt_errno); | ||
| 2479 | } | ||
| 2480 | |||
| 2520 | return (1 << sopt->optbit); | 2481 | return (1 << sopt->optbit); |
| 2521 | } | 2482 | } |
| 2522 | 2483 | ||
| @@ -2648,16 +2609,6 @@ usage: (serial-process-configure &rest ARGS) */) | |||
| 2648 | return Qnil; | 2609 | return Qnil; |
| 2649 | } | 2610 | } |
| 2650 | 2611 | ||
| 2651 | /* Used by make-serial-process to recover from errors. */ | ||
| 2652 | static Lisp_Object | ||
| 2653 | make_serial_process_unwind (Lisp_Object proc) | ||
| 2654 | { | ||
| 2655 | if (!PROCESSP (proc)) | ||
| 2656 | emacs_abort (); | ||
| 2657 | remove_process (proc); | ||
| 2658 | return Qnil; | ||
| 2659 | } | ||
| 2660 | |||
| 2661 | DEFUN ("make-serial-process", Fmake_serial_process, Smake_serial_process, | 2612 | DEFUN ("make-serial-process", Fmake_serial_process, Smake_serial_process, |
| 2662 | 0, MANY, 0, | 2613 | 0, MANY, 0, |
| 2663 | doc: /* Create and return a serial port process. | 2614 | doc: /* Create and return a serial port process. |
| @@ -2763,10 +2714,10 @@ usage: (make-serial-process &rest ARGS) */) | |||
| 2763 | CHECK_STRING (name); | 2714 | CHECK_STRING (name); |
| 2764 | proc = make_process (name); | 2715 | proc = make_process (name); |
| 2765 | specpdl_count = SPECPDL_INDEX (); | 2716 | specpdl_count = SPECPDL_INDEX (); |
| 2766 | record_unwind_protect (make_serial_process_unwind, proc); | 2717 | record_unwind_protect (remove_process, proc); |
| 2767 | p = XPROCESS (proc); | 2718 | p = XPROCESS (proc); |
| 2768 | 2719 | ||
| 2769 | fd = serial_open (SSDATA (port)); | 2720 | fd = serial_open (port); |
| 2770 | p->infd = fd; | 2721 | p->infd = fd; |
| 2771 | p->outfd = fd; | 2722 | p->outfd = fd; |
| 2772 | if (fd > max_desc) | 2723 | if (fd > max_desc) |
| @@ -2789,7 +2740,7 @@ usage: (make-serial-process &rest ARGS) */) | |||
| 2789 | p->kill_without_query = 1; | 2740 | p->kill_without_query = 1; |
| 2790 | if (tem = Fplist_get (contact, QCstop), !NILP (tem)) | 2741 | if (tem = Fplist_get (contact, QCstop), !NILP (tem)) |
| 2791 | pset_command (p, Qt); | 2742 | pset_command (p, Qt); |
| 2792 | p->pty_flag = 0; | 2743 | eassert (! p->pty_flag); |
| 2793 | 2744 | ||
| 2794 | if (!EQ (p->command, Qt)) | 2745 | if (!EQ (p->command, Qt)) |
| 2795 | add_non_keyboard_read_fd (fd); | 2746 | add_non_keyboard_read_fd (fd); |
| @@ -3196,7 +3147,7 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3196 | #ifdef POLL_FOR_INPUT | 3147 | #ifdef POLL_FOR_INPUT |
| 3197 | if (socktype != SOCK_DGRAM) | 3148 | if (socktype != SOCK_DGRAM) |
| 3198 | { | 3149 | { |
| 3199 | record_unwind_protect (unwind_stop_other_atimers, Qnil); | 3150 | record_unwind_protect_void (run_all_atimers); |
| 3200 | bind_polling_period (10); | 3151 | bind_polling_period (10); |
| 3201 | } | 3152 | } |
| 3202 | #endif | 3153 | #endif |
| @@ -3356,7 +3307,7 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3356 | #endif | 3307 | #endif |
| 3357 | 3308 | ||
| 3358 | /* Make us close S if quit. */ | 3309 | /* Make us close S if quit. */ |
| 3359 | record_unwind_protect (close_file_unwind, make_number (s)); | 3310 | record_unwind_protect_int (close_file_unwind, s); |
| 3360 | 3311 | ||
| 3361 | /* Parse network options in the arg list. | 3312 | /* Parse network options in the arg list. |
| 3362 | We simply ignore anything which isn't a known option (including other keywords). | 3313 | We simply ignore anything which isn't a known option (including other keywords). |
| @@ -3447,16 +3398,16 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3447 | if (errno == EINTR) | 3398 | if (errno == EINTR) |
| 3448 | goto retry_select; | 3399 | goto retry_select; |
| 3449 | else | 3400 | else |
| 3450 | report_file_error ("select failed", Qnil); | 3401 | report_file_error ("Failed select", Qnil); |
| 3451 | } | 3402 | } |
| 3452 | eassert (sc > 0); | 3403 | eassert (sc > 0); |
| 3453 | 3404 | ||
| 3454 | len = sizeof xerrno; | 3405 | len = sizeof xerrno; |
| 3455 | eassert (FD_ISSET (s, &fdset)); | 3406 | eassert (FD_ISSET (s, &fdset)); |
| 3456 | if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0) | 3407 | if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0) |
| 3457 | report_file_error ("getsockopt failed", Qnil); | 3408 | report_file_error ("Failed getsockopt", Qnil); |
| 3458 | if (xerrno) | 3409 | if (xerrno) |
| 3459 | report_file_errno ("error during connect", Qnil, xerrno); | 3410 | report_file_errno ("Failed connect", Qnil, xerrno); |
| 3460 | break; | 3411 | break; |
| 3461 | } | 3412 | } |
| 3462 | #endif /* !WINDOWSNT */ | 3413 | #endif /* !WINDOWSNT */ |
| @@ -3716,10 +3667,13 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3716 | ptrdiff_t buf_size = 512; | 3667 | ptrdiff_t buf_size = 512; |
| 3717 | int s; | 3668 | int s; |
| 3718 | Lisp_Object res; | 3669 | Lisp_Object res; |
| 3670 | ptrdiff_t count; | ||
| 3719 | 3671 | ||
| 3720 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); | 3672 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); |
| 3721 | if (s < 0) | 3673 | if (s < 0) |
| 3722 | return Qnil; | 3674 | return Qnil; |
| 3675 | count = SPECPDL_INDEX (); | ||
| 3676 | record_unwind_protect_int (close_file_unwind, s); | ||
| 3723 | 3677 | ||
| 3724 | do | 3678 | do |
| 3725 | { | 3679 | { |
| @@ -3735,9 +3689,7 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3735 | } | 3689 | } |
| 3736 | while (ifconf.ifc_len == buf_size); | 3690 | while (ifconf.ifc_len == buf_size); |
| 3737 | 3691 | ||
| 3738 | emacs_close (s); | 3692 | res = unbind_to (count, Qnil); |
| 3739 | |||
| 3740 | res = Qnil; | ||
| 3741 | ifreq = ifconf.ifc_req; | 3693 | ifreq = ifconf.ifc_req; |
| 3742 | while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len) | 3694 | while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len) |
| 3743 | { | 3695 | { |
| @@ -3862,6 +3814,7 @@ FLAGS is the current flags of the interface. */) | |||
| 3862 | Lisp_Object elt; | 3814 | Lisp_Object elt; |
| 3863 | int s; | 3815 | int s; |
| 3864 | bool any = 0; | 3816 | bool any = 0; |
| 3817 | ptrdiff_t count; | ||
| 3865 | #if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \ | 3818 | #if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \ |
| 3866 | && defined HAVE_GETIFADDRS && defined LLADDR) | 3819 | && defined HAVE_GETIFADDRS && defined LLADDR) |
| 3867 | struct ifaddrs *ifap; | 3820 | struct ifaddrs *ifap; |
| @@ -3876,6 +3829,8 @@ FLAGS is the current flags of the interface. */) | |||
| 3876 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); | 3829 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); |
| 3877 | if (s < 0) | 3830 | if (s < 0) |
| 3878 | return Qnil; | 3831 | return Qnil; |
| 3832 | count = SPECPDL_INDEX (); | ||
| 3833 | record_unwind_protect_int (close_file_unwind, s); | ||
| 3879 | 3834 | ||
| 3880 | elt = Qnil; | 3835 | elt = Qnil; |
| 3881 | #if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS) | 3836 | #if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS) |
| @@ -3992,9 +3947,7 @@ FLAGS is the current flags of the interface. */) | |||
| 3992 | #endif | 3947 | #endif |
| 3993 | res = Fcons (elt, res); | 3948 | res = Fcons (elt, res); |
| 3994 | 3949 | ||
| 3995 | emacs_close (s); | 3950 | return unbind_to (count, any ? res : Qnil); |
| 3996 | |||
| 3997 | return any ? res : Qnil; | ||
| 3998 | } | 3951 | } |
| 3999 | #endif | 3952 | #endif |
| 4000 | #endif /* defined (HAVE_NET_IF_H) */ | 3953 | #endif /* defined (HAVE_NET_IF_H) */ |
| @@ -4164,6 +4117,7 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4164 | #endif | 4117 | #endif |
| 4165 | } saddr; | 4118 | } saddr; |
| 4166 | socklen_t len = sizeof saddr; | 4119 | socklen_t len = sizeof saddr; |
| 4120 | ptrdiff_t count; | ||
| 4167 | 4121 | ||
| 4168 | s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC); | 4122 | s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC); |
| 4169 | 4123 | ||
| @@ -4186,6 +4140,9 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4186 | return; | 4140 | return; |
| 4187 | } | 4141 | } |
| 4188 | 4142 | ||
| 4143 | count = SPECPDL_INDEX (); | ||
| 4144 | record_unwind_protect_int (close_file_unwind, s); | ||
| 4145 | |||
| 4189 | connect_counter++; | 4146 | connect_counter++; |
| 4190 | 4147 | ||
| 4191 | /* Setup a new process to handle the connection. */ | 4148 | /* Setup a new process to handle the connection. */ |
| @@ -4302,6 +4259,10 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4302 | pset_filter (p, ps->filter); | 4259 | pset_filter (p, ps->filter); |
| 4303 | pset_command (p, Qnil); | 4260 | pset_command (p, Qnil); |
| 4304 | p->pid = 0; | 4261 | p->pid = 0; |
| 4262 | |||
| 4263 | /* Discard the unwind protect for closing S. */ | ||
| 4264 | specpdl_ptr = specpdl + count; | ||
| 4265 | |||
| 4305 | p->infd = s; | 4266 | p->infd = s; |
| 4306 | p->outfd = s; | 4267 | p->outfd = s; |
| 4307 | pset_status (p, Qrun); | 4268 | pset_status (p, Qrun); |
| @@ -4338,12 +4299,11 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4338 | build_string ("\n"))); | 4299 | build_string ("\n"))); |
| 4339 | } | 4300 | } |
| 4340 | 4301 | ||
| 4341 | static Lisp_Object | 4302 | static void |
| 4342 | wait_reading_process_output_unwind (Lisp_Object data) | 4303 | wait_reading_process_output_unwind (int data) |
| 4343 | { | 4304 | { |
| 4344 | clear_waiting_thread_info (); | 4305 | clear_waiting_thread_info (); |
| 4345 | waiting_for_user_input_p = XINT (data); | 4306 | waiting_for_user_input_p = data; |
| 4346 | return Qnil; | ||
| 4347 | } | 4307 | } |
| 4348 | 4308 | ||
| 4349 | /* This is here so breakpoints can be put on it. */ | 4309 | /* This is here so breakpoints can be put on it. */ |
| @@ -4425,8 +4385,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4425 | if (wait_proc != NULL) | 4385 | if (wait_proc != NULL) |
| 4426 | wait_channel = wait_proc->infd; | 4386 | wait_channel = wait_proc->infd; |
| 4427 | 4387 | ||
| 4428 | record_unwind_protect (wait_reading_process_output_unwind, | 4388 | record_unwind_protect_int (wait_reading_process_output_unwind, |
| 4429 | make_number (waiting_for_user_input_p)); | 4389 | waiting_for_user_input_p); |
| 4430 | waiting_for_user_input_p = read_kbd; | 4390 | waiting_for_user_input_p = read_kbd; |
| 4431 | 4391 | ||
| 4432 | if (time_limit < 0) | 4392 | if (time_limit < 0) |
| @@ -4791,7 +4751,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4791 | else if (xerrno == EBADF) | 4751 | else if (xerrno == EBADF) |
| 4792 | emacs_abort (); | 4752 | emacs_abort (); |
| 4793 | else | 4753 | else |
| 4794 | error ("select error: %s", emacs_strerror (xerrno)); | 4754 | report_file_errno ("Failed select", Qnil, xerrno); |
| 4795 | } | 4755 | } |
| 4796 | 4756 | ||
| 4797 | if (no_avail) | 4757 | if (no_avail) |
| @@ -5284,9 +5244,7 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars, | |||
| 5284 | sometimes it's simply wrong to wrap (e.g. when called from | 5244 | sometimes it's simply wrong to wrap (e.g. when called from |
| 5285 | accept-process-output). */ | 5245 | accept-process-output). */ |
| 5286 | internal_condition_case_1 (read_process_output_call, | 5246 | internal_condition_case_1 (read_process_output_call, |
| 5287 | Fcons (outstream, | 5247 | list3 (outstream, make_lisp_proc (p), text), |
| 5288 | Fcons (make_lisp_proc (p), | ||
| 5289 | Fcons (text, Qnil))), | ||
| 5290 | !NILP (Vdebug_on_error) ? Qnil : Qerror, | 5248 | !NILP (Vdebug_on_error) ? Qnil : Qerror, |
| 5291 | read_process_output_error_handler); | 5249 | read_process_output_error_handler); |
| 5292 | 5250 | ||
| @@ -5456,7 +5414,7 @@ write_queue_push (struct Lisp_Process *p, Lisp_Object input_obj, | |||
| 5456 | if (front) | 5414 | if (front) |
| 5457 | pset_write_queue (p, Fcons (entry, p->write_queue)); | 5415 | pset_write_queue (p, Fcons (entry, p->write_queue)); |
| 5458 | else | 5416 | else |
| 5459 | pset_write_queue (p, nconc2 (p->write_queue, Fcons (entry, Qnil))); | 5417 | pset_write_queue (p, nconc2 (p->write_queue, list1 (entry))); |
| 5460 | } | 5418 | } |
| 5461 | 5419 | ||
| 5462 | /* Remove the first element in the write_queue of process P, put its | 5420 | /* Remove the first element in the write_queue of process P, put its |
| @@ -5629,7 +5587,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, | |||
| 5629 | if (rv >= 0) | 5587 | if (rv >= 0) |
| 5630 | written = rv; | 5588 | written = rv; |
| 5631 | else if (errno == EMSGSIZE) | 5589 | else if (errno == EMSGSIZE) |
| 5632 | report_file_error ("sending datagram", Fcons (proc, Qnil)); | 5590 | report_file_error ("Sending datagram", proc); |
| 5633 | } | 5591 | } |
| 5634 | else | 5592 | else |
| 5635 | #endif | 5593 | #endif |
| @@ -5706,7 +5664,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, | |||
| 5706 | } | 5664 | } |
| 5707 | else | 5665 | else |
| 5708 | /* This is a real error. */ | 5666 | /* This is a real error. */ |
| 5709 | report_file_error ("writing to process", Fcons (proc, Qnil)); | 5667 | report_file_error ("Writing to process", proc); |
| 5710 | } | 5668 | } |
| 5711 | cur_buf += written; | 5669 | cur_buf += written; |
| 5712 | cur_len -= written; | 5670 | cur_len -= written; |
| @@ -6196,7 +6154,7 @@ process has been transmitted to the serial port. */) | |||
| 6196 | { | 6154 | { |
| 6197 | #ifndef WINDOWSNT | 6155 | #ifndef WINDOWSNT |
| 6198 | if (tcdrain (XPROCESS (proc)->outfd) != 0) | 6156 | if (tcdrain (XPROCESS (proc)->outfd) != 0) |
| 6199 | error ("tcdrain() failed: %s", emacs_strerror (errno)); | 6157 | report_file_error ("Failed tcdrain", Qnil); |
| 6200 | #endif /* not WINDOWSNT */ | 6158 | #endif /* not WINDOWSNT */ |
| 6201 | /* Do nothing on Windows because writes are blocking. */ | 6159 | /* Do nothing on Windows because writes are blocking. */ |
| 6202 | } | 6160 | } |
| @@ -6425,8 +6383,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason) | |||
| 6425 | running_asynch_code = 1; | 6383 | running_asynch_code = 1; |
| 6426 | 6384 | ||
| 6427 | internal_condition_case_1 (read_process_output_call, | 6385 | internal_condition_case_1 (read_process_output_call, |
| 6428 | Fcons (sentinel, | 6386 | list3 (sentinel, proc, reason), |
| 6429 | Fcons (proc, Fcons (reason, Qnil))), | ||
| 6430 | !NILP (Vdebug_on_error) ? Qnil : Qerror, | 6387 | !NILP (Vdebug_on_error) ? Qnil : Qerror, |
| 6431 | exec_sentinel_error_handler); | 6388 | exec_sentinel_error_handler); |
| 6432 | 6389 | ||
| @@ -6890,7 +6847,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 6890 | if (xerrno == EINTR) | 6847 | if (xerrno == EINTR) |
| 6891 | FD_ZERO (&waitchannels); | 6848 | FD_ZERO (&waitchannels); |
| 6892 | else | 6849 | else |
| 6893 | error ("select error: %s", emacs_strerror (xerrno)); | 6850 | report_file_errno ("Failed select", Qnil, xerrno); |
| 6894 | } | 6851 | } |
| 6895 | 6852 | ||
| 6896 | /* Check for keyboard input */ | 6853 | /* Check for keyboard input */ |