diff options
| author | Richard M. Stallman | 1994-11-01 08:31:31 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-11-01 08:31:31 +0000 |
| commit | e98d950b325d0d123035613177685f9aaf2b487e (patch) | |
| tree | 2709a678154c46edbf739b2e7e5bc09a41b96bfd /src/process.c | |
| parent | 6cc1fc1d3da7d2d44e707226c5296926b4b0c5d7 (diff) | |
| download | emacs-e98d950b325d0d123035613177685f9aaf2b487e.tar.gz emacs-e98d950b325d0d123035613177685f9aaf2b487e.zip | |
Use macros IS_ANY_SEP, IS_DIRECTORY_SEP,
IS_DEVICE_SEP, DIRECTORY_SEP, and DEVICE_SEP.
[WINDOWSNT]: Add includes. Don't define sys_siglist.
(sigchld_handler): Work around bug in MS C compiler.
(sigchld_handler) [WINDOWSNT]: Do not call signal.
(signal_process) [WINDOWSNT]: Use win32_kill_process instead of kill.
(read_process_output) [WINDOWSNT]: Use read_child_output instead of
read.
(create_process) [WINDOWSNT]: Use
pipe_with_inherited_out and pipe_with_inherited_in.
Use the pid returned by child_setup. Deal with not having vfork,
Call register_child.
(close_process_descs): Do nothing if WINDOWSNT.
(proc_buffer_char): No longer static.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 69 |
1 files changed, 60 insertions, 9 deletions
diff --git a/src/process.c b/src/process.c index 8c59f626133..7ffe74ac821 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -42,6 +42,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 42 | #include <unistd.h> | 42 | #include <unistd.h> |
| 43 | #endif | 43 | #endif |
| 44 | 44 | ||
| 45 | #ifdef WINDOWSNT | ||
| 46 | #include <stdlib.h> | ||
| 47 | #include <fcntl.h> | ||
| 48 | #endif /* not WINDOWSNT */ | ||
| 49 | |||
| 45 | #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */ | 50 | #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */ |
| 46 | #include <sys/socket.h> | 51 | #include <sys/socket.h> |
| 47 | #include <netdb.h> | 52 | #include <netdb.h> |
| @@ -142,6 +147,7 @@ extern int h_errno; | |||
| 142 | #ifndef SYS_SIGLIST_DECLARED | 147 | #ifndef SYS_SIGLIST_DECLARED |
| 143 | #ifndef VMS | 148 | #ifndef VMS |
| 144 | #ifndef BSD4_1 | 149 | #ifndef BSD4_1 |
| 150 | #ifndef WINDOWSNT | ||
| 145 | #ifndef LINUX | 151 | #ifndef LINUX |
| 146 | extern char *sys_siglist[]; | 152 | extern char *sys_siglist[]; |
| 147 | #endif /* not LINUX */ | 153 | #endif /* not LINUX */ |
| @@ -175,6 +181,7 @@ char *sys_siglist[] = | |||
| 175 | "exceeded CPU time limit", | 181 | "exceeded CPU time limit", |
| 176 | "exceeded file size limit" | 182 | "exceeded file size limit" |
| 177 | }; | 183 | }; |
| 184 | #endif /* not WINDOWSNT */ | ||
| 178 | #endif | 185 | #endif |
| 179 | #endif /* VMS */ | 186 | #endif /* VMS */ |
| 180 | #endif /* ! SYS_SIGLIST_DECLARED */ | 187 | #endif /* ! SYS_SIGLIST_DECLARED */ |
| @@ -251,7 +258,8 @@ Lisp_Object Vprocess_alist; | |||
| 251 | output from the process is to read at least one char. | 258 | output from the process is to read at least one char. |
| 252 | Always -1 on systems that support FIONREAD. */ | 259 | Always -1 on systems that support FIONREAD. */ |
| 253 | 260 | ||
| 254 | static int proc_buffered_char[MAXDESC]; | 261 | /* Don't make static; need to access externally. */ |
| 262 | int proc_buffered_char[MAXDESC]; | ||
| 255 | 263 | ||
| 256 | static Lisp_Object get_process (); | 264 | static Lisp_Object get_process (); |
| 257 | 265 | ||
| @@ -1090,7 +1098,9 @@ Remaining arguments are strings to give program as arguments.") | |||
| 1090 | new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); | 1098 | new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); |
| 1091 | 1099 | ||
| 1092 | /* If program file name is not absolute, search our path for it */ | 1100 | /* If program file name is not absolute, search our path for it */ |
| 1093 | if (XSTRING (program)->data[0] != '/') | 1101 | if (!IS_DIRECTORY_SEP (XSTRING (program)->data[0]) |
| 1102 | && !(XSTRING (program)->size > 1 | ||
| 1103 | && IS_DEVICE_SEP (XSTRING (program)->data[1]))) | ||
| 1094 | { | 1104 | { |
| 1095 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 1105 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 1096 | 1106 | ||
| @@ -1232,12 +1242,22 @@ create_process (process, new_argv, current_dir) | |||
| 1232 | } | 1242 | } |
| 1233 | #else /* not SKTPAIR */ | 1243 | #else /* not SKTPAIR */ |
| 1234 | { | 1244 | { |
| 1245 | #ifdef WINDOWSNT | ||
| 1246 | pipe_with_inherited_out (sv); | ||
| 1247 | inchannel = sv[0]; | ||
| 1248 | forkout = sv[1]; | ||
| 1249 | |||
| 1250 | pipe_with_inherited_in (sv); | ||
| 1251 | forkin = sv[0]; | ||
| 1252 | outchannel = sv[1]; | ||
| 1253 | #else /* not WINDOWSNT */ | ||
| 1235 | pipe (sv); | 1254 | pipe (sv); |
| 1236 | inchannel = sv[0]; | 1255 | inchannel = sv[0]; |
| 1237 | forkout = sv[1]; | 1256 | forkout = sv[1]; |
| 1238 | pipe (sv); | 1257 | pipe (sv); |
| 1239 | outchannel = sv[1]; | 1258 | outchannel = sv[1]; |
| 1240 | forkin = sv[0]; | 1259 | forkin = sv[0]; |
| 1260 | #endif /* not WINDOWSNT */ | ||
| 1241 | } | 1261 | } |
| 1242 | #endif /* not SKTPAIR */ | 1262 | #endif /* not SKTPAIR */ |
| 1243 | 1263 | ||
| @@ -1312,8 +1332,10 @@ create_process (process, new_argv, current_dir) | |||
| 1312 | Protect it from permanent change. */ | 1332 | Protect it from permanent change. */ |
| 1313 | char **save_environ = environ; | 1333 | char **save_environ = environ; |
| 1314 | 1334 | ||
| 1335 | #ifndef WINDOWSNT | ||
| 1315 | pid = vfork (); | 1336 | pid = vfork (); |
| 1316 | if (pid == 0) | 1337 | if (pid == 0) |
| 1338 | #endif /* not WINDOWSNT */ | ||
| 1317 | { | 1339 | { |
| 1318 | int xforkin = forkin; | 1340 | int xforkin = forkin; |
| 1319 | int xforkout = forkout; | 1341 | int xforkout = forkout; |
| @@ -1444,8 +1466,13 @@ create_process (process, new_argv, current_dir) | |||
| 1444 | 1466 | ||
| 1445 | if (pty_flag) | 1467 | if (pty_flag) |
| 1446 | child_setup_tty (xforkout); | 1468 | child_setup_tty (xforkout); |
| 1469 | #ifdef WINDOWSNT | ||
| 1470 | pid = child_setup (xforkin, xforkout, xforkout, | ||
| 1471 | new_argv, 1, current_dir); | ||
| 1472 | #else /* not WINDOWSNT */ | ||
| 1447 | child_setup (xforkin, xforkout, xforkout, | 1473 | child_setup (xforkin, xforkout, xforkout, |
| 1448 | new_argv, 1, current_dir); | 1474 | new_argv, 1, current_dir); |
| 1475 | #endif /* not WINDOWSNT */ | ||
| 1449 | } | 1476 | } |
| 1450 | environ = save_environ; | 1477 | environ = save_environ; |
| 1451 | } | 1478 | } |
| @@ -1461,6 +1488,10 @@ create_process (process, new_argv, current_dir) | |||
| 1461 | 1488 | ||
| 1462 | XSETFASTINT (XPROCESS (process)->pid, pid); | 1489 | XSETFASTINT (XPROCESS (process)->pid, pid); |
| 1463 | 1490 | ||
| 1491 | #ifdef WINDOWSNT | ||
| 1492 | register_child (pid, inchannel); | ||
| 1493 | #endif /* WINDOWSNT */ | ||
| 1494 | |||
| 1464 | /* If the subfork execv fails, and it exits, | 1495 | /* If the subfork execv fails, and it exits, |
| 1465 | this close hangs. I don't know why. | 1496 | this close hangs. I don't know why. |
| 1466 | So have an interrupt jar it loose. */ | 1497 | So have an interrupt jar it loose. */ |
| @@ -1742,6 +1773,7 @@ deactivate_process (proc) | |||
| 1742 | 1773 | ||
| 1743 | close_process_descs () | 1774 | close_process_descs () |
| 1744 | { | 1775 | { |
| 1776 | #ifndef WINDOWSNT | ||
| 1745 | int i; | 1777 | int i; |
| 1746 | for (i = 0; i < MAXDESC; i++) | 1778 | for (i = 0; i < MAXDESC; i++) |
| 1747 | { | 1779 | { |
| @@ -1757,6 +1789,7 @@ close_process_descs () | |||
| 1757 | close (out); | 1789 | close (out); |
| 1758 | } | 1790 | } |
| 1759 | } | 1791 | } |
| 1792 | #endif | ||
| 1760 | } | 1793 | } |
| 1761 | 1794 | ||
| 1762 | DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output, | 1795 | DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output, |
| @@ -2277,12 +2310,20 @@ read_process_output (proc, channel) | |||
| 2277 | #else /* not VMS */ | 2310 | #else /* not VMS */ |
| 2278 | 2311 | ||
| 2279 | if (proc_buffered_char[channel] < 0) | 2312 | if (proc_buffered_char[channel] < 0) |
| 2313 | #ifdef WINDOWSNT | ||
| 2314 | nchars = read_child_output (channel, chars, sizeof (chars)); | ||
| 2315 | #else | ||
| 2280 | nchars = read (channel, chars, sizeof chars); | 2316 | nchars = read (channel, chars, sizeof chars); |
| 2317 | #endif | ||
| 2281 | else | 2318 | else |
| 2282 | { | 2319 | { |
| 2283 | chars[0] = proc_buffered_char[channel]; | 2320 | chars[0] = proc_buffered_char[channel]; |
| 2284 | proc_buffered_char[channel] = -1; | 2321 | proc_buffered_char[channel] = -1; |
| 2322 | #ifdef WINDOWSNT | ||
| 2323 | nchars = read_child_output (channel, chars + 1, sizeof (chars) - 1); | ||
| 2324 | #else | ||
| 2285 | nchars = read (channel, chars + 1, sizeof chars - 1); | 2325 | nchars = read (channel, chars + 1, sizeof chars - 1); |
| 2326 | #endif | ||
| 2286 | if (nchars < 0) | 2327 | if (nchars < 0) |
| 2287 | nchars = 1; | 2328 | nchars = 1; |
| 2288 | else | 2329 | else |
| @@ -2909,7 +2950,12 @@ Both PID and CODE are integers.") | |||
| 2909 | { | 2950 | { |
| 2910 | CHECK_NUMBER (pid, 0); | 2951 | CHECK_NUMBER (pid, 0); |
| 2911 | CHECK_NUMBER (sig, 1); | 2952 | CHECK_NUMBER (sig, 1); |
| 2953 | #ifdef WINDOWSNT | ||
| 2954 | /* Only works for kill-type signals */ | ||
| 2955 | return make_number (win32_kill_process (XINT (pid), XINT (sig))); | ||
| 2956 | #else | ||
| 2912 | return make_number (kill (XINT (pid), XINT (sig))); | 2957 | return make_number (kill (XINT (pid), XINT (sig))); |
| 2958 | #endif | ||
| 2913 | } | 2959 | } |
| 2914 | 2960 | ||
| 2915 | DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0, | 2961 | DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0, |
| @@ -3071,6 +3117,7 @@ sigchld_handler (signo) | |||
| 3071 | if (p != 0) | 3117 | if (p != 0) |
| 3072 | { | 3118 | { |
| 3073 | union { int i; WAITTYPE wt; } u; | 3119 | union { int i; WAITTYPE wt; } u; |
| 3120 | int clear_desc_flag = 0; | ||
| 3074 | 3121 | ||
| 3075 | XSETINT (p->tick, ++process_tick); | 3122 | XSETINT (p->tick, ++process_tick); |
| 3076 | u.wt = w; | 3123 | u.wt = w; |
| @@ -3078,12 +3125,16 @@ sigchld_handler (signo) | |||
| 3078 | XSETFASTINT (p->raw_status_high, u.i >> 16); | 3125 | XSETFASTINT (p->raw_status_high, u.i >> 16); |
| 3079 | 3126 | ||
| 3080 | /* If process has terminated, stop waiting for its output. */ | 3127 | /* If process has terminated, stop waiting for its output. */ |
| 3081 | if (WIFSIGNALED (w) || WIFEXITED (w)) | 3128 | if ((WIFSIGNALED (w) || WIFEXITED (w)) |
| 3082 | if (XINT (p->infd) >= 0) | 3129 | && XINT (p->infd) >= 0) |
| 3083 | { | 3130 | clear_desc_flag = 1; |
| 3084 | FD_CLR (XINT (p->infd), &input_wait_mask); | 3131 | |
| 3085 | FD_CLR (XINT (p->infd), &non_keyboard_wait_mask); | 3132 | /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ |
| 3086 | } | 3133 | if (clear_desc_flag) |
| 3134 | { | ||
| 3135 | FD_CLR (XINT (p->infd), &input_wait_mask); | ||
| 3136 | FD_CLR (XINT (p->infd), &non_keyboard_wait_mask); | ||
| 3137 | } | ||
| 3087 | 3138 | ||
| 3088 | /* Tell wait_reading_process_input that it needs to wake up and | 3139 | /* Tell wait_reading_process_input that it needs to wake up and |
| 3089 | look around. */ | 3140 | look around. */ |
| @@ -3131,7 +3182,7 @@ sigchld_handler (signo) | |||
| 3131 | get another signal. | 3182 | get another signal. |
| 3132 | Otherwise (on systems that have WNOHANG), loop around | 3183 | Otherwise (on systems that have WNOHANG), loop around |
| 3133 | to use up all the processes that have something to tell us. */ | 3184 | to use up all the processes that have something to tell us. */ |
| 3134 | #if defined (USG) && ! (defined (HPUX) && defined (WNOHANG)) | 3185 | #if defined (USG) && ! (defined (HPUX) && defined (WNOHANG)) || defined (WINDOWSNT) |
| 3135 | #ifdef USG | 3186 | #ifdef USG |
| 3136 | signal (signo, sigchld_handler); | 3187 | signal (signo, sigchld_handler); |
| 3137 | #endif | 3188 | #endif |