Commit b0310da4 authored by Jim Blandy's avatar Jim Blandy
Browse files

* 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.
parent 64a3a3c0
......@@ -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");
string = build_string (code < NSIG ? sys_errlist[code] : "unknown");
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);
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\
......@@ -953,6 +963,7 @@ Remaining arguments are strings to give program as arguments.")
register unsigned char **new_argv;
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;
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);
......@@ -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));
/* 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);
/* 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))
/* 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);
#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);
#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) */
/* Get the pgrp using the tty itself, if we have that.
Otherwise, use the pty to get the pgrp.
On pfa systems, 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;
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)];
synch_process_death = sys_errlist[WTERMSIG (w)];
/* On some systems, we must return right away.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment