diff options
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 296 |
1 files changed, 281 insertions, 15 deletions
diff --git a/src/process.c b/src/process.c index 2800fa58340..fbc634be49c 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -189,6 +189,8 @@ process_socket (int domain, int type, int protocol) | |||
| 189 | #define NETCONN1_P(p) (EQ (p->type, Qnetwork)) | 189 | #define NETCONN1_P(p) (EQ (p->type, Qnetwork)) |
| 190 | #define SERIALCONN_P(p) (EQ (XPROCESS (p)->type, Qserial)) | 190 | #define SERIALCONN_P(p) (EQ (XPROCESS (p)->type, Qserial)) |
| 191 | #define SERIALCONN1_P(p) (EQ (p->type, Qserial)) | 191 | #define SERIALCONN1_P(p) (EQ (p->type, Qserial)) |
| 192 | #define PIPECONN_P(p) (EQ (XPROCESS (p)->type, Qpipe)) | ||
| 193 | #define PIPECONN1_P(p) (EQ (p->type, Qpipe)) | ||
| 192 | 194 | ||
| 193 | /* Number of events of change of status of a process. */ | 195 | /* Number of events of change of status of a process. */ |
| 194 | static EMACS_INT process_tick; | 196 | static EMACS_INT process_tick; |
| @@ -411,6 +413,11 @@ pset_write_queue (struct Lisp_Process *p, Lisp_Object val) | |||
| 411 | { | 413 | { |
| 412 | p->write_queue = val; | 414 | p->write_queue = val; |
| 413 | } | 415 | } |
| 416 | static void | ||
| 417 | pset_stderrproc (struct Lisp_Process *p, Lisp_Object val) | ||
| 418 | { | ||
| 419 | p->stderrproc = val; | ||
| 420 | } | ||
| 414 | 421 | ||
| 415 | 422 | ||
| 416 | static Lisp_Object | 423 | static Lisp_Object |
| @@ -837,7 +844,7 @@ nil, indicating the current buffer's process. */) | |||
| 837 | p = XPROCESS (process); | 844 | p = XPROCESS (process); |
| 838 | 845 | ||
| 839 | p->raw_status_new = 0; | 846 | p->raw_status_new = 0; |
| 840 | if (NETCONN1_P (p) || SERIALCONN1_P (p)) | 847 | if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p)) |
| 841 | { | 848 | { |
| 842 | pset_status (p, list2 (Qexit, make_number (0))); | 849 | pset_status (p, list2 (Qexit, make_number (0))); |
| 843 | p->tick = ++process_tick; | 850 | p->tick = ++process_tick; |
| @@ -903,7 +910,7 @@ nil, indicating the current buffer's process. */) | |||
| 903 | status = p->status; | 910 | status = p->status; |
| 904 | if (CONSP (status)) | 911 | if (CONSP (status)) |
| 905 | status = XCAR (status); | 912 | status = XCAR (status); |
| 906 | if (NETCONN1_P (p) || SERIALCONN1_P (p)) | 913 | if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p)) |
| 907 | { | 914 | { |
| 908 | if (EQ (status, Qexit)) | 915 | if (EQ (status, Qexit)) |
| 909 | status = Qclosed; | 916 | status = Qclosed; |
| @@ -987,7 +994,7 @@ Return BUFFER. */) | |||
| 987 | CHECK_BUFFER (buffer); | 994 | CHECK_BUFFER (buffer); |
| 988 | p = XPROCESS (process); | 995 | p = XPROCESS (process); |
| 989 | pset_buffer (p, buffer); | 996 | pset_buffer (p, buffer); |
| 990 | if (NETCONN1_P (p) || SERIALCONN1_P (p)) | 997 | if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p)) |
| 991 | pset_childp (p, Fplist_put (p->childp, QCbuffer, buffer)); | 998 | pset_childp (p, Fplist_put (p->childp, QCbuffer, buffer)); |
| 992 | setup_process_coding_systems (process); | 999 | setup_process_coding_systems (process); |
| 993 | return buffer; | 1000 | return buffer; |
| @@ -1063,7 +1070,7 @@ The string argument is normally a multibyte string, except: | |||
| 1063 | } | 1070 | } |
| 1064 | 1071 | ||
| 1065 | pset_filter (p, filter); | 1072 | pset_filter (p, filter); |
| 1066 | if (NETCONN1_P (p) || SERIALCONN1_P (p)) | 1073 | if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p)) |
| 1067 | pset_childp (p, Fplist_put (p->childp, QCfilter, filter)); | 1074 | pset_childp (p, Fplist_put (p->childp, QCfilter, filter)); |
| 1068 | setup_process_coding_systems (process); | 1075 | setup_process_coding_systems (process); |
| 1069 | return filter; | 1076 | return filter; |
| @@ -1095,7 +1102,7 @@ It gets two arguments: the process, and a string describing the change. */) | |||
| 1095 | sentinel = Qinternal_default_process_sentinel; | 1102 | sentinel = Qinternal_default_process_sentinel; |
| 1096 | 1103 | ||
| 1097 | pset_sentinel (p, sentinel); | 1104 | pset_sentinel (p, sentinel); |
| 1098 | if (NETCONN1_P (p) || SERIALCONN1_P (p)) | 1105 | if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p)) |
| 1099 | pset_childp (p, Fplist_put (p->childp, QCsentinel, sentinel)); | 1106 | pset_childp (p, Fplist_put (p->childp, QCsentinel, sentinel)); |
| 1100 | return sentinel; | 1107 | return sentinel; |
| 1101 | } | 1108 | } |
| @@ -1204,7 +1211,8 @@ list of keywords. */) | |||
| 1204 | Fprocess_datagram_address (process)); | 1211 | Fprocess_datagram_address (process)); |
| 1205 | #endif | 1212 | #endif |
| 1206 | 1213 | ||
| 1207 | if ((!NETCONN_P (process) && !SERIALCONN_P (process)) || EQ (key, Qt)) | 1214 | if ((!NETCONN_P (process) && !SERIALCONN_P (process) && !PIPECONN_P (process)) |
| 1215 | || EQ (key, Qt)) | ||
| 1208 | return contact; | 1216 | return contact; |
| 1209 | if (NILP (key) && NETCONN_P (process)) | 1217 | if (NILP (key) && NETCONN_P (process)) |
| 1210 | return list2 (Fplist_get (contact, QChost), | 1218 | return list2 (Fplist_get (contact, QChost), |
| @@ -1212,6 +1220,11 @@ list of keywords. */) | |||
| 1212 | if (NILP (key) && SERIALCONN_P (process)) | 1220 | if (NILP (key) && SERIALCONN_P (process)) |
| 1213 | return list2 (Fplist_get (contact, QCport), | 1221 | return list2 (Fplist_get (contact, QCport), |
| 1214 | Fplist_get (contact, QCspeed)); | 1222 | Fplist_get (contact, QCspeed)); |
| 1223 | /* FIXME: Return a meaningful value (e.g. the child ends of pipe), | ||
| 1224 | if pipe process is useful for other purposes than receiving | ||
| 1225 | stderr. */ | ||
| 1226 | if (NILP (key) && PIPECONN_P (process)) | ||
| 1227 | return Qt; | ||
| 1215 | return Fplist_get (contact, key); | 1228 | return Fplist_get (contact, key); |
| 1216 | } | 1229 | } |
| 1217 | 1230 | ||
| @@ -1386,10 +1399,15 @@ to use a pty, or nil to use the default specified through | |||
| 1386 | 1399 | ||
| 1387 | :sentinel SENTINEL -- Install SENTINEL as the process sentinel. | 1400 | :sentinel SENTINEL -- Install SENTINEL as the process sentinel. |
| 1388 | 1401 | ||
| 1402 | :stderr STDERR -- STDERR is either a buffer or a pipe process attached | ||
| 1403 | to the standard error of subprocess. Specifying this implies | ||
| 1404 | `:connection-type' is set to `pipe'. | ||
| 1405 | |||
| 1389 | usage: (make-process &rest ARGS) */) | 1406 | usage: (make-process &rest ARGS) */) |
| 1390 | (ptrdiff_t nargs, Lisp_Object *args) | 1407 | (ptrdiff_t nargs, Lisp_Object *args) |
| 1391 | { | 1408 | { |
| 1392 | Lisp_Object buffer, name, command, program, proc, contact, current_dir, tem; | 1409 | Lisp_Object buffer, name, command, program, proc, contact, current_dir, tem; |
| 1410 | Lisp_Object xstderr, stderrproc; | ||
| 1393 | ptrdiff_t count = SPECPDL_INDEX (); | 1411 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1394 | struct gcpro gcpro1; | 1412 | struct gcpro gcpro1; |
| 1395 | USE_SAFE_ALLOCA; | 1413 | USE_SAFE_ALLOCA; |
| @@ -1433,6 +1451,27 @@ usage: (make-process &rest ARGS) */) | |||
| 1433 | if (!NILP (program)) | 1451 | if (!NILP (program)) |
| 1434 | CHECK_STRING (program); | 1452 | CHECK_STRING (program); |
| 1435 | 1453 | ||
| 1454 | stderrproc = Qnil; | ||
| 1455 | xstderr = Fplist_get (contact, QCstderr); | ||
| 1456 | if (PROCESSP (xstderr)) | ||
| 1457 | { | ||
| 1458 | if (!PIPECONN_P (xstderr)) | ||
| 1459 | error ("Process is not a pipe process"); | ||
| 1460 | stderrproc = xstderr; | ||
| 1461 | } | ||
| 1462 | else if (!NILP (xstderr)) | ||
| 1463 | { | ||
| 1464 | struct gcpro gcpro1, gcpro2; | ||
| 1465 | CHECK_STRING (program); | ||
| 1466 | GCPRO2 (buffer, current_dir); | ||
| 1467 | stderrproc = CALLN (Fmake_pipe_process, | ||
| 1468 | QCname, | ||
| 1469 | concat2 (name, build_string (" stderr")), | ||
| 1470 | QCbuffer, | ||
| 1471 | Fget_buffer_create (xstderr)); | ||
| 1472 | UNGCPRO; | ||
| 1473 | } | ||
| 1474 | |||
| 1436 | proc = make_process (name); | 1475 | proc = make_process (name); |
| 1437 | /* If an error occurs and we can't start the process, we want to | 1476 | /* If an error occurs and we can't start the process, we want to |
| 1438 | remove it from the process list. This means that each error | 1477 | remove it from the process list. This means that each error |
| @@ -1463,6 +1502,13 @@ usage: (make-process &rest ARGS) */) | |||
| 1463 | else | 1502 | else |
| 1464 | report_file_error ("Unknown connection type", tem); | 1503 | report_file_error ("Unknown connection type", tem); |
| 1465 | 1504 | ||
| 1505 | if (!NILP (stderrproc)) | ||
| 1506 | { | ||
| 1507 | pset_stderrproc (XPROCESS (proc), stderrproc); | ||
| 1508 | |||
| 1509 | XPROCESS (proc)->pty_flag = false; | ||
| 1510 | } | ||
| 1511 | |||
| 1466 | #ifdef HAVE_GNUTLS | 1512 | #ifdef HAVE_GNUTLS |
| 1467 | /* AKA GNUTLS_INITSTAGE(proc). */ | 1513 | /* AKA GNUTLS_INITSTAGE(proc). */ |
| 1468 | XPROCESS (proc)->gnutls_initstage = GNUTLS_STAGE_EMPTY; | 1514 | XPROCESS (proc)->gnutls_initstage = GNUTLS_STAGE_EMPTY; |
| @@ -1705,10 +1751,10 @@ static void | |||
| 1705 | create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | 1751 | create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) |
| 1706 | { | 1752 | { |
| 1707 | struct Lisp_Process *p = XPROCESS (process); | 1753 | struct Lisp_Process *p = XPROCESS (process); |
| 1708 | int inchannel, outchannel; | 1754 | int inchannel, outchannel, errchannel = -1; |
| 1709 | pid_t pid; | 1755 | pid_t pid; |
| 1710 | int vfork_errno; | 1756 | int vfork_errno; |
| 1711 | int forkin, forkout; | 1757 | int forkin, forkout, forkerr = -1; |
| 1712 | bool pty_flag = 0; | 1758 | bool pty_flag = 0; |
| 1713 | char pty_name[PTY_NAME_SIZE]; | 1759 | char pty_name[PTY_NAME_SIZE]; |
| 1714 | Lisp_Object lisp_pty_name = Qnil; | 1760 | Lisp_Object lisp_pty_name = Qnil; |
| @@ -1746,6 +1792,18 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1746 | outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; | 1792 | outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; |
| 1747 | inchannel = p->open_fd[READ_FROM_SUBPROCESS]; | 1793 | inchannel = p->open_fd[READ_FROM_SUBPROCESS]; |
| 1748 | forkout = p->open_fd[SUBPROCESS_STDOUT]; | 1794 | forkout = p->open_fd[SUBPROCESS_STDOUT]; |
| 1795 | |||
| 1796 | if (!NILP (p->stderrproc)) | ||
| 1797 | { | ||
| 1798 | struct Lisp_Process *pp = XPROCESS (p->stderrproc); | ||
| 1799 | |||
| 1800 | forkerr = pp->open_fd[SUBPROCESS_STDOUT]; | ||
| 1801 | errchannel = pp->open_fd[READ_FROM_SUBPROCESS]; | ||
| 1802 | |||
| 1803 | /* Close unnecessary file descriptors. */ | ||
| 1804 | close_process_fd (&pp->open_fd[WRITE_TO_SUBPROCESS]); | ||
| 1805 | close_process_fd (&pp->open_fd[SUBPROCESS_STDIN]); | ||
| 1806 | } | ||
| 1749 | } | 1807 | } |
| 1750 | 1808 | ||
| 1751 | #ifndef WINDOWSNT | 1809 | #ifndef WINDOWSNT |
| @@ -1792,6 +1850,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1792 | char **volatile new_argv_volatile = new_argv; | 1850 | char **volatile new_argv_volatile = new_argv; |
| 1793 | int volatile forkin_volatile = forkin; | 1851 | int volatile forkin_volatile = forkin; |
| 1794 | int volatile forkout_volatile = forkout; | 1852 | int volatile forkout_volatile = forkout; |
| 1853 | int volatile forkerr_volatile = forkerr; | ||
| 1795 | struct Lisp_Process *p_volatile = p; | 1854 | struct Lisp_Process *p_volatile = p; |
| 1796 | 1855 | ||
| 1797 | pid = vfork (); | 1856 | pid = vfork (); |
| @@ -1801,6 +1860,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1801 | new_argv = new_argv_volatile; | 1860 | new_argv = new_argv_volatile; |
| 1802 | forkin = forkin_volatile; | 1861 | forkin = forkin_volatile; |
| 1803 | forkout = forkout_volatile; | 1862 | forkout = forkout_volatile; |
| 1863 | forkerr = forkerr_volatile; | ||
| 1804 | p = p_volatile; | 1864 | p = p_volatile; |
| 1805 | 1865 | ||
| 1806 | pty_flag = p->pty_flag; | 1866 | pty_flag = p->pty_flag; |
| @@ -1811,6 +1871,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1811 | { | 1871 | { |
| 1812 | int xforkin = forkin; | 1872 | int xforkin = forkin; |
| 1813 | int xforkout = forkout; | 1873 | int xforkout = forkout; |
| 1874 | int xforkerr = forkerr; | ||
| 1814 | 1875 | ||
| 1815 | /* Make the pty be the controlling terminal of the process. */ | 1876 | /* Make the pty be the controlling terminal of the process. */ |
| 1816 | #ifdef HAVE_PTYS | 1877 | #ifdef HAVE_PTYS |
| @@ -1910,10 +1971,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1910 | 1971 | ||
| 1911 | if (pty_flag) | 1972 | if (pty_flag) |
| 1912 | child_setup_tty (xforkout); | 1973 | child_setup_tty (xforkout); |
| 1974 | |||
| 1975 | if (xforkerr < 0) | ||
| 1976 | xforkerr = xforkout; | ||
| 1913 | #ifdef WINDOWSNT | 1977 | #ifdef WINDOWSNT |
| 1914 | pid = child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); | 1978 | pid = child_setup (xforkin, xforkout, xforkerr, new_argv, 1, current_dir); |
| 1915 | #else /* not WINDOWSNT */ | 1979 | #else /* not WINDOWSNT */ |
| 1916 | child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); | 1980 | child_setup (xforkin, xforkout, xforkerr, new_argv, 1, current_dir); |
| 1917 | #endif /* not WINDOWSNT */ | 1981 | #endif /* not WINDOWSNT */ |
| 1918 | } | 1982 | } |
| 1919 | 1983 | ||
| @@ -1958,6 +2022,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1958 | close_process_fd (&p->open_fd[READ_FROM_EXEC_MONITOR]); | 2022 | close_process_fd (&p->open_fd[READ_FROM_EXEC_MONITOR]); |
| 1959 | } | 2023 | } |
| 1960 | #endif | 2024 | #endif |
| 2025 | if (!NILP (p->stderrproc)) | ||
| 2026 | { | ||
| 2027 | struct Lisp_Process *pp = XPROCESS (p->stderrproc); | ||
| 2028 | close_process_fd (&pp->open_fd[SUBPROCESS_STDOUT]); | ||
| 2029 | } | ||
| 1961 | } | 2030 | } |
| 1962 | } | 2031 | } |
| 1963 | 2032 | ||
| @@ -2016,6 +2085,187 @@ create_pty (Lisp_Object process) | |||
| 2016 | p->pid = -2; | 2085 | p->pid = -2; |
| 2017 | } | 2086 | } |
| 2018 | 2087 | ||
| 2088 | DEFUN ("make-pipe-process", Fmake_pipe_process, Smake_pipe_process, | ||
| 2089 | 0, MANY, 0, | ||
| 2090 | doc: /* Create and return a bidirectional pipe process. | ||
| 2091 | |||
| 2092 | In Emacs, pipes are represented by process objects, so input and | ||
| 2093 | output work as for subprocesses, and `delete-process' closes a pipe. | ||
| 2094 | However, a pipe process has no process id, it cannot be signaled, | ||
| 2095 | and the status codes are different from normal processes. | ||
| 2096 | |||
| 2097 | Arguments are specified as keyword/argument pairs. The following | ||
| 2098 | arguments are defined: | ||
| 2099 | |||
| 2100 | :name NAME -- NAME is the name of the process. It is modified if necessary to make it unique. | ||
| 2101 | |||
| 2102 | :buffer BUFFER -- BUFFER is the buffer (or buffer-name) to associate | ||
| 2103 | with the process. Process output goes at the end of that buffer, | ||
| 2104 | unless you specify an output stream or filter function to handle the | ||
| 2105 | output. If BUFFER is not given, the value of NAME is used. | ||
| 2106 | |||
| 2107 | :coding CODING -- If CODING is a symbol, it specifies the coding | ||
| 2108 | system used for both reading and writing for this process. If CODING | ||
| 2109 | is a cons (DECODING . ENCODING), DECODING is used for reading, and | ||
| 2110 | ENCODING is used for writing. | ||
| 2111 | |||
| 2112 | :noquery BOOL -- When exiting Emacs, query the user if BOOL is nil and | ||
| 2113 | the process is running. If BOOL is not given, query before exiting. | ||
| 2114 | |||
| 2115 | :stop BOOL -- Start process in the `stopped' state if BOOL non-nil. | ||
| 2116 | In the stopped state, a pipe process does not accept incoming data, | ||
| 2117 | but you can send outgoing data. The stopped state is cleared by | ||
| 2118 | `continue-process' and set by `stop-process'. | ||
| 2119 | |||
| 2120 | :filter FILTER -- Install FILTER as the process filter. | ||
| 2121 | |||
| 2122 | :sentinel SENTINEL -- Install SENTINEL as the process sentinel. | ||
| 2123 | |||
| 2124 | usage: (make-pipe-process &rest ARGS) */) | ||
| 2125 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 2126 | { | ||
| 2127 | Lisp_Object proc, contact; | ||
| 2128 | struct Lisp_Process *p; | ||
| 2129 | struct gcpro gcpro1; | ||
| 2130 | Lisp_Object name, buffer; | ||
| 2131 | Lisp_Object tem, val; | ||
| 2132 | ptrdiff_t specpdl_count; | ||
| 2133 | int inchannel, outchannel; | ||
| 2134 | |||
| 2135 | if (nargs == 0) | ||
| 2136 | return Qnil; | ||
| 2137 | |||
| 2138 | contact = Flist (nargs, args); | ||
| 2139 | GCPRO1 (contact); | ||
| 2140 | |||
| 2141 | name = Fplist_get (contact, QCname); | ||
| 2142 | CHECK_STRING (name); | ||
| 2143 | proc = make_process (name); | ||
| 2144 | specpdl_count = SPECPDL_INDEX (); | ||
| 2145 | record_unwind_protect (remove_process, proc); | ||
| 2146 | p = XPROCESS (proc); | ||
| 2147 | |||
| 2148 | if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0 | ||
| 2149 | || emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0) | ||
| 2150 | report_file_error ("Creating pipe", Qnil); | ||
| 2151 | outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; | ||
| 2152 | inchannel = p->open_fd[READ_FROM_SUBPROCESS]; | ||
| 2153 | |||
| 2154 | fcntl (inchannel, F_SETFL, O_NONBLOCK); | ||
| 2155 | fcntl (outchannel, F_SETFL, O_NONBLOCK); | ||
| 2156 | |||
| 2157 | #ifdef WINDOWSNT | ||
| 2158 | register_aux_fd (inchannel); | ||
| 2159 | #endif | ||
| 2160 | |||
| 2161 | /* Record this as an active process, with its channels. */ | ||
| 2162 | chan_process[inchannel] = proc; | ||
| 2163 | p->infd = inchannel; | ||
| 2164 | p->outfd = outchannel; | ||
| 2165 | |||
| 2166 | if (inchannel > max_process_desc) | ||
| 2167 | max_process_desc = inchannel; | ||
| 2168 | |||
| 2169 | buffer = Fplist_get (contact, QCbuffer); | ||
| 2170 | if (NILP (buffer)) | ||
| 2171 | buffer = name; | ||
| 2172 | buffer = Fget_buffer_create (buffer); | ||
| 2173 | pset_buffer (p, buffer); | ||
| 2174 | |||
| 2175 | pset_childp (p, contact); | ||
| 2176 | pset_plist (p, Fcopy_sequence (Fplist_get (contact, QCplist))); | ||
| 2177 | pset_type (p, Qpipe); | ||
| 2178 | pset_sentinel (p, Fplist_get (contact, QCsentinel)); | ||
| 2179 | pset_filter (p, Fplist_get (contact, QCfilter)); | ||
| 2180 | pset_log (p, Qnil); | ||
| 2181 | if (tem = Fplist_get (contact, QCnoquery), !NILP (tem)) | ||
| 2182 | p->kill_without_query = 1; | ||
| 2183 | if (tem = Fplist_get (contact, QCstop), !NILP (tem)) | ||
| 2184 | pset_command (p, Qt); | ||
| 2185 | eassert (! p->pty_flag); | ||
| 2186 | |||
| 2187 | if (!EQ (p->command, Qt)) | ||
| 2188 | { | ||
| 2189 | FD_SET (inchannel, &input_wait_mask); | ||
| 2190 | FD_SET (inchannel, &non_keyboard_wait_mask); | ||
| 2191 | } | ||
| 2192 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 2193 | p->adaptive_read_buffering | ||
| 2194 | = (NILP (Vprocess_adaptive_read_buffering) ? 0 | ||
| 2195 | : EQ (Vprocess_adaptive_read_buffering, Qt) ? 1 : 2); | ||
| 2196 | #endif | ||
| 2197 | |||
| 2198 | /* Make the process marker point into the process buffer (if any). */ | ||
| 2199 | if (BUFFERP (buffer)) | ||
| 2200 | set_marker_both (p->mark, buffer, | ||
| 2201 | BUF_ZV (XBUFFER (buffer)), | ||
| 2202 | BUF_ZV_BYTE (XBUFFER (buffer))); | ||
| 2203 | |||
| 2204 | { | ||
| 2205 | /* Setup coding systems for communicating with the network stream. */ | ||
| 2206 | struct gcpro gcpro1; | ||
| 2207 | /* Qt denotes we have not yet called Ffind_operation_coding_system. */ | ||
| 2208 | Lisp_Object coding_systems = Qt; | ||
| 2209 | Lisp_Object val; | ||
| 2210 | |||
| 2211 | tem = Fplist_get (contact, QCcoding); | ||
| 2212 | val = Qnil; | ||
| 2213 | if (!NILP (tem)) | ||
| 2214 | { | ||
| 2215 | val = tem; | ||
| 2216 | if (CONSP (val)) | ||
| 2217 | val = XCAR (val); | ||
| 2218 | } | ||
| 2219 | else if (!NILP (Vcoding_system_for_read)) | ||
| 2220 | val = Vcoding_system_for_read; | ||
| 2221 | else if ((!NILP (buffer) && NILP (BVAR (XBUFFER (buffer), enable_multibyte_characters))) | ||
| 2222 | || (NILP (buffer) && NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))) | ||
| 2223 | /* We dare not decode end-of-line format by setting VAL to | ||
| 2224 | Qraw_text, because the existing Emacs Lisp libraries | ||
| 2225 | assume that they receive bare code including a sequence of | ||
| 2226 | CR LF. */ | ||
| 2227 | val = Qnil; | ||
| 2228 | else | ||
| 2229 | { | ||
| 2230 | if (CONSP (coding_systems)) | ||
| 2231 | val = XCAR (coding_systems); | ||
| 2232 | else if (CONSP (Vdefault_process_coding_system)) | ||
| 2233 | val = XCAR (Vdefault_process_coding_system); | ||
| 2234 | else | ||
| 2235 | val = Qnil; | ||
| 2236 | } | ||
| 2237 | pset_decode_coding_system (p, val); | ||
| 2238 | |||
| 2239 | if (!NILP (tem)) | ||
| 2240 | { | ||
| 2241 | val = tem; | ||
| 2242 | if (CONSP (val)) | ||
| 2243 | val = XCDR (val); | ||
| 2244 | } | ||
| 2245 | else if (!NILP (Vcoding_system_for_write)) | ||
| 2246 | val = Vcoding_system_for_write; | ||
| 2247 | else if (NILP (BVAR (current_buffer, enable_multibyte_characters))) | ||
| 2248 | val = Qnil; | ||
| 2249 | else | ||
| 2250 | { | ||
| 2251 | if (CONSP (coding_systems)) | ||
| 2252 | val = XCDR (coding_systems); | ||
| 2253 | else if (CONSP (Vdefault_process_coding_system)) | ||
| 2254 | val = XCDR (Vdefault_process_coding_system); | ||
| 2255 | else | ||
| 2256 | val = Qnil; | ||
| 2257 | } | ||
| 2258 | pset_encode_coding_system (p, val); | ||
| 2259 | } | ||
| 2260 | /* This may signal an error. */ | ||
| 2261 | setup_process_coding_systems (proc); | ||
| 2262 | |||
| 2263 | specpdl_ptr = specpdl + specpdl_count; | ||
| 2264 | |||
| 2265 | UNGCPRO; | ||
| 2266 | return proc; | ||
| 2267 | } | ||
| 2268 | |||
| 2019 | 2269 | ||
| 2020 | /* Convert an internal struct sockaddr to a lisp object (vector or string). | 2270 | /* Convert an internal struct sockaddr to a lisp object (vector or string). |
| 2021 | The address family of sa is not included in the result. */ | 2271 | The address family of sa is not included in the result. */ |
| @@ -4884,7 +5134,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4884 | available now and a closed pipe. | 5134 | available now and a closed pipe. |
| 4885 | With luck, a closed pipe will be accompanied by | 5135 | With luck, a closed pipe will be accompanied by |
| 4886 | subprocess termination and SIGCHLD. */ | 5136 | subprocess termination and SIGCHLD. */ |
| 4887 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) | 5137 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc) |
| 5138 | && !PIPECONN_P (proc)) | ||
| 4888 | ; | 5139 | ; |
| 4889 | #endif | 5140 | #endif |
| 4890 | #ifdef HAVE_PTYS | 5141 | #ifdef HAVE_PTYS |
| @@ -4916,8 +5167,18 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4916 | #endif /* HAVE_PTYS */ | 5167 | #endif /* HAVE_PTYS */ |
| 4917 | /* If we can detect process termination, don't consider the | 5168 | /* If we can detect process termination, don't consider the |
| 4918 | process gone just because its pipe is closed. */ | 5169 | process gone just because its pipe is closed. */ |
| 4919 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) | 5170 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc) |
| 5171 | && !PIPECONN_P (proc)) | ||
| 4920 | ; | 5172 | ; |
| 5173 | else if (nread == 0 && PIPECONN_P (proc)) | ||
| 5174 | { | ||
| 5175 | /* Preserve status of processes already terminated. */ | ||
| 5176 | XPROCESS (proc)->tick = ++process_tick; | ||
| 5177 | deactivate_process (proc); | ||
| 5178 | if (EQ (XPROCESS (proc)->status, Qrun)) | ||
| 5179 | pset_status (XPROCESS (proc), | ||
| 5180 | list2 (Qexit, make_number (0))); | ||
| 5181 | } | ||
| 4921 | else | 5182 | else |
| 4922 | { | 5183 | { |
| 4923 | /* Preserve status of processes already terminated. */ | 5184 | /* Preserve status of processes already terminated. */ |
| @@ -5954,7 +6215,8 @@ If PROCESS is a network or serial process, inhibit handling of incoming | |||
| 5954 | traffic. */) | 6215 | traffic. */) |
| 5955 | (Lisp_Object process, Lisp_Object current_group) | 6216 | (Lisp_Object process, Lisp_Object current_group) |
| 5956 | { | 6217 | { |
| 5957 | if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process))) | 6218 | if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process) |
| 6219 | || PIPECONN_P (process))) | ||
| 5958 | { | 6220 | { |
| 5959 | struct Lisp_Process *p; | 6221 | struct Lisp_Process *p; |
| 5960 | 6222 | ||
| @@ -5983,7 +6245,8 @@ If PROCESS is a network or serial process, resume handling of incoming | |||
| 5983 | traffic. */) | 6245 | traffic. */) |
| 5984 | (Lisp_Object process, Lisp_Object current_group) | 6246 | (Lisp_Object process, Lisp_Object current_group) |
| 5985 | { | 6247 | { |
| 5986 | if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process))) | 6248 | if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process) |
| 6249 | || PIPECONN_P (process))) | ||
| 5987 | { | 6250 | { |
| 5988 | struct Lisp_Process *p; | 6251 | struct Lisp_Process *p; |
| 5989 | 6252 | ||
| @@ -7030,7 +7293,7 @@ kill_buffer_processes (Lisp_Object buffer) | |||
| 7030 | FOR_EACH_PROCESS (tail, proc) | 7293 | FOR_EACH_PROCESS (tail, proc) |
| 7031 | if (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)) | 7294 | if (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)) |
| 7032 | { | 7295 | { |
| 7033 | if (NETCONN_P (proc) || SERIALCONN_P (proc)) | 7296 | if (NETCONN_P (proc) || SERIALCONN_P (proc) || PIPECONN_P (proc)) |
| 7034 | Fdelete_process (proc); | 7297 | Fdelete_process (proc); |
| 7035 | else if (XPROCESS (proc)->infd >= 0) | 7298 | else if (XPROCESS (proc)->infd >= 0) |
| 7036 | process_send_signal (proc, SIGHUP, Qnil, 1); | 7299 | process_send_signal (proc, SIGHUP, Qnil, 1); |
| @@ -7330,6 +7593,7 @@ syms_of_process (void) | |||
| 7330 | DEFSYM (Qreal, "real"); | 7593 | DEFSYM (Qreal, "real"); |
| 7331 | DEFSYM (Qnetwork, "network"); | 7594 | DEFSYM (Qnetwork, "network"); |
| 7332 | DEFSYM (Qserial, "serial"); | 7595 | DEFSYM (Qserial, "serial"); |
| 7596 | DEFSYM (Qpipe, "pipe"); | ||
| 7333 | DEFSYM (QCbuffer, ":buffer"); | 7597 | DEFSYM (QCbuffer, ":buffer"); |
| 7334 | DEFSYM (QChost, ":host"); | 7598 | DEFSYM (QChost, ":host"); |
| 7335 | DEFSYM (QCservice, ":service"); | 7599 | DEFSYM (QCservice, ":service"); |
| @@ -7346,6 +7610,7 @@ syms_of_process (void) | |||
| 7346 | DEFSYM (QCplist, ":plist"); | 7610 | DEFSYM (QCplist, ":plist"); |
| 7347 | DEFSYM (QCcommand, ":command"); | 7611 | DEFSYM (QCcommand, ":command"); |
| 7348 | DEFSYM (QCconnection_type, ":connection-type"); | 7612 | DEFSYM (QCconnection_type, ":connection-type"); |
| 7613 | DEFSYM (QCstderr, ":stderr"); | ||
| 7349 | DEFSYM (Qpty, "pty"); | 7614 | DEFSYM (Qpty, "pty"); |
| 7350 | DEFSYM (Qpipe, "pipe"); | 7615 | DEFSYM (Qpipe, "pipe"); |
| 7351 | 7616 | ||
| @@ -7451,6 +7716,7 @@ The variable takes effect when `start-process' is called. */); | |||
| 7451 | defsubr (&Sset_process_plist); | 7716 | defsubr (&Sset_process_plist); |
| 7452 | defsubr (&Sprocess_list); | 7717 | defsubr (&Sprocess_list); |
| 7453 | defsubr (&Smake_process); | 7718 | defsubr (&Smake_process); |
| 7719 | defsubr (&Smake_pipe_process); | ||
| 7454 | defsubr (&Sserial_process_configure); | 7720 | defsubr (&Sserial_process_configure); |
| 7455 | defsubr (&Smake_serial_process); | 7721 | defsubr (&Smake_serial_process); |
| 7456 | defsubr (&Sset_network_process_option); | 7722 | defsubr (&Sset_network_process_option); |