#endif
#endif /* HAVE_SOCKETS */
-/* TERM is a poor-man's SLIP, used on GNU/Linux. */
-#ifdef TERM
-#include <client.h>
-#endif
-
#if defined(BSD_SYSTEM)
#include <sys/ioctl.h>
#if !defined (O_NDELAY) && defined (HAVE_PTYS) && !defined(USG5)
#endif /* HAVE_PTYS and no O_NDELAY */
#endif /* BSD_SYSTEM */
-#ifdef BROKEN_O_NONBLOCK
-#undef O_NONBLOCK
-#endif /* BROKEN_O_NONBLOCK */
-
#ifdef NEED_BSDTTY
#include <bsdtty.h>
#endif
#endif
#endif
-#ifdef IRIS
-#include <sys/sysmacros.h> /* for "minor" */
-#endif /* not IRIS */
-
#ifdef HAVE_SYS_WAIT
#include <sys/wait.h>
#endif
#endif /* HAVE_SOCKETS */
/* Define first descriptor number available for subprocesses. */
-#ifdef VMS
-#define FIRST_PROC_DESC 1
-#else /* Not VMS */
#define FIRST_PROC_DESC 3
-#endif
/* Define SIGCHLD as an alias for SIGCLD. There are many conditionals
testing SIGCHLD. */
#ifndef USE_CRT_DLL
extern int errno;
#endif
-#ifdef VMS
-extern char *sys_errlist[];
-#endif
#ifndef HAVE_H_ERRNO
extern int h_errno;
#endif /* DATAGRAM_SOCKETS */
#endif /* BROKEN_DATAGRAM_SOCKETS */
-#ifdef TERM
-#undef NON_BLOCKING_CONNECT
-#undef DATAGRAM_SOCKETS
-#endif
-
#if !defined (ADAPTIVE_READ_BUFFERING) && !defined (NO_ADAPTIVE_READ_BUFFERING)
#ifdef EMACS_HAS_USECS
#define ADAPTIVE_READ_BUFFERING
/* Compute the Lisp form of the process status, p->status, from
the numeric status that was returned by `wait'. */
-static Lisp_Object status_convert ();
+static Lisp_Object status_convert (int);
static void
update_status (p)
struct Lisp_Process *p;
{
- union { int i; WAITTYPE wt; } u;
eassert (p->raw_status_new);
- u.i = p->raw_status;
- p->status = status_convert (u.wt);
+ p->status = status_convert (p->raw_status);
p->raw_status_new = 0;
}
the list that we use internally. */
static Lisp_Object
-status_convert (w)
- WAITTYPE w;
+status_convert (int w)
{
if (WIFSTOPPED (w))
return Fcons (Qstop, Fcons (make_number (WSTOPSIG (w)), Qnil));
PTY_OPEN;
#else /* no PTY_OPEN */
{
-# ifdef IRIS
- /* Unusual IRIS code */
- *ptyv = emacs_open ("/dev/ptc", O_RDWR | O_NDELAY, 0);
- if (fd < 0)
- return -1;
- if (fstat (fd, &stb) < 0)
- return -1;
-# else /* not IRIS */
{ /* Some systems name their pseudoterminals so that there are gaps in
the usual sequence - for example, on HP9000/S700 systems, there
are no pseudoterminals with names ending in 'f'. So we wait for
# else
fd = emacs_open (pty_name, O_RDWR | O_NDELAY, 0);
# endif
-# endif /* not IRIS */
}
#endif /* no PTY_OPEN */
if (access (pty_name, 6) != 0)
{
emacs_close (fd);
-# if !defined(IRIS) && !defined(__sgi)
+# ifndef __sgi
continue;
# else
return -1;
-# endif /* IRIS */
+# endif /* __sgi */
}
setup_pty (fd);
return fd;
{
Lisp_Object tem;
tem = Fcar (Fcdr (p->status));
-#ifdef VMS
- if (XINT (tem) < NSIG)
- write_string (sys_errlist [XINT (tem)], -1);
- else
-#endif
- Fprinc (symbol, Qnil);
+ Fprinc (symbol, Qnil);
}
else if (NETCONN1_P (p) || SERIALCONN1_P (p))
{
register Lisp_Object *args;
{
Lisp_Object buffer, name, program, proc, current_dir, tem;
-#ifdef VMS
- register unsigned char *new_argv;
- int len;
-#else
register unsigned char **new_argv;
-#endif
register int i;
int count = SPECPDL_INDEX ();
XPROCESS (proc)->encode_coding_system = val;
}
-#ifdef VMS
- /* Make a one member argv with all args concatenated
- together separated by a blank. */
- len = SBYTES (program) + 2;
- for (i = 3; i < nargs; i++)
- {
- tem = args[i];
- CHECK_STRING (tem);
- len += SBYTES (tem) + 1; /* count the blank */
- }
- new_argv = (unsigned char *) alloca (len);
- strcpy (new_argv, SDATA (program));
- for (i = 3; i < nargs; i++)
- {
- tem = args[i];
- CHECK_STRING (tem);
- strcat (new_argv, " ");
- strcat (new_argv, SDATA (tem));
- }
- /* Need to add code here to check for program existence on VMS */
-
-#else /* not VMS */
new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *));
/* If program file name is not absolute, search our path for it.
new_argv[i - 2] = SDATA (tem);
}
new_argv[i - 2] = 0;
-#endif /* not VMS */
XPROCESS (proc)->decoding_buf = make_uninit_string (0);
XPROCESS (proc)->decoding_carryover = 0;
#endif
#endif
-#ifndef VMS /* VMS version of this function is in vmsproc.c. */
void
create_process (process, new_argv, current_dir)
Lisp_Object process;
int inchannel, outchannel;
pid_t pid;
int sv[2];
+#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
+ int wait_child_setup[2];
+#endif
#ifdef POSIX_SIGNALS
sigset_t procmask;
sigset_t blocked;
forkin = sv[0];
}
+#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
+ {
+ int tem;
+
+ tem = pipe (wait_child_setup);
+ if (tem < 0)
+ report_file_error ("Creating pipe", Qnil);
+ tem = fcntl (wait_child_setup[1], F_GETFD, 0);
+ if (tem >= 0)
+ tem = fcntl (wait_child_setup[1], F_SETFD, tem | FD_CLOEXEC);
+ if (tem < 0)
+ {
+ emacs_close (wait_child_setup[0]);
+ emacs_close (wait_child_setup[1]);
+ report_file_error ("Setting file descriptor flags", Qnil);
+ }
+ }
+#endif
+
#if 0
/* Replaced by close_process_descs */
set_exclusive_use (inchannel);
sigprocmask (SIG_BLOCK, &blocked, &procmask);
#else /* !POSIX_SIGNALS */
#ifdef SIGCHLD
-#ifdef BSD4_1
- sighold (SIGCHLD);
-#else /* not BSD4_1 */
#if defined (BSD_SYSTEM) || defined (HPUX)
sigsetmask (sigmask (SIGCHLD));
#else /* ordinary USG */
sigchld = signal (SIGCHLD, create_process_sigchld);
#endif
#endif /* ordinary USG */
-#endif /* not BSD4_1 */
#endif /* SIGCHLD */
#endif /* !POSIX_SIGNALS */
This makes the pty the controlling terminal of the subprocess. */
if (pty_flag)
{
-#ifdef SET_CHILD_PTY_PGRP
- int pgrp = getpid ();
-#endif
/* I wonder if emacs_close (emacs_open (pty_name, ...))
would work? */
_exit (1);
}
-#ifdef SET_CHILD_PTY_PGRP
- ioctl (xforkin, TIOCSPGRP, &pgrp);
- ioctl (xforkout, TIOCSPGRP, &pgrp);
-#endif
}
#endif /* not DONT_REOPEN_PTY */
sigprocmask (SIG_SETMASK, &procmask, 0);
#else /* !POSIX_SIGNALS */
#ifdef SIGCHLD
-#ifdef BSD4_1
- sigrelse (SIGCHLD);
-#else /* not BSD4_1 */
#if defined (BSD_SYSTEM) || defined (HPUX)
sigsetmask (SIGEMPTYMASK);
#else /* ordinary USG */
signal (SIGCHLD, sigchld);
#endif
#endif /* ordinary USG */
-#endif /* not BSD4_1 */
#endif /* SIGCHLD */
#endif /* !POSIX_SIGNALS */
pid = child_setup (xforkin, xforkout, xforkout,
new_argv, 1, current_dir);
#else /* not WINDOWSNT */
+#ifdef FD_CLOEXEC
+ emacs_close (wait_child_setup[0]);
+#endif
child_setup (xforkin, xforkout, xforkout,
new_argv, 1, current_dir);
#endif /* not WINDOWSNT */
else
#endif
XPROCESS (process)->tty_name = Qnil;
+
+#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
+ /* Wait for child_setup to complete in case that vfork is
+ actually defined as fork. The descriptor wait_child_setup[1]
+ of a pipe is closed at the child side either by close-on-exec
+ on successful execvp or the _exit call in child_setup. */
+ {
+ char dummy;
+
+ emacs_close (wait_child_setup[1]);
+ emacs_read (wait_child_setup[0], &dummy, 1);
+ emacs_close (wait_child_setup[0]);
+ }
+#endif
}
/* Restore the signal state whether vfork succeeded or not.
sigprocmask (SIG_SETMASK, &procmask, 0);
#else /* !POSIX_SIGNALS */
#ifdef SIGCHLD
-#ifdef BSD4_1
- sigrelse (SIGCHLD);
-#else /* not BSD4_1 */
#if defined (BSD_SYSTEM) || defined (HPUX)
sigsetmask (SIGEMPTYMASK);
#else /* ordinary USG */
kill (getpid (), SIGCHLD);
#endif
#endif /* ordinary USG */
-#endif /* not BSD4_1 */
#endif /* SIGCHLD */
#endif /* !POSIX_SIGNALS */
if (pid < 0)
report_file_error ("Doing vfork", Qnil);
}
-#endif /* not VMS */
\f
#ifdef HAVE_SOCKETS
}
\f
-/* A version of request_sigio suitable for a record_unwind_protect. */
-
-#ifdef __ultrix__
-static Lisp_Object
-unwind_request_sigio (dummy)
- Lisp_Object dummy;
-{
- if (interrupt_input)
- request_sigio ();
- return Qnil;
-}
-#endif
-
#ifdef HAVE_SERIAL
DEFUN ("serial-process-configure",
Fserial_process_configure,
UNGCPRO;
return Qnil;
}
-#endif /* HAVE_SERIAL */
-#ifdef HAVE_SERIAL
/* Used by make-serial-process to recover from errors. */
Lisp_Object make_serial_process_unwind (Lisp_Object proc)
{
remove_process (proc);
return Qnil;
}
-#endif /* HAVE_SERIAL */
-#ifdef HAVE_SERIAL
DEFUN ("make-serial-process", Fmake_serial_process, Smake_serial_process,
0, MANY, 0,
doc: /* Create and return a serial port process.
{
/* Don't support network sockets when non-blocking mode is
not available, since a blocked Emacs is not useful. */
-#if defined(TERM) || (!defined(O_NONBLOCK) && !defined(O_NDELAY))
+#if !defined(O_NONBLOCK) && !defined(O_NDELAY)
error ("Network servers not supported");
#else
is_server = 1;
CHECK_STRING (name);
-#ifdef TERM
- /* Let's handle TERM before things get complicated ... */
- host = Fplist_get (contact, QChost);
- CHECK_STRING (host);
-
- service = Fplist_get (contact, QCservice);
- if (INTEGERP (service))
- port = htons ((unsigned short) XINT (service));
- else
- {
- struct servent *svc_info;
- CHECK_STRING (service);
- svc_info = getservbyname (SDATA (service), "tcp");
- if (svc_info == 0)
- error ("Unknown service: %s", SDATA (service));
- port = svc_info->s_port;
- }
-
- s = connect_server (0);
- if (s < 0)
- report_file_error ("error creating socket", Fcons (name, Qnil));
- send_command (s, C_PORT, 0, "%s:%d", SDATA (host), ntohs (port));
- send_command (s, C_DUMB, 1, 0);
-
-#else /* not TERM */
-
/* Initialize addrinfo structure in case we don't use getaddrinfo. */
ai.ai_socktype = socktype;
ai.ai_protocol = 0;
open_socket:
-#ifdef __ultrix__
- /* Previously this was compiled unconditionally, but that seems
- unnecessary on modern systems, and `unrequest_sigio' was a noop
- under X anyway. --lorentey */
- /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
- when connect is interrupted. So let's not let it get interrupted.
- Note we do not turn off polling, because polling is only used
- when not interrupt_input, and thus not normally used on the systems
- which have this bug. On systems which use polling, there's no way
- to quit if polling is turned off. */
- if (interrupt_input
- && !is_server && socktype == SOCK_STREAM)
- {
- /* Comment from KFS: The original open-network-stream code
- didn't unwind protect this, but it seems like the proper
- thing to do. In any case, I don't see how it could harm to
- do this -- and it makes cleanup (using unbind_to) easier. */
- record_unwind_protect (unwind_request_sigio, Qnil);
- unrequest_sigio ();
- }
-#endif
-
/* Do this in case we never enter the for-loop below. */
count1 = SPECPDL_INDEX ();
s = -1;
/* Parse network options in the arg list.
We simply ignore anything which isn't a known option (including other keywords).
- An error is signalled if setting a known option fails. */
+ An error is signaled if setting a known option fails. */
for (optn = optbits = 0; optn < nargs-1; optn += 2)
optbits |= set_socket_option (s, args[optn], args[optn+1]);
report_file_error ("make client process failed", contact);
}
-#endif /* not TERM */
-
inch = s;
outch = s;
{
/* Beware SIGCHLD hereabouts. */
flush_pending_output (inchannel);
-#ifdef VMS
- {
- VMS_PROC_STUFF *get_vms_process_pointer (), *vs;
- sys$dassgn (outchannel);
- vs = get_vms_process_pointer (p->pid);
- if (vs)
- give_back_vms_process_stuff (vs);
- }
-#else
emacs_close (inchannel);
if (outchannel >= 0 && outchannel != inchannel)
emacs_close (outchannel);
-#endif
p->infd = -1;
p->outfd = -1;
EMACS_SET_SECS_USECS (timeout, time_limit, microsecs);
EMACS_ADD_TIME (end_time, end_time, timeout);
}
-#ifdef POLL_INTERRUPTED_SYS_CALL
- /* AlainF 5-Jul-1996
- HP-UX 10.10 seem to have problems with signals coming in
- Causes "poll: interrupted system call" messages when Emacs is run
- in an X window
- Turn off periodic alarms (in case they are in use),
- and then turn off any other atimers. */
- stop_polling ();
- turn_on_atimers (0);
-#endif /* POLL_INTERRUPTED_SYS_CALL */
while (1)
{
#endif
Atemp = input_wait_mask;
-#if 0
- /* On Mac OS X 10.0, the SELECT system call always says input is
- present (for reading) at stdin, even when none is. This
- causes the call to SELECT below to return 1 and
- status_notify not to be called. As a result output of
- subprocesses are incorrectly discarded.
- */
- FD_CLR (0, &Atemp);
-#endif
IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask);
EMACS_SET_SECS_USECS (timeout, 0, 0);
process_output_skip = 0;
}
#endif
-
- nfds = select (max (max (max_process_desc, max_keyboard_desc),
+#ifdef HAVE_NS
+ nfds = ns_select
+#else
+ nfds = select
+#endif
+ (max (max (max_process_desc, max_keyboard_desc),
max_gpm_desc) + 1,
&Available,
#ifdef NON_BLOCKING_CONNECT
{
if (xerrno == EINTR)
no_avail = 1;
-#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)
- no_avail = 1;
-#endif
else if (xerrno == EBADF)
{
#ifdef AIX
IF_NON_BLOCKING_CONNECT (check_connect = 0);
}
-#if defined(sun) && !defined(USG5_4)
- if (nfds > 0 && keyboard_bit_set (&Available)
- && interrupt_input)
- /* System sometimes fails to deliver SIGIO.
-
- David J. Mackenzie says that Emacs doesn't compile under
- Solaris if this code is enabled, thus the USG5_4 in the CPP
- conditional. "I haven't noticed any ill effects so far.
- If you find a Solaris expert somewhere, they might know
- better." */
- kill (getpid (), SIGIO);
-#endif
-
#if 0 /* When polling is used, interrupt_input is 0,
so get_input_pending should read the input.
So this should not be needed. */
clear_input_pending ();
QUIT;
}
-#ifdef POLL_INTERRUPTED_SYS_CALL
- /* AlainF 5-Jul-1996
- HP-UX 10.10 seems to have problems with signals coming in
- Causes "poll: interrupted system call" messages when Emacs is run
- in an X window
- Turn periodic alarms back on */
- start_polling ();
-#endif /* POLL_INTERRUPTED_SYS_CALL */
return got_some_input;
}
int carryover = p->decoding_carryover;
int readmax = 4096;
-#ifdef VMS
- VMS_PROC_STUFF *vs, *get_vms_process_pointer();
-
- vs = get_vms_process_pointer (p->pid);
- if (vs)
- {
- if (!vs->iosb[0])
- return (0); /* Really weird if it does this */
- if (!(vs->iosb[0] & 1))
- return -1; /* I/O error */
- }
- else
- error ("Could not get VMS process pointer");
- chars = vs->inputBuffer;
- nbytes = clean_vms_buffer (chars, vs->iosb[1]);
- if (nbytes <= 0)
- {
- start_vms_process_read (vs); /* Crank up the next read on the process */
- return 1; /* Nothing worth printing, say we got 1 */
- }
- if (carryover > 0)
- {
- /* The data carried over in the previous decoding (which are at
- the tail of decoding buffer) should be prepended to the new
- data read to decode all together. */
- chars = (char *) alloca (nbytes + carryover);
- bcopy (SDATA (p->decoding_buf), buf, carryover);
- bcopy (vs->inputBuffer, chars + carryover, nbytes);
- }
-#else /* not VMS */
-
chars = (char *) alloca (carryover + readmax);
if (carryover)
/* See the comment above. */
else
nbytes = nbytes + 1;
}
-#endif /* not VMS */
p->decoding_carryover = 0;
if (waiting_for_user_input_p == -1)
record_asynch_buffer_change ();
-#ifdef VMS
- start_vms_process_read (vs);
-#endif
unbind_to (count, Qnil);
return nbytes;
}
SET_PT_BOTH (opoint, opoint_byte);
set_buffer_internal (old);
}
-#ifdef VMS
- start_vms_process_read (vs);
-#endif
return nbytes;
}
send_process_trap ()
{
SIGNAL_THREAD_CHECK (SIGPIPE);
-#ifdef BSD4_1
- sigrelse (SIGPIPE);
- sigrelse (SIGALRM);
-#endif /* BSD4_1 */
sigunblock (sigmask (SIGPIPE));
longjmp (send_process_frame, 1);
}
GCPRO1 (object);
-#ifdef VMS
- VMS_PROC_STUFF *vs, *get_vms_process_pointer();
-#endif /* VMS */
-
if (p->raw_status_new)
update_status (p);
if (! EQ (p->status, Qrun))
buf = SDATA (coding->dst_object);
}
-#ifdef VMS
- vs = get_vms_process_pointer (p->pid);
- if (vs == 0)
- error ("Could not find this process: %x", p->pid);
- else if (write_to_vms_process (vs, buf, len))
- ;
-#else /* not VMS */
-
if (pty_max_bytes == 0)
{
#if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON)
Fprocess_send_eof (proc);
}
}
-#endif /* not VMS */
else
{
signal (SIGPIPE, old_sigpipe);
-#ifndef VMS
proc = process_sent_to;
p = XPROCESS (proc);
-#endif
p->raw_status_new = 0;
p->status = Fcons (Qexit, Fcons (make_number (256), Qnil));
p->tick = ++process_tick;
deactivate_process (proc);
-#ifdef VMS
- error ("Error writing to process %s; closed it", SDATA (p->name));
-#else
error ("SIGPIPE raised on process %s; closed it", SDATA (p->name));
-#endif
}
UNGCPRO;
break;
#endif /* ! defined (SIGCONT) */
case SIGINT:
-#ifdef VMS
- send_process (proc, "\003", 1, Qnil); /* ^C */
- goto whoosh;
-#endif
case SIGQUIT:
-#ifdef VMS
- send_process (proc, "\031", 1, Qnil); /* ^Y */
- goto whoosh;
-#endif
case SIGKILL:
-#ifdef VMS
- sys$forcex (&(p->pid), 0, 1);
- whoosh:
-#endif
flush_pending_output (p->infd);
break;
}
send_process (proc, "", 0, Qnil);
}
-#ifdef VMS
- send_process (proc, "\032", 1, Qnil); /* ^z */
-#else
if (XPROCESS (proc)->pty_flag)
send_process (proc, "\004", 1, Qnil);
else if (EQ (XPROCESS (proc)->type, Qserial))
XPROCESS (proc)->outfd = new_outfd;
}
-#endif /* VMS */
return process;
}
SIGNAL_THREAD_CHECK (signo);
-#ifdef BSD4_1
- extern int sigheld;
- sigheld |= sigbit (SIGCHLD);
-#endif
-
while (1)
{
pid_t pid;
- WAITTYPE w;
+ int w;
Lisp_Object tail;
#ifdef WNOHANG
must reestablish each time */
#if defined (USG) && !defined (POSIX_SIGNALS)
signal (signo, sigchld_handler); /* WARNING - must come after wait3() */
-#endif
-#ifdef BSD4_1
- sigheld &= ~sigbit (SIGCHLD);
- sigrelse (SIGCHLD);
#endif
errno = old_errno;
return;
/* Change the status of the process that was found. */
if (p != 0)
{
- union { int i; WAITTYPE wt; } u;
int clear_desc_flag = 0;
p->tick = ++process_tick;
- u.wt = w;
- p->raw_status = u.i;
+ p->raw_status = w;
p->raw_status_new = 1;
/* If process has terminated, stop waiting for its output. */
#ifdef HAVE_GETSOCKNAME
ADD_SUBFEATURE (QCservice, Qt);
#endif
-#if !defined(TERM) && (defined(O_NONBLOCK) || defined(O_NDELAY))
+#if defined(O_NONBLOCK) || defined(O_NDELAY)
ADD_SUBFEATURE (QCserver, Qt);
#endif
}
#endif /* HAVE_SOCKETS */
-#if defined (DARWIN) || defined (MAC_OSX)
+#if defined (DARWIN)
/* PTYs are broken on Darwin < 6, but are sometimes useful for interactive
processes. As such, we only change the default value. */
if (initialized)
else
error ("select error: %s", emacs_strerror (xerrno));
}
-#ifdef sun
+#ifdef SOLARIS2
else if (nfds > 0 && (waitchannels & 1) && interrupt_input)
/* System sometimes fails to deliver SIGIO. */
kill (getpid (), SIGIO);