diff options
author | Jim Blandy <jimb@redhat.com> | 1992-11-16 00:53:26 +0000 |
---|---|---|
committer | Jim Blandy <jimb@redhat.com> | 1992-11-16 00:53:26 +0000 |
commit | b0310da46a84635eb11693f59fe456c40cb8dc39 (patch) | |
tree | 41e3a2adee43d75f5dd49fd6cdbb865aabc49680 /src | |
parent | 64a3a3c0b4ff590ca41431dd4287d234f4fd6349 (diff) | |
download | emacs-b0310da46a84635eb11693f59fe456c40cb8dc39.tar.gz |
* 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; /* For the CMU PTY driver + */ #define DCL_PROMPT "$ " - +/* This is a hack. I have no idea what needs to go here, but this */ +/* will get it to compile. We can fix it later. rbr */ +#define WAITTYPE int #include <ssdef.h> #include <iodef.h> #include <clidef.h> @@ -349,7 +351,11 @@ status_message (status) if (EQ (symbol, Qsignal) || EQ (symbol, Qstop)) { +#ifndef VMS string = build_string (code < NSIG ? sys_siglist[code] : "unknown"); +#else + string = build_string (code < NSIG ? sys_errlist[code] : "unknown"); +#endif string2 = build_string (coredump ? " (core dumped)\n" : "\n"); XSTRING (string)->data[0] = DOWNCASE (XSTRING (string)->data[0]); return concat2 (string, string2); @@ -847,7 +853,7 @@ Proc Status Buffer Command\n\ tem = Fcar (Fcdr (p->status)); #ifdef VMS if (XINT (tem) < NSIG) - write_string (sys_siglist [XINT (tem)], -1); + write_string (sys_errlist [XINT (tem)], -1); else #endif Fprinc (symbol, Qnil); @@ -930,6 +936,10 @@ DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0, return Fmapcar (Qcdr, Vprocess_alist); } +/* Starting asynchronous inferior processes. */ + +static Lisp_Object start_process_unwind (); + DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, "Start a program in a subprocess. Return the process object for it.\n\ Args are NAME BUFFER PROGRAM &rest PROGRAM-ARGS\n\ @@ -953,6 +963,7 @@ Remaining arguments are strings to give program as arguments.") register unsigned char **new_argv; #endif register int i; + int count = specpdl_ptr - specpdl; buffer = args[1]; if (!NILP (buffer)) @@ -984,6 +995,8 @@ Remaining arguments are strings to give program as arguments.") strcat (new_argv, " "); strcat (new_argv, XSTRING (tem)->data); } + /* Need to add code here to check for program existence on VMS */ + #else /* not VMS */ new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); @@ -1008,6 +1021,11 @@ Remaining arguments are strings to give program as arguments.") #endif /* not VMS */ proc = make_process (name); + /* If an error occurs and we can't start the process, we want to + remove it from the process list. This means that each error + check in create_process doesn't need to call remove_process + itself; it's all taken care of here. */ + record_unwind_protect (start_process_unwind, proc); XPROCESS (proc)->childp = Qt; XPROCESS (proc)->command_channel_p = Qnil; @@ -1018,9 +1036,28 @@ Remaining arguments are strings to give program as arguments.") create_process (proc, new_argv); - return proc; + return unbind_to (count, proc); +} + +/* This function is the unwind_protect form for Fstart_process. If + PROC doesn't have its pid set, then we know someone has signalled + an error and the process wasn't started successfully, so we should + remove it from the process list. */ +static Lisp_Object +start_process_unwind (proc) + Lisp_Object proc; +{ + if (XTYPE (proc) != Lisp_Process) + abort (); + + /* Was PROC started successfully? */ + if (XPROCESS (proc)->pid <= 0) + remove_process (proc); + + return Qnil; } + SIGTYPE create_process_1 (signo) int signo; @@ -1282,11 +1319,8 @@ create_process (process, new_argv) } if (pid < 0) - { - remove_process (process); - report_file_error ("Doing vfork", Qnil); - } - + report_file_error ("Doing vfork", Qnil); + XFASTINT (XPROCESS (process)->pid) = pid; FD_SET (inchannel, &input_wait_mask); @@ -1741,9 +1775,12 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) { if (xerrno == EINTR) FD_ZERO (&Available); -#ifdef __ultrix__ - /* Ultrix select seems to return ENOMEM when it is interrupted. - Treat it just like EINTR. Bleah. -JimB */ +#ifdef ultrix + /* Ultrix select seems to return ENOMEM when it is + interrupted. Treat it just like EINTR. Bleah. Note + that we want to test for the "ultrix" CPP symbol, not + "__ultrix__"; the latter is only defined under GCC, but + not by DEC's bundled CC. -JimB */ else if (xerrno == ENOMEM) FD_ZERO (&Available); #endif @@ -2014,10 +2051,16 @@ read_process_output (proc, channel) /* If no filter, write into buffer if it isn't dead. */ if (!NILP (p->buffer) && !NILP (XBUFFER (p->buffer)->name)) { - Lisp_Object tem; + Lisp_Object old_read_only; + Lisp_Object old_begv, old_zv; Fset_buffer (p->buffer); opoint = point; + old_read_only = current_buffer->read_only; + XFASTINT (old_begv) = BEGV; + XFASTINT (old_zv) = ZV; + + current_buffer->read_only = Qnil; /* Insert new output into buffer at the current end-of-output marker, @@ -2026,18 +2069,35 @@ read_process_output (proc, channel) SET_PT (marker_position (p->mark)); else SET_PT (ZV); + + /* If the output marker is outside of the visible region, save + the restriction and widen. */ + if (! (BEGV <= point && point <= ZV)) + Fwiden (); + + /* Make sure opoint floats ahead of any new text, just as point + would. */ if (point <= opoint) opoint += nchars; - tem = current_buffer->read_only; - current_buffer->read_only = Qnil; + /* Insert after old_begv, but before old_zv. */ + if (point < XFASTINT (old_begv)) + XFASTINT (old_begv) += nchars; + if (point <= XFASTINT (old_zv)) + XFASTINT (old_zv) += nchars; + /* Insert before markers in case we are inserting where the buffer's mark is, and the user's next command is Meta-y. */ insert_before_markers (chars, nchars); - current_buffer->read_only = tem; Fset_marker (p->mark, make_number (point), p->buffer); + update_mode_lines++; + /* If the restriction isn't what it should be, set it. */ + if (XFASTINT (old_begv) != BEGV || XFASTINT (old_zv) != ZV) + Fnarrow_to_region (old_begv, old_zv); + + current_buffer->read_only = old_read_only; SET_PT (opoint); set_buffer_internal (old); } @@ -2209,7 +2269,11 @@ Output from processes can arrive in between bunches.") the terminal being used to communicate with PROCESS. This is used for various commands in shell mode. If NOMSG is zero, insert signal-announcements into process's buffers - right away. */ + right away. + + If we can, we try to signal PROCESS by sending control characters + down the pipe. This allows us to signal inferiors who have changed + their uid, for which killpg would return an EPERM error. */ static void process_send_signal (process, signo, current_group, nomsg) @@ -2239,9 +2303,14 @@ process_send_signal (process, signo, current_group, nomsg) /* If we are using pgrps, get a pgrp number and make it negative. */ if (!NILP (current_group)) { +#ifdef SIGNALS_VIA_CHARACTERS /* If possible, send signals to the entire pgrp by sending an input character to it. */ + + /* On Berkeley descendants, the following IOCTL's retrieve the + current control characters. */ #if defined (TIOCGLTC) && defined (TIOCGETC) + struct tchars c; struct ltchars lc; @@ -2260,13 +2329,14 @@ process_send_signal (process, signo, current_group, nomsg) ioctl (XFASTINT (p->infd), TIOCGLTC, &lc); send_process (proc, &lc.t_suspc, 1); return; -#endif /* SIGTSTP */ +#endif /* ! defined (SIGTSTP) */ } -#endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */ - /* It is possible that the following code would work - on other kinds of USG systems, not just on the IRIS. - This should be tried in Emacs 19. */ -#if defined (USG) + +#else /* ! defined (TIOCGLTC) && defined (TIOCGETC) */ + + /* On SYSV descendants, the TCGETA ioctl retrieves the current control + characters. */ +#ifdef TCGETA struct termio t; switch (signo) { @@ -2283,16 +2353,22 @@ process_send_signal (process, signo, current_group, nomsg) ioctl (XFASTINT (p->infd), TCGETA, &t); send_process (proc, &t.c_cc[VSWTCH], 1); return; -#endif +#endif /* ! defined (SIGTSTP) */ } -#endif /* ! defined (USG) */ +#else /* ! defined (TCGETA) */ + Your configuration files are messed up. + /* If your system configuration files define SIGNALS_VIA_CHARACTERS, + you'd better be using one of the alternatives above! */ +#endif /* ! defined (TCGETA) */ +#endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */ +#endif /* ! defined (SIGNALS_VIA_CHARACTERS) */ #ifdef TIOCGPGRP /* Get the pgrp using the tty itself, if we have that. Otherwise, use the pty to get the pgrp. On pfa systems, saka@pfu.fujitsu.co.JP writes: - "TICGPGRP symbol defined in sys/ioctl.h at E50. - But, TIOCGPGRP does not work on E50 ;-P works fine on E60" + "TIOCGPGRP symbol defined in sys/ioctl.h at E50. + But, TIOCGPGRP does not work on E50 ;-P works fine on E60" His patch indicates that if TIOCGPGRP returns an error, then we should just assume that p->pid is also the process group id. */ { @@ -2312,7 +2388,7 @@ process_send_signal (process, signo, current_group, nomsg) no_pgrp = 1; else gid = - gid; -#else /* ! defined (TIOCGPGRP ) */ +#else /* ! defined (TIOCGPGRP ) */ /* Can't select pgrps on this system, so we know that the child itself heads the pgrp. */ gid = - XFASTINT (p->pid); @@ -2630,7 +2706,11 @@ sigchld_handler (signo) if (WIFEXITED (w)) synch_process_retcode = WRETCODE (w); else if (WIFSIGNALED (w)) +#ifndef VMS synch_process_death = sys_siglist[WTERMSIG (w)]; +#else + synch_process_death = sys_errlist[WTERMSIG (w)]; +#endif } /* On some systems, we must return right away. |