summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Blandy <jimb@redhat.com>1992-11-16 00:53:26 +0000
committerJim Blandy <jimb@redhat.com>1992-11-16 00:53:26 +0000
commitb0310da46a84635eb11693f59fe456c40cb8dc39 (patch)
tree41e3a2adee43d75f5dd49fd6cdbb865aabc49680 /src
parent64a3a3c0b4ff590ca41431dd4287d234f4fd6349 (diff)
downloademacs-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.c134
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.