# HG changeset patch # User Jim Blandy # Date 721875206 0 # Node ID b476a97ad17e5837077f8444ce00f0da4a7c12ae # Parent a3862c6dfcd0cdc1f22f21e9fad6f0bfb46650d5 * 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. diff -r a3862c6dfcd0 -r b476a97ad17e src/process.c --- a/src/process.c Mon Nov 16 00:46:19 1992 +0000 +++ b/src/process.c Mon Nov 16 00:53:26 1992 +0000 @@ -162,7 +162,9 @@ /* 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 #include #include @@ -349,7 +351,11 @@ 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 @@ 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 @@ 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 @@ register unsigned char **new_argv; #endif register int i; + int count = specpdl_ptr - specpdl; buffer = args[1]; if (!NILP (buffer)) @@ -984,6 +995,8 @@ 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 @@ #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 @@ 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 @@ } 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 @@ { 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 @@ /* 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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.