diff options
| author | Jim Blandy | 1992-11-16 00:53:26 +0000 |
|---|---|---|
| committer | Jim Blandy | 1992-11-16 00:53:26 +0000 |
| commit | b0310da46a84635eb11693f59fe456c40cb8dc39 (patch) | |
| tree | 41e3a2adee43d75f5dd49fd6cdbb865aabc49680 /src | |
| parent | 64a3a3c0b4ff590ca41431dd4287d234f4fd6349 (diff) | |
| download | emacs-b0310da46a84635eb11693f59fe456c40cb8dc39.tar.gz emacs-b0310da46a84635eb11693f59fe456c40cb8dc39.zip | |
* systty.h, process.c, buffer.h, callproc.c, sysdep.c, dired.c:
Added VMS changes from Roland Roberts.
* process.c (read_process_output): Save, widen, insert the process
output, and then restore the restriction if inserting text outside
the visible region.
* process.c (Fstart_process): Establish an unwind-protect to
remove PROC from the process list if an error occurs while
starting it.
(start_process_unwind): New function to help with that.
(create_process): There's no need to explicitly call
remove_process if the fork fails; the record_unwind_protect in
Fstart_process will take care of it.
* process.c (wait_reading_process_input): Test the C preprocessor
symbol "ultrix", not "__ultrix__" to see if we should ignore
ENOMEM errors from select.
* process.c (process_send_signal): On systems which have both
the TIOCGETC and TCGETA ioctls, just use the former.
* s/bsd4-2.h, s/bsd4-3.h: #define SIGNALS_VIA_CHARACTERS.
* process.c (process_send_signal): Put all the code for sending
signals via characters in a #ifdef SIGNALS_VIA_CHARACTERS. Decide
whether to use the Berkeley-style or SYSV-style ioctls by seeing
which ioctl commands are #defined.
* process.c (process_send_signal): Doc fix.
Diffstat (limited to 'src')
| -rw-r--r-- | src/process.c | 134 |
1 files changed, 107 insertions, 27 deletions
diff --git a/src/process.c b/src/process.c index 35a30540c02..4effac06ee4 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -162,7 +162,9 @@ static Lisp_Object stream_process; | |||
| 162 | 162 | ||
| 163 | /* For the CMU PTY driver + */ | 163 | /* For the CMU PTY driver + */ |
| 164 | #define DCL_PROMPT "$ " | 164 | #define DCL_PROMPT "$ " |
| 165 | 165 | /* This is a hack. I have no idea what needs to go here, but this */ | |
| 166 | /* will get it to compile. We can fix it later. rbr */ | ||
| 167 | #define WAITTYPE int | ||
| 166 | #include <ssdef.h> | 168 | #include <ssdef.h> |
| 167 | #include <iodef.h> | 169 | #include <iodef.h> |
| 168 | #include <clidef.h> | 170 | #include <clidef.h> |
| @@ -349,7 +351,11 @@ status_message (status) | |||
| 349 | 351 | ||
| 350 | if (EQ (symbol, Qsignal) || EQ (symbol, Qstop)) | 352 | if (EQ (symbol, Qsignal) || EQ (symbol, Qstop)) |
| 351 | { | 353 | { |
| 354 | #ifndef VMS | ||
| 352 | string = build_string (code < NSIG ? sys_siglist[code] : "unknown"); | 355 | string = build_string (code < NSIG ? sys_siglist[code] : "unknown"); |
| 356 | #else | ||
| 357 | string = build_string (code < NSIG ? sys_errlist[code] : "unknown"); | ||
| 358 | #endif | ||
| 353 | string2 = build_string (coredump ? " (core dumped)\n" : "\n"); | 359 | string2 = build_string (coredump ? " (core dumped)\n" : "\n"); |
| 354 | XSTRING (string)->data[0] = DOWNCASE (XSTRING (string)->data[0]); | 360 | XSTRING (string)->data[0] = DOWNCASE (XSTRING (string)->data[0]); |
| 355 | return concat2 (string, string2); | 361 | return concat2 (string, string2); |
| @@ -847,7 +853,7 @@ Proc Status Buffer Command\n\ | |||
| 847 | tem = Fcar (Fcdr (p->status)); | 853 | tem = Fcar (Fcdr (p->status)); |
| 848 | #ifdef VMS | 854 | #ifdef VMS |
| 849 | if (XINT (tem) < NSIG) | 855 | if (XINT (tem) < NSIG) |
| 850 | write_string (sys_siglist [XINT (tem)], -1); | 856 | write_string (sys_errlist [XINT (tem)], -1); |
| 851 | else | 857 | else |
| 852 | #endif | 858 | #endif |
| 853 | Fprinc (symbol, Qnil); | 859 | Fprinc (symbol, Qnil); |
| @@ -930,6 +936,10 @@ DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0, | |||
| 930 | return Fmapcar (Qcdr, Vprocess_alist); | 936 | return Fmapcar (Qcdr, Vprocess_alist); |
| 931 | } | 937 | } |
| 932 | 938 | ||
| 939 | /* Starting asynchronous inferior processes. */ | ||
| 940 | |||
| 941 | static Lisp_Object start_process_unwind (); | ||
| 942 | |||
| 933 | DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, | 943 | DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, |
| 934 | "Start a program in a subprocess. Return the process object for it.\n\ | 944 | "Start a program in a subprocess. Return the process object for it.\n\ |
| 935 | Args are NAME BUFFER PROGRAM &rest PROGRAM-ARGS\n\ | 945 | Args are NAME BUFFER PROGRAM &rest PROGRAM-ARGS\n\ |
| @@ -953,6 +963,7 @@ Remaining arguments are strings to give program as arguments.") | |||
| 953 | register unsigned char **new_argv; | 963 | register unsigned char **new_argv; |
| 954 | #endif | 964 | #endif |
| 955 | register int i; | 965 | register int i; |
| 966 | int count = specpdl_ptr - specpdl; | ||
| 956 | 967 | ||
| 957 | buffer = args[1]; | 968 | buffer = args[1]; |
| 958 | if (!NILP (buffer)) | 969 | if (!NILP (buffer)) |
| @@ -984,6 +995,8 @@ Remaining arguments are strings to give program as arguments.") | |||
| 984 | strcat (new_argv, " "); | 995 | strcat (new_argv, " "); |
| 985 | strcat (new_argv, XSTRING (tem)->data); | 996 | strcat (new_argv, XSTRING (tem)->data); |
| 986 | } | 997 | } |
| 998 | /* Need to add code here to check for program existence on VMS */ | ||
| 999 | |||
| 987 | #else /* not VMS */ | 1000 | #else /* not VMS */ |
| 988 | new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); | 1001 | new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); |
| 989 | 1002 | ||
| @@ -1008,6 +1021,11 @@ Remaining arguments are strings to give program as arguments.") | |||
| 1008 | #endif /* not VMS */ | 1021 | #endif /* not VMS */ |
| 1009 | 1022 | ||
| 1010 | proc = make_process (name); | 1023 | proc = make_process (name); |
| 1024 | /* If an error occurs and we can't start the process, we want to | ||
| 1025 | remove it from the process list. This means that each error | ||
| 1026 | check in create_process doesn't need to call remove_process | ||
| 1027 | itself; it's all taken care of here. */ | ||
| 1028 | record_unwind_protect (start_process_unwind, proc); | ||
| 1011 | 1029 | ||
| 1012 | XPROCESS (proc)->childp = Qt; | 1030 | XPROCESS (proc)->childp = Qt; |
| 1013 | XPROCESS (proc)->command_channel_p = Qnil; | 1031 | XPROCESS (proc)->command_channel_p = Qnil; |
| @@ -1018,9 +1036,28 @@ Remaining arguments are strings to give program as arguments.") | |||
| 1018 | 1036 | ||
| 1019 | create_process (proc, new_argv); | 1037 | create_process (proc, new_argv); |
| 1020 | 1038 | ||
| 1021 | return proc; | 1039 | return unbind_to (count, proc); |
| 1040 | } | ||
| 1041 | |||
| 1042 | /* This function is the unwind_protect form for Fstart_process. If | ||
| 1043 | PROC doesn't have its pid set, then we know someone has signalled | ||
| 1044 | an error and the process wasn't started successfully, so we should | ||
| 1045 | remove it from the process list. */ | ||
| 1046 | static Lisp_Object | ||
| 1047 | start_process_unwind (proc) | ||
| 1048 | Lisp_Object proc; | ||
| 1049 | { | ||
| 1050 | if (XTYPE (proc) != Lisp_Process) | ||
| 1051 | abort (); | ||
| 1052 | |||
| 1053 | /* Was PROC started successfully? */ | ||
| 1054 | if (XPROCESS (proc)->pid <= 0) | ||
| 1055 | remove_process (proc); | ||
| 1056 | |||
| 1057 | return Qnil; | ||
| 1022 | } | 1058 | } |
| 1023 | 1059 | ||
| 1060 | |||
| 1024 | SIGTYPE | 1061 | SIGTYPE |
| 1025 | create_process_1 (signo) | 1062 | create_process_1 (signo) |
| 1026 | int signo; | 1063 | int signo; |
| @@ -1282,11 +1319,8 @@ create_process (process, new_argv) | |||
| 1282 | } | 1319 | } |
| 1283 | 1320 | ||
| 1284 | if (pid < 0) | 1321 | if (pid < 0) |
| 1285 | { | 1322 | report_file_error ("Doing vfork", Qnil); |
| 1286 | remove_process (process); | 1323 | |
| 1287 | report_file_error ("Doing vfork", Qnil); | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | XFASTINT (XPROCESS (process)->pid) = pid; | 1324 | XFASTINT (XPROCESS (process)->pid) = pid; |
| 1291 | 1325 | ||
| 1292 | FD_SET (inchannel, &input_wait_mask); | 1326 | FD_SET (inchannel, &input_wait_mask); |
| @@ -1741,9 +1775,12 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) | |||
| 1741 | { | 1775 | { |
| 1742 | if (xerrno == EINTR) | 1776 | if (xerrno == EINTR) |
| 1743 | FD_ZERO (&Available); | 1777 | FD_ZERO (&Available); |
| 1744 | #ifdef __ultrix__ | 1778 | #ifdef ultrix |
| 1745 | /* Ultrix select seems to return ENOMEM when it is interrupted. | 1779 | /* Ultrix select seems to return ENOMEM when it is |
| 1746 | Treat it just like EINTR. Bleah. -JimB */ | 1780 | interrupted. Treat it just like EINTR. Bleah. Note |
| 1781 | that we want to test for the "ultrix" CPP symbol, not | ||
| 1782 | "__ultrix__"; the latter is only defined under GCC, but | ||
| 1783 | not by DEC's bundled CC. -JimB */ | ||
| 1747 | else if (xerrno == ENOMEM) | 1784 | else if (xerrno == ENOMEM) |
| 1748 | FD_ZERO (&Available); | 1785 | FD_ZERO (&Available); |
| 1749 | #endif | 1786 | #endif |
| @@ -2014,10 +2051,16 @@ read_process_output (proc, channel) | |||
| 2014 | /* If no filter, write into buffer if it isn't dead. */ | 2051 | /* If no filter, write into buffer if it isn't dead. */ |
| 2015 | if (!NILP (p->buffer) && !NILP (XBUFFER (p->buffer)->name)) | 2052 | if (!NILP (p->buffer) && !NILP (XBUFFER (p->buffer)->name)) |
| 2016 | { | 2053 | { |
| 2017 | Lisp_Object tem; | 2054 | Lisp_Object old_read_only; |
| 2055 | Lisp_Object old_begv, old_zv; | ||
| 2018 | 2056 | ||
| 2019 | Fset_buffer (p->buffer); | 2057 | Fset_buffer (p->buffer); |
| 2020 | opoint = point; | 2058 | opoint = point; |
| 2059 | old_read_only = current_buffer->read_only; | ||
| 2060 | XFASTINT (old_begv) = BEGV; | ||
| 2061 | XFASTINT (old_zv) = ZV; | ||
| 2062 | |||
| 2063 | current_buffer->read_only = Qnil; | ||
| 2021 | 2064 | ||
| 2022 | /* Insert new output into buffer | 2065 | /* Insert new output into buffer |
| 2023 | at the current end-of-output marker, | 2066 | at the current end-of-output marker, |
| @@ -2026,18 +2069,35 @@ read_process_output (proc, channel) | |||
| 2026 | SET_PT (marker_position (p->mark)); | 2069 | SET_PT (marker_position (p->mark)); |
| 2027 | else | 2070 | else |
| 2028 | SET_PT (ZV); | 2071 | SET_PT (ZV); |
| 2072 | |||
| 2073 | /* If the output marker is outside of the visible region, save | ||
| 2074 | the restriction and widen. */ | ||
| 2075 | if (! (BEGV <= point && point <= ZV)) | ||
| 2076 | Fwiden (); | ||
| 2077 | |||
| 2078 | /* Make sure opoint floats ahead of any new text, just as point | ||
| 2079 | would. */ | ||
| 2029 | if (point <= opoint) | 2080 | if (point <= opoint) |
| 2030 | opoint += nchars; | 2081 | opoint += nchars; |
| 2031 | 2082 | ||
| 2032 | tem = current_buffer->read_only; | 2083 | /* Insert after old_begv, but before old_zv. */ |
| 2033 | current_buffer->read_only = Qnil; | 2084 | if (point < XFASTINT (old_begv)) |
| 2085 | XFASTINT (old_begv) += nchars; | ||
| 2086 | if (point <= XFASTINT (old_zv)) | ||
| 2087 | XFASTINT (old_zv) += nchars; | ||
| 2088 | |||
| 2034 | /* Insert before markers in case we are inserting where | 2089 | /* Insert before markers in case we are inserting where |
| 2035 | the buffer's mark is, and the user's next command is Meta-y. */ | 2090 | the buffer's mark is, and the user's next command is Meta-y. */ |
| 2036 | insert_before_markers (chars, nchars); | 2091 | insert_before_markers (chars, nchars); |
| 2037 | current_buffer->read_only = tem; | ||
| 2038 | Fset_marker (p->mark, make_number (point), p->buffer); | 2092 | Fset_marker (p->mark, make_number (point), p->buffer); |
| 2093 | |||
| 2039 | update_mode_lines++; | 2094 | update_mode_lines++; |
| 2040 | 2095 | ||
| 2096 | /* If the restriction isn't what it should be, set it. */ | ||
| 2097 | if (XFASTINT (old_begv) != BEGV || XFASTINT (old_zv) != ZV) | ||
| 2098 | Fnarrow_to_region (old_begv, old_zv); | ||
| 2099 | |||
| 2100 | current_buffer->read_only = old_read_only; | ||
| 2041 | SET_PT (opoint); | 2101 | SET_PT (opoint); |
| 2042 | set_buffer_internal (old); | 2102 | set_buffer_internal (old); |
| 2043 | } | 2103 | } |
| @@ -2209,7 +2269,11 @@ Output from processes can arrive in between bunches.") | |||
| 2209 | the terminal being used to communicate with PROCESS. | 2269 | the terminal being used to communicate with PROCESS. |
| 2210 | This is used for various commands in shell mode. | 2270 | This is used for various commands in shell mode. |
| 2211 | If NOMSG is zero, insert signal-announcements into process's buffers | 2271 | If NOMSG is zero, insert signal-announcements into process's buffers |
| 2212 | right away. */ | 2272 | right away. |
| 2273 | |||
| 2274 | If we can, we try to signal PROCESS by sending control characters | ||
| 2275 | down the pipe. This allows us to signal inferiors who have changed | ||
| 2276 | their uid, for which killpg would return an EPERM error. */ | ||
| 2213 | 2277 | ||
| 2214 | static void | 2278 | static void |
| 2215 | process_send_signal (process, signo, current_group, nomsg) | 2279 | process_send_signal (process, signo, current_group, nomsg) |
| @@ -2239,9 +2303,14 @@ process_send_signal (process, signo, current_group, nomsg) | |||
| 2239 | /* If we are using pgrps, get a pgrp number and make it negative. */ | 2303 | /* If we are using pgrps, get a pgrp number and make it negative. */ |
| 2240 | if (!NILP (current_group)) | 2304 | if (!NILP (current_group)) |
| 2241 | { | 2305 | { |
| 2306 | #ifdef SIGNALS_VIA_CHARACTERS | ||
| 2242 | /* If possible, send signals to the entire pgrp | 2307 | /* If possible, send signals to the entire pgrp |
| 2243 | by sending an input character to it. */ | 2308 | by sending an input character to it. */ |
| 2309 | |||
| 2310 | /* On Berkeley descendants, the following IOCTL's retrieve the | ||
| 2311 | current control characters. */ | ||
| 2244 | #if defined (TIOCGLTC) && defined (TIOCGETC) | 2312 | #if defined (TIOCGLTC) && defined (TIOCGETC) |
| 2313 | |||
| 2245 | struct tchars c; | 2314 | struct tchars c; |
| 2246 | struct ltchars lc; | 2315 | struct ltchars lc; |
| 2247 | 2316 | ||
| @@ -2260,13 +2329,14 @@ process_send_signal (process, signo, current_group, nomsg) | |||
| 2260 | ioctl (XFASTINT (p->infd), TIOCGLTC, &lc); | 2329 | ioctl (XFASTINT (p->infd), TIOCGLTC, &lc); |
| 2261 | send_process (proc, &lc.t_suspc, 1); | 2330 | send_process (proc, &lc.t_suspc, 1); |
| 2262 | return; | 2331 | return; |
| 2263 | #endif /* SIGTSTP */ | 2332 | #endif /* ! defined (SIGTSTP) */ |
| 2264 | } | 2333 | } |
| 2265 | #endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */ | 2334 | |
| 2266 | /* It is possible that the following code would work | 2335 | #else /* ! defined (TIOCGLTC) && defined (TIOCGETC) */ |
| 2267 | on other kinds of USG systems, not just on the IRIS. | 2336 | |
| 2268 | This should be tried in Emacs 19. */ | 2337 | /* On SYSV descendants, the TCGETA ioctl retrieves the current control |
| 2269 | #if defined (USG) | 2338 | characters. */ |
| 2339 | #ifdef TCGETA | ||
| 2270 | struct termio t; | 2340 | struct termio t; |
| 2271 | switch (signo) | 2341 | switch (signo) |
| 2272 | { | 2342 | { |
| @@ -2283,16 +2353,22 @@ process_send_signal (process, signo, current_group, nomsg) | |||
| 2283 | ioctl (XFASTINT (p->infd), TCGETA, &t); | 2353 | ioctl (XFASTINT (p->infd), TCGETA, &t); |
| 2284 | send_process (proc, &t.c_cc[VSWTCH], 1); | 2354 | send_process (proc, &t.c_cc[VSWTCH], 1); |
| 2285 | return; | 2355 | return; |
| 2286 | #endif | 2356 | #endif /* ! defined (SIGTSTP) */ |
| 2287 | } | 2357 | } |
| 2288 | #endif /* ! defined (USG) */ | 2358 | #else /* ! defined (TCGETA) */ |
| 2359 | Your configuration files are messed up. | ||
| 2360 | /* If your system configuration files define SIGNALS_VIA_CHARACTERS, | ||
| 2361 | you'd better be using one of the alternatives above! */ | ||
| 2362 | #endif /* ! defined (TCGETA) */ | ||
| 2363 | #endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */ | ||
| 2364 | #endif /* ! defined (SIGNALS_VIA_CHARACTERS) */ | ||
| 2289 | 2365 | ||
| 2290 | #ifdef TIOCGPGRP | 2366 | #ifdef TIOCGPGRP |
| 2291 | /* Get the pgrp using the tty itself, if we have that. | 2367 | /* Get the pgrp using the tty itself, if we have that. |
| 2292 | Otherwise, use the pty to get the pgrp. | 2368 | Otherwise, use the pty to get the pgrp. |
| 2293 | On pfa systems, saka@pfu.fujitsu.co.JP writes: | 2369 | On pfa systems, saka@pfu.fujitsu.co.JP writes: |
| 2294 | "TICGPGRP symbol defined in sys/ioctl.h at E50. | 2370 | "TIOCGPGRP symbol defined in sys/ioctl.h at E50. |
| 2295 | But, TIOCGPGRP does not work on E50 ;-P works fine on E60" | 2371 | But, TIOCGPGRP does not work on E50 ;-P works fine on E60" |
| 2296 | His patch indicates that if TIOCGPGRP returns an error, then | 2372 | His patch indicates that if TIOCGPGRP returns an error, then |
| 2297 | we should just assume that p->pid is also the process group id. */ | 2373 | we should just assume that p->pid is also the process group id. */ |
| 2298 | { | 2374 | { |
| @@ -2312,7 +2388,7 @@ process_send_signal (process, signo, current_group, nomsg) | |||
| 2312 | no_pgrp = 1; | 2388 | no_pgrp = 1; |
| 2313 | else | 2389 | else |
| 2314 | gid = - gid; | 2390 | gid = - gid; |
| 2315 | #else /* ! defined (TIOCGPGRP ) */ | 2391 | #else /* ! defined (TIOCGPGRP ) */ |
| 2316 | /* Can't select pgrps on this system, so we know that | 2392 | /* Can't select pgrps on this system, so we know that |
| 2317 | the child itself heads the pgrp. */ | 2393 | the child itself heads the pgrp. */ |
| 2318 | gid = - XFASTINT (p->pid); | 2394 | gid = - XFASTINT (p->pid); |
| @@ -2630,7 +2706,11 @@ sigchld_handler (signo) | |||
| 2630 | if (WIFEXITED (w)) | 2706 | if (WIFEXITED (w)) |
| 2631 | synch_process_retcode = WRETCODE (w); | 2707 | synch_process_retcode = WRETCODE (w); |
| 2632 | else if (WIFSIGNALED (w)) | 2708 | else if (WIFSIGNALED (w)) |
| 2709 | #ifndef VMS | ||
| 2633 | synch_process_death = sys_siglist[WTERMSIG (w)]; | 2710 | synch_process_death = sys_siglist[WTERMSIG (w)]; |
| 2711 | #else | ||
| 2712 | synch_process_death = sys_errlist[WTERMSIG (w)]; | ||
| 2713 | #endif | ||
| 2634 | } | 2714 | } |
| 2635 | 2715 | ||
| 2636 | /* On some systems, we must return right away. | 2716 | /* On some systems, we must return right away. |