diff options
| author | Jan D | 2015-04-26 13:55:01 +0200 |
|---|---|---|
| committer | Jan D | 2015-04-26 13:55:01 +0200 |
| commit | f92ac2e82ed199d6f25d2a59508e08addb1150ac (patch) | |
| tree | d7d7756e3dbce10d8f73c27815d815499f78c2bd /src/process.c | |
| parent | 5a094119ce79723108abd90a1fcc33721e964823 (diff) | |
| parent | a40869789fc5502e3d4e393b7c31d78cb7f29aa1 (diff) | |
| download | emacs-f92ac2e82ed199d6f25d2a59508e08addb1150ac.tar.gz emacs-f92ac2e82ed199d6f25d2a59508e08addb1150ac.zip | |
Merge branch 'master' into cairo
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 406 |
1 files changed, 338 insertions, 68 deletions
diff --git a/src/process.c b/src/process.c index 2800fa58340..3e04cb76387 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 end of the pipe) | ||
| 1224 | if the pipe process is useful for purposes other 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 |
| @@ -1444,8 +1483,8 @@ usage: (make-process &rest ARGS) */) | |||
| 1444 | pset_plist (XPROCESS (proc), Qnil); | 1483 | pset_plist (XPROCESS (proc), Qnil); |
| 1445 | pset_type (XPROCESS (proc), Qreal); | 1484 | pset_type (XPROCESS (proc), Qreal); |
| 1446 | pset_buffer (XPROCESS (proc), buffer); | 1485 | pset_buffer (XPROCESS (proc), buffer); |
| 1447 | pset_sentinel (XPROCESS (proc), Qinternal_default_process_sentinel); | 1486 | pset_sentinel (XPROCESS (proc), Fplist_get (contact, QCsentinel)); |
| 1448 | pset_filter (XPROCESS (proc), Qinternal_default_process_filter); | 1487 | pset_filter (XPROCESS (proc), Fplist_get (contact, QCfilter)); |
| 1449 | pset_command (XPROCESS (proc), Fcopy_sequence (command)); | 1488 | pset_command (XPROCESS (proc), Fcopy_sequence (command)); |
| 1450 | 1489 | ||
| 1451 | if (tem = Fplist_get (contact, QCnoquery), !NILP (tem)) | 1490 | if (tem = Fplist_get (contact, QCnoquery), !NILP (tem)) |
| @@ -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; |
| @@ -1708,7 +1754,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1708 | int inchannel, outchannel; | 1754 | int inchannel, outchannel; |
| 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,17 @@ 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 | |||
| 1802 | /* Close unnecessary file descriptors. */ | ||
| 1803 | close_process_fd (&pp->open_fd[WRITE_TO_SUBPROCESS]); | ||
| 1804 | close_process_fd (&pp->open_fd[SUBPROCESS_STDIN]); | ||
| 1805 | } | ||
| 1749 | } | 1806 | } |
| 1750 | 1807 | ||
| 1751 | #ifndef WINDOWSNT | 1808 | #ifndef WINDOWSNT |
| @@ -1792,6 +1849,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1792 | char **volatile new_argv_volatile = new_argv; | 1849 | char **volatile new_argv_volatile = new_argv; |
| 1793 | int volatile forkin_volatile = forkin; | 1850 | int volatile forkin_volatile = forkin; |
| 1794 | int volatile forkout_volatile = forkout; | 1851 | int volatile forkout_volatile = forkout; |
| 1852 | int volatile forkerr_volatile = forkerr; | ||
| 1795 | struct Lisp_Process *p_volatile = p; | 1853 | struct Lisp_Process *p_volatile = p; |
| 1796 | 1854 | ||
| 1797 | pid = vfork (); | 1855 | pid = vfork (); |
| @@ -1801,6 +1859,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1801 | new_argv = new_argv_volatile; | 1859 | new_argv = new_argv_volatile; |
| 1802 | forkin = forkin_volatile; | 1860 | forkin = forkin_volatile; |
| 1803 | forkout = forkout_volatile; | 1861 | forkout = forkout_volatile; |
| 1862 | forkerr = forkerr_volatile; | ||
| 1804 | p = p_volatile; | 1863 | p = p_volatile; |
| 1805 | 1864 | ||
| 1806 | pty_flag = p->pty_flag; | 1865 | pty_flag = p->pty_flag; |
| @@ -1811,6 +1870,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1811 | { | 1870 | { |
| 1812 | int xforkin = forkin; | 1871 | int xforkin = forkin; |
| 1813 | int xforkout = forkout; | 1872 | int xforkout = forkout; |
| 1873 | int xforkerr = forkerr; | ||
| 1814 | 1874 | ||
| 1815 | /* Make the pty be the controlling terminal of the process. */ | 1875 | /* Make the pty be the controlling terminal of the process. */ |
| 1816 | #ifdef HAVE_PTYS | 1876 | #ifdef HAVE_PTYS |
| @@ -1910,10 +1970,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1910 | 1970 | ||
| 1911 | if (pty_flag) | 1971 | if (pty_flag) |
| 1912 | child_setup_tty (xforkout); | 1972 | child_setup_tty (xforkout); |
| 1973 | |||
| 1974 | if (xforkerr < 0) | ||
| 1975 | xforkerr = xforkout; | ||
| 1913 | #ifdef WINDOWSNT | 1976 | #ifdef WINDOWSNT |
| 1914 | pid = child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); | 1977 | pid = child_setup (xforkin, xforkout, xforkerr, new_argv, 1, current_dir); |
| 1915 | #else /* not WINDOWSNT */ | 1978 | #else /* not WINDOWSNT */ |
| 1916 | child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); | 1979 | child_setup (xforkin, xforkout, xforkerr, new_argv, 1, current_dir); |
| 1917 | #endif /* not WINDOWSNT */ | 1980 | #endif /* not WINDOWSNT */ |
| 1918 | } | 1981 | } |
| 1919 | 1982 | ||
| @@ -1958,6 +2021,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1958 | close_process_fd (&p->open_fd[READ_FROM_EXEC_MONITOR]); | 2021 | close_process_fd (&p->open_fd[READ_FROM_EXEC_MONITOR]); |
| 1959 | } | 2022 | } |
| 1960 | #endif | 2023 | #endif |
| 2024 | if (!NILP (p->stderrproc)) | ||
| 2025 | { | ||
| 2026 | struct Lisp_Process *pp = XPROCESS (p->stderrproc); | ||
| 2027 | close_process_fd (&pp->open_fd[SUBPROCESS_STDOUT]); | ||
| 2028 | } | ||
| 1961 | } | 2029 | } |
| 1962 | } | 2030 | } |
| 1963 | 2031 | ||
| @@ -2016,6 +2084,187 @@ create_pty (Lisp_Object process) | |||
| 2016 | p->pid = -2; | 2084 | p->pid = -2; |
| 2017 | } | 2085 | } |
| 2018 | 2086 | ||
| 2087 | DEFUN ("make-pipe-process", Fmake_pipe_process, Smake_pipe_process, | ||
| 2088 | 0, MANY, 0, | ||
| 2089 | doc: /* Create and return a bidirectional pipe process. | ||
| 2090 | |||
| 2091 | In Emacs, pipes are represented by process objects, so input and | ||
| 2092 | output work as for subprocesses, and `delete-process' closes a pipe. | ||
| 2093 | However, a pipe process has no process id, it cannot be signaled, | ||
| 2094 | and the status codes are different from normal processes. | ||
| 2095 | |||
| 2096 | Arguments are specified as keyword/argument pairs. The following | ||
| 2097 | arguments are defined: | ||
| 2098 | |||
| 2099 | :name NAME -- NAME is the name of the process. It is modified if necessary to make it unique. | ||
| 2100 | |||
| 2101 | :buffer BUFFER -- BUFFER is the buffer (or buffer-name) to associate | ||
| 2102 | with the process. Process output goes at the end of that buffer, | ||
| 2103 | unless you specify an output stream or filter function to handle the | ||
| 2104 | output. If BUFFER is not given, the value of NAME is used. | ||
| 2105 | |||
| 2106 | :coding CODING -- If CODING is a symbol, it specifies the coding | ||
| 2107 | system used for both reading and writing for this process. If CODING | ||
| 2108 | is a cons (DECODING . ENCODING), DECODING is used for reading, and | ||
| 2109 | ENCODING is used for writing. | ||
| 2110 | |||
| 2111 | :noquery BOOL -- When exiting Emacs, query the user if BOOL is nil and | ||
| 2112 | the process is running. If BOOL is not given, query before exiting. | ||
| 2113 | |||
| 2114 | :stop BOOL -- Start process in the `stopped' state if BOOL non-nil. | ||
| 2115 | In the stopped state, a pipe process does not accept incoming data, | ||
| 2116 | but you can send outgoing data. The stopped state is cleared by | ||
| 2117 | `continue-process' and set by `stop-process'. | ||
| 2118 | |||
| 2119 | :filter FILTER -- Install FILTER as the process filter. | ||
| 2120 | |||
| 2121 | :sentinel SENTINEL -- Install SENTINEL as the process sentinel. | ||
| 2122 | |||
| 2123 | usage: (make-pipe-process &rest ARGS) */) | ||
| 2124 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 2125 | { | ||
| 2126 | Lisp_Object proc, contact; | ||
| 2127 | struct Lisp_Process *p; | ||
| 2128 | struct gcpro gcpro1; | ||
| 2129 | Lisp_Object name, buffer; | ||
| 2130 | Lisp_Object tem; | ||
| 2131 | ptrdiff_t specpdl_count; | ||
| 2132 | int inchannel, outchannel; | ||
| 2133 | |||
| 2134 | if (nargs == 0) | ||
| 2135 | return Qnil; | ||
| 2136 | |||
| 2137 | contact = Flist (nargs, args); | ||
| 2138 | GCPRO1 (contact); | ||
| 2139 | |||
| 2140 | name = Fplist_get (contact, QCname); | ||
| 2141 | CHECK_STRING (name); | ||
| 2142 | proc = make_process (name); | ||
| 2143 | specpdl_count = SPECPDL_INDEX (); | ||
| 2144 | record_unwind_protect (remove_process, proc); | ||
| 2145 | p = XPROCESS (proc); | ||
| 2146 | |||
| 2147 | if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0 | ||
| 2148 | || emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0) | ||
| 2149 | report_file_error ("Creating pipe", Qnil); | ||
| 2150 | outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; | ||
| 2151 | inchannel = p->open_fd[READ_FROM_SUBPROCESS]; | ||
| 2152 | |||
| 2153 | fcntl (inchannel, F_SETFL, O_NONBLOCK); | ||
| 2154 | fcntl (outchannel, F_SETFL, O_NONBLOCK); | ||
| 2155 | |||
| 2156 | #ifdef WINDOWSNT | ||
| 2157 | register_aux_fd (inchannel); | ||
| 2158 | #endif | ||
| 2159 | |||
| 2160 | /* Record this as an active process, with its channels. */ | ||
| 2161 | chan_process[inchannel] = proc; | ||
| 2162 | p->infd = inchannel; | ||
| 2163 | p->outfd = outchannel; | ||
| 2164 | |||
| 2165 | if (inchannel > max_process_desc) | ||
| 2166 | max_process_desc = inchannel; | ||
| 2167 | |||
| 2168 | buffer = Fplist_get (contact, QCbuffer); | ||
| 2169 | if (NILP (buffer)) | ||
| 2170 | buffer = name; | ||
| 2171 | buffer = Fget_buffer_create (buffer); | ||
| 2172 | pset_buffer (p, buffer); | ||
| 2173 | |||
| 2174 | pset_childp (p, contact); | ||
| 2175 | pset_plist (p, Fcopy_sequence (Fplist_get (contact, QCplist))); | ||
| 2176 | pset_type (p, Qpipe); | ||
| 2177 | pset_sentinel (p, Fplist_get (contact, QCsentinel)); | ||
| 2178 | pset_filter (p, Fplist_get (contact, QCfilter)); | ||
| 2179 | pset_log (p, Qnil); | ||
| 2180 | if (tem = Fplist_get (contact, QCnoquery), !NILP (tem)) | ||
| 2181 | p->kill_without_query = 1; | ||
| 2182 | if (tem = Fplist_get (contact, QCstop), !NILP (tem)) | ||
| 2183 | pset_command (p, Qt); | ||
| 2184 | eassert (! p->pty_flag); | ||
| 2185 | |||
| 2186 | if (!EQ (p->command, Qt)) | ||
| 2187 | { | ||
| 2188 | FD_SET (inchannel, &input_wait_mask); | ||
| 2189 | FD_SET (inchannel, &non_keyboard_wait_mask); | ||
| 2190 | } | ||
| 2191 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 2192 | p->adaptive_read_buffering | ||
| 2193 | = (NILP (Vprocess_adaptive_read_buffering) ? 0 | ||
| 2194 | : EQ (Vprocess_adaptive_read_buffering, Qt) ? 1 : 2); | ||
| 2195 | #endif | ||
| 2196 | |||
| 2197 | /* Make the process marker point into the process buffer (if any). */ | ||
| 2198 | if (BUFFERP (buffer)) | ||
| 2199 | set_marker_both (p->mark, buffer, | ||
| 2200 | BUF_ZV (XBUFFER (buffer)), | ||
| 2201 | BUF_ZV_BYTE (XBUFFER (buffer))); | ||
| 2202 | |||
| 2203 | { | ||
| 2204 | /* Setup coding systems for communicating with the network stream. */ | ||
| 2205 | |||
| 2206 | /* Qt denotes we have not yet called Ffind_operation_coding_system. */ | ||
| 2207 | Lisp_Object coding_systems = Qt; | ||
| 2208 | Lisp_Object val; | ||
| 2209 | |||
| 2210 | tem = Fplist_get (contact, QCcoding); | ||
| 2211 | val = Qnil; | ||
| 2212 | if (!NILP (tem)) | ||
| 2213 | { | ||
| 2214 | val = tem; | ||
| 2215 | if (CONSP (val)) | ||
| 2216 | val = XCAR (val); | ||
| 2217 | } | ||
| 2218 | else if (!NILP (Vcoding_system_for_read)) | ||
| 2219 | val = Vcoding_system_for_read; | ||
| 2220 | else if ((!NILP (buffer) && NILP (BVAR (XBUFFER (buffer), enable_multibyte_characters))) | ||
| 2221 | || (NILP (buffer) && NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))) | ||
| 2222 | /* We dare not decode end-of-line format by setting VAL to | ||
| 2223 | Qraw_text, because the existing Emacs Lisp libraries | ||
| 2224 | assume that they receive bare code including a sequence of | ||
| 2225 | CR LF. */ | ||
| 2226 | val = Qnil; | ||
| 2227 | else | ||
| 2228 | { | ||
| 2229 | if (CONSP (coding_systems)) | ||
| 2230 | val = XCAR (coding_systems); | ||
| 2231 | else if (CONSP (Vdefault_process_coding_system)) | ||
| 2232 | val = XCAR (Vdefault_process_coding_system); | ||
| 2233 | else | ||
| 2234 | val = Qnil; | ||
| 2235 | } | ||
| 2236 | pset_decode_coding_system (p, val); | ||
| 2237 | |||
| 2238 | if (!NILP (tem)) | ||
| 2239 | { | ||
| 2240 | val = tem; | ||
| 2241 | if (CONSP (val)) | ||
| 2242 | val = XCDR (val); | ||
| 2243 | } | ||
| 2244 | else if (!NILP (Vcoding_system_for_write)) | ||
| 2245 | val = Vcoding_system_for_write; | ||
| 2246 | else if (NILP (BVAR (current_buffer, enable_multibyte_characters))) | ||
| 2247 | val = Qnil; | ||
| 2248 | else | ||
| 2249 | { | ||
| 2250 | if (CONSP (coding_systems)) | ||
| 2251 | val = XCDR (coding_systems); | ||
| 2252 | else if (CONSP (Vdefault_process_coding_system)) | ||
| 2253 | val = XCDR (Vdefault_process_coding_system); | ||
| 2254 | else | ||
| 2255 | val = Qnil; | ||
| 2256 | } | ||
| 2257 | pset_encode_coding_system (p, val); | ||
| 2258 | } | ||
| 2259 | /* This may signal an error. */ | ||
| 2260 | setup_process_coding_systems (proc); | ||
| 2261 | |||
| 2262 | specpdl_ptr = specpdl + specpdl_count; | ||
| 2263 | |||
| 2264 | UNGCPRO; | ||
| 2265 | return proc; | ||
| 2266 | } | ||
| 2267 | |||
| 2019 | 2268 | ||
| 2020 | /* Convert an internal struct sockaddr to a lisp object (vector or string). | 2269 | /* Convert an internal struct sockaddr to a lisp object (vector or string). |
| 2021 | The address family of sa is not included in the result. */ | 2270 | The address family of sa is not included in the result. */ |
| @@ -4536,37 +4785,41 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4536 | if (wait_proc && wait_proc->raw_status_new) | 4785 | if (wait_proc && wait_proc->raw_status_new) |
| 4537 | update_status (wait_proc); | 4786 | update_status (wait_proc); |
| 4538 | if (wait_proc | 4787 | if (wait_proc |
| 4539 | && wait_proc->infd >= 0 | ||
| 4540 | && ! EQ (wait_proc->status, Qrun) | 4788 | && ! EQ (wait_proc->status, Qrun) |
| 4541 | && ! EQ (wait_proc->status, Qconnect)) | 4789 | && ! EQ (wait_proc->status, Qconnect)) |
| 4542 | { | 4790 | { |
| 4543 | bool read_some_bytes = false; | 4791 | bool read_some_bytes = false; |
| 4544 | 4792 | ||
| 4545 | clear_waiting_for_input (); | 4793 | clear_waiting_for_input (); |
| 4546 | XSETPROCESS (proc, wait_proc); | ||
| 4547 | 4794 | ||
| 4548 | /* Read data from the process, until we exhaust it. */ | 4795 | /* If data can be read from the process, do so until exhausted. */ |
| 4549 | while (true) | 4796 | if (wait_proc->infd >= 0) |
| 4550 | { | 4797 | { |
| 4551 | int nread = read_process_output (proc, wait_proc->infd); | 4798 | XSETPROCESS (proc, wait_proc); |
| 4552 | if (nread < 0) | 4799 | |
| 4800 | while (true) | ||
| 4553 | { | 4801 | { |
| 4554 | if (errno == EIO || errno == EAGAIN) | 4802 | int nread = read_process_output (proc, wait_proc->infd); |
| 4555 | break; | 4803 | if (nread < 0) |
| 4804 | { | ||
| 4805 | if (errno == EIO || errno == EAGAIN) | ||
| 4806 | break; | ||
| 4556 | #ifdef EWOULDBLOCK | 4807 | #ifdef EWOULDBLOCK |
| 4557 | if (errno == EWOULDBLOCK) | 4808 | if (errno == EWOULDBLOCK) |
| 4558 | break; | 4809 | break; |
| 4559 | #endif | 4810 | #endif |
| 4560 | } | 4811 | } |
| 4561 | else | 4812 | else |
| 4562 | { | 4813 | { |
| 4563 | if (got_some_input < nread) | 4814 | if (got_some_input < nread) |
| 4564 | got_some_input = nread; | 4815 | got_some_input = nread; |
| 4565 | if (nread == 0) | 4816 | if (nread == 0) |
| 4566 | break; | 4817 | break; |
| 4567 | read_some_bytes = true; | 4818 | read_some_bytes = true; |
| 4819 | } | ||
| 4568 | } | 4820 | } |
| 4569 | } | 4821 | } |
| 4822 | |||
| 4570 | if (read_some_bytes && do_display) | 4823 | if (read_some_bytes && do_display) |
| 4571 | redisplay_preserve_echo_area (10); | 4824 | redisplay_preserve_echo_area (10); |
| 4572 | 4825 | ||
| @@ -4884,7 +5137,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4884 | available now and a closed pipe. | 5137 | available now and a closed pipe. |
| 4885 | With luck, a closed pipe will be accompanied by | 5138 | With luck, a closed pipe will be accompanied by |
| 4886 | subprocess termination and SIGCHLD. */ | 5139 | subprocess termination and SIGCHLD. */ |
| 4887 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) | 5140 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc) |
| 5141 | && !PIPECONN_P (proc)) | ||
| 4888 | ; | 5142 | ; |
| 4889 | #endif | 5143 | #endif |
| 4890 | #ifdef HAVE_PTYS | 5144 | #ifdef HAVE_PTYS |
| @@ -4916,8 +5170,18 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4916 | #endif /* HAVE_PTYS */ | 5170 | #endif /* HAVE_PTYS */ |
| 4917 | /* If we can detect process termination, don't consider the | 5171 | /* If we can detect process termination, don't consider the |
| 4918 | process gone just because its pipe is closed. */ | 5172 | process gone just because its pipe is closed. */ |
| 4919 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) | 5173 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc) |
| 5174 | && !PIPECONN_P (proc)) | ||
| 4920 | ; | 5175 | ; |
| 5176 | else if (nread == 0 && PIPECONN_P (proc)) | ||
| 5177 | { | ||
| 5178 | /* Preserve status of processes already terminated. */ | ||
| 5179 | XPROCESS (proc)->tick = ++process_tick; | ||
| 5180 | deactivate_process (proc); | ||
| 5181 | if (EQ (XPROCESS (proc)->status, Qrun)) | ||
| 5182 | pset_status (XPROCESS (proc), | ||
| 5183 | list2 (Qexit, make_number (0))); | ||
| 5184 | } | ||
| 4921 | else | 5185 | else |
| 4922 | { | 5186 | { |
| 4923 | /* Preserve status of processes already terminated. */ | 5187 | /* Preserve status of processes already terminated. */ |
| @@ -5954,7 +6218,8 @@ If PROCESS is a network or serial process, inhibit handling of incoming | |||
| 5954 | traffic. */) | 6218 | traffic. */) |
| 5955 | (Lisp_Object process, Lisp_Object current_group) | 6219 | (Lisp_Object process, Lisp_Object current_group) |
| 5956 | { | 6220 | { |
| 5957 | if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process))) | 6221 | if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process) |
| 6222 | || PIPECONN_P (process))) | ||
| 5958 | { | 6223 | { |
| 5959 | struct Lisp_Process *p; | 6224 | struct Lisp_Process *p; |
| 5960 | 6225 | ||
| @@ -5983,7 +6248,8 @@ If PROCESS is a network or serial process, resume handling of incoming | |||
| 5983 | traffic. */) | 6248 | traffic. */) |
| 5984 | (Lisp_Object process, Lisp_Object current_group) | 6249 | (Lisp_Object process, Lisp_Object current_group) |
| 5985 | { | 6250 | { |
| 5986 | if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process))) | 6251 | if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process) |
| 6252 | || PIPECONN_P (process))) | ||
| 5987 | { | 6253 | { |
| 5988 | struct Lisp_Process *p; | 6254 | struct Lisp_Process *p; |
| 5989 | 6255 | ||
| @@ -7030,7 +7296,7 @@ kill_buffer_processes (Lisp_Object buffer) | |||
| 7030 | FOR_EACH_PROCESS (tail, proc) | 7296 | FOR_EACH_PROCESS (tail, proc) |
| 7031 | if (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)) | 7297 | if (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)) |
| 7032 | { | 7298 | { |
| 7033 | if (NETCONN_P (proc) || SERIALCONN_P (proc)) | 7299 | if (NETCONN_P (proc) || SERIALCONN_P (proc) || PIPECONN_P (proc)) |
| 7034 | Fdelete_process (proc); | 7300 | Fdelete_process (proc); |
| 7035 | else if (XPROCESS (proc)->infd >= 0) | 7301 | else if (XPROCESS (proc)->infd >= 0) |
| 7036 | process_send_signal (proc, SIGHUP, Qnil, 1); | 7302 | process_send_signal (proc, SIGHUP, Qnil, 1); |
| @@ -7236,40 +7502,6 @@ init_process_emacs (void) | |||
| 7236 | memset (datagram_address, 0, sizeof datagram_address); | 7502 | memset (datagram_address, 0, sizeof datagram_address); |
| 7237 | #endif | 7503 | #endif |
| 7238 | 7504 | ||
| 7239 | { | ||
| 7240 | Lisp_Object subfeatures = Qnil; | ||
| 7241 | const struct socket_options *sopt; | ||
| 7242 | |||
| 7243 | #define ADD_SUBFEATURE(key, val) \ | ||
| 7244 | subfeatures = pure_cons (pure_cons (key, pure_cons (val, Qnil)), subfeatures) | ||
| 7245 | |||
| 7246 | #ifdef NON_BLOCKING_CONNECT | ||
| 7247 | ADD_SUBFEATURE (QCnowait, Qt); | ||
| 7248 | #endif | ||
| 7249 | #ifdef DATAGRAM_SOCKETS | ||
| 7250 | ADD_SUBFEATURE (QCtype, Qdatagram); | ||
| 7251 | #endif | ||
| 7252 | #ifdef HAVE_SEQPACKET | ||
| 7253 | ADD_SUBFEATURE (QCtype, Qseqpacket); | ||
| 7254 | #endif | ||
| 7255 | #ifdef HAVE_LOCAL_SOCKETS | ||
| 7256 | ADD_SUBFEATURE (QCfamily, Qlocal); | ||
| 7257 | #endif | ||
| 7258 | ADD_SUBFEATURE (QCfamily, Qipv4); | ||
| 7259 | #ifdef AF_INET6 | ||
| 7260 | ADD_SUBFEATURE (QCfamily, Qipv6); | ||
| 7261 | #endif | ||
| 7262 | #ifdef HAVE_GETSOCKNAME | ||
| 7263 | ADD_SUBFEATURE (QCservice, Qt); | ||
| 7264 | #endif | ||
| 7265 | ADD_SUBFEATURE (QCserver, Qt); | ||
| 7266 | |||
| 7267 | for (sopt = socket_options; sopt->name; sopt++) | ||
| 7268 | subfeatures = pure_cons (intern_c_string (sopt->name), subfeatures); | ||
| 7269 | |||
| 7270 | Fprovide (intern_c_string ("make-network-process"), subfeatures); | ||
| 7271 | } | ||
| 7272 | |||
| 7273 | #if defined (DARWIN_OS) | 7505 | #if defined (DARWIN_OS) |
| 7274 | /* PTYs are broken on Darwin < 6, but are sometimes useful for interactive | 7506 | /* PTYs are broken on Darwin < 6, but are sometimes useful for interactive |
| 7275 | processes. As such, we only change the default value. */ | 7507 | processes. As such, we only change the default value. */ |
| @@ -7330,6 +7562,7 @@ syms_of_process (void) | |||
| 7330 | DEFSYM (Qreal, "real"); | 7562 | DEFSYM (Qreal, "real"); |
| 7331 | DEFSYM (Qnetwork, "network"); | 7563 | DEFSYM (Qnetwork, "network"); |
| 7332 | DEFSYM (Qserial, "serial"); | 7564 | DEFSYM (Qserial, "serial"); |
| 7565 | DEFSYM (Qpipe, "pipe"); | ||
| 7333 | DEFSYM (QCbuffer, ":buffer"); | 7566 | DEFSYM (QCbuffer, ":buffer"); |
| 7334 | DEFSYM (QChost, ":host"); | 7567 | DEFSYM (QChost, ":host"); |
| 7335 | DEFSYM (QCservice, ":service"); | 7568 | DEFSYM (QCservice, ":service"); |
| @@ -7346,6 +7579,7 @@ syms_of_process (void) | |||
| 7346 | DEFSYM (QCplist, ":plist"); | 7579 | DEFSYM (QCplist, ":plist"); |
| 7347 | DEFSYM (QCcommand, ":command"); | 7580 | DEFSYM (QCcommand, ":command"); |
| 7348 | DEFSYM (QCconnection_type, ":connection-type"); | 7581 | DEFSYM (QCconnection_type, ":connection-type"); |
| 7582 | DEFSYM (QCstderr, ":stderr"); | ||
| 7349 | DEFSYM (Qpty, "pty"); | 7583 | DEFSYM (Qpty, "pty"); |
| 7350 | DEFSYM (Qpipe, "pipe"); | 7584 | DEFSYM (Qpipe, "pipe"); |
| 7351 | 7585 | ||
| @@ -7451,6 +7685,7 @@ The variable takes effect when `start-process' is called. */); | |||
| 7451 | defsubr (&Sset_process_plist); | 7685 | defsubr (&Sset_process_plist); |
| 7452 | defsubr (&Sprocess_list); | 7686 | defsubr (&Sprocess_list); |
| 7453 | defsubr (&Smake_process); | 7687 | defsubr (&Smake_process); |
| 7688 | defsubr (&Smake_pipe_process); | ||
| 7454 | defsubr (&Sserial_process_configure); | 7689 | defsubr (&Sserial_process_configure); |
| 7455 | defsubr (&Smake_serial_process); | 7690 | defsubr (&Smake_serial_process); |
| 7456 | defsubr (&Sset_network_process_option); | 7691 | defsubr (&Sset_network_process_option); |
| @@ -7488,4 +7723,39 @@ The variable takes effect when `start-process' is called. */); | |||
| 7488 | defsubr (&Sprocess_inherit_coding_system_flag); | 7723 | defsubr (&Sprocess_inherit_coding_system_flag); |
| 7489 | defsubr (&Slist_system_processes); | 7724 | defsubr (&Slist_system_processes); |
| 7490 | defsubr (&Sprocess_attributes); | 7725 | defsubr (&Sprocess_attributes); |
| 7726 | |||
| 7727 | { | ||
| 7728 | Lisp_Object subfeatures = Qnil; | ||
| 7729 | const struct socket_options *sopt; | ||
| 7730 | |||
| 7731 | #define ADD_SUBFEATURE(key, val) \ | ||
| 7732 | subfeatures = pure_cons (pure_cons (key, pure_cons (val, Qnil)), subfeatures) | ||
| 7733 | |||
| 7734 | #ifdef NON_BLOCKING_CONNECT | ||
| 7735 | ADD_SUBFEATURE (QCnowait, Qt); | ||
| 7736 | #endif | ||
| 7737 | #ifdef DATAGRAM_SOCKETS | ||
| 7738 | ADD_SUBFEATURE (QCtype, Qdatagram); | ||
| 7739 | #endif | ||
| 7740 | #ifdef HAVE_SEQPACKET | ||
| 7741 | ADD_SUBFEATURE (QCtype, Qseqpacket); | ||
| 7742 | #endif | ||
| 7743 | #ifdef HAVE_LOCAL_SOCKETS | ||
| 7744 | ADD_SUBFEATURE (QCfamily, Qlocal); | ||
| 7745 | #endif | ||
| 7746 | ADD_SUBFEATURE (QCfamily, Qipv4); | ||
| 7747 | #ifdef AF_INET6 | ||
| 7748 | ADD_SUBFEATURE (QCfamily, Qipv6); | ||
| 7749 | #endif | ||
| 7750 | #ifdef HAVE_GETSOCKNAME | ||
| 7751 | ADD_SUBFEATURE (QCservice, Qt); | ||
| 7752 | #endif | ||
| 7753 | ADD_SUBFEATURE (QCserver, Qt); | ||
| 7754 | |||
| 7755 | for (sopt = socket_options; sopt->name; sopt++) | ||
| 7756 | subfeatures = pure_cons (intern_c_string (sopt->name), subfeatures); | ||
| 7757 | |||
| 7758 | Fprovide (intern_c_string ("make-network-process"), subfeatures); | ||
| 7759 | } | ||
| 7760 | |||
| 7491 | } | 7761 | } |