#include <c-ctype.h>
#include <sig2str.h>
+#include <verify.h>
#endif /* subprocesses */
static int num_pending_connects;
#endif /* NON_BLOCKING_CONNECT */
-/* The largest descriptor currently in use for a process object. */
+/* The largest descriptor currently in use for a process object; -1 if none. */
static int max_process_desc;
-/* The largest descriptor currently in use for input. */
+/* The largest descriptor currently in use for input; -1 if none. */
static int max_input_desc;
/* Indexed by descriptor, gives the process (if any) for that descriptor */
#define DATAGRAM_CONN_P(proc) (0)
#endif
+/* FOR_EACH_PROCESS (LIST_VAR, PROC_VAR) followed by a statement is
+ a `for' loop which iterates over processes from Vprocess_alist. */
+
+#define FOR_EACH_PROCESS(list_var, proc_var) \
+ FOR_EACH_ALIST_VALUE (Vprocess_alist, list_var, proc_var)
+
/* These setters are used only in this file, so they can be private. */
static void
pset_buffer (struct Lisp_Process *p, Lisp_Object val)
fd_callback_info[fd].condition |= FOR_WRITE;
}
+/* FD is no longer an input descriptor; update max_input_desc accordingly. */
+
+static void
+delete_input_desc (int fd)
+{
+ if (fd == max_input_desc)
+ {
+ do
+ fd--;
+ while (0 <= fd && ! (FD_ISSET (fd, &input_wait_mask)
+ || FD_ISSET (fd, &write_mask)));
+
+ max_input_desc = fd;
+ }
+}
+
/* Stop monitoring file descriptor FD for when write is possible. */
void
delete_write_fd (int fd)
{
- int lim = max_input_desc;
-
eassert (fd < MAXDESC);
FD_CLR (fd, &write_mask);
fd_callback_info[fd].condition &= ~FOR_WRITE;
{
fd_callback_info[fd].func = 0;
fd_callback_info[fd].data = 0;
-
- if (fd == max_input_desc)
- for (fd = lim; fd >= 0; fd--)
- if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask))
- {
- max_input_desc = fd;
- break;
- }
-
+ delete_input_desc (fd);
}
}
if (fd >= 0)
{
+#ifdef PTY_OPEN
+ /* Set FD's close-on-exec flag. This is needed even if
+ PT_OPEN calls posix_openpt with O_CLOEXEC, since POSIX
+ doesn't require support for that combination.
+ Multithreaded platforms where posix_openpt ignores
+ O_CLOEXEC (or where PTY_OPEN doesn't call posix_openpt)
+ have a race condition between the PTY_OPEN and here. */
+ fcntl (fd, F_SETFD, FD_CLOEXEC);
+#endif
/* check to make certain that both sides are available
this avoids a nasty yet stupid bug in rlogins */
#ifdef PTY_TTY_NAME_SPRINTF
non-Lisp data, so do it only for slots which should not be zero. */
p->infd = -1;
p->outfd = -1;
+ for (i = 0; i < PROCESS_OPEN_FDS; i++)
+ p->open_fd[i] = -1;
#ifdef HAVE_GNUTLS
p->gnutls_initstage = GNUTLS_STAGE_EMPTY;
treated by the SIGCHLD handler and waitpid has been invoked on them;
otherwise they might fill up the kernel's process table.
- Some processes created by call-process are also put onto this list. */
+ Some processes created by call-process are also put onto this list.
+
+ Members of this list are (process-ID . filename) pairs. The
+ process-ID is a number; the filename, if a string, is a file that
+ needs to be removed after the process exits. */
static Lisp_Object deleted_pid_list;
void
-record_deleted_pid (pid_t pid)
+record_deleted_pid (pid_t pid, Lisp_Object filename)
{
- deleted_pid_list = Fcons (make_fixnum_or_float (pid),
+ deleted_pid_list = Fcons (Fcons (make_fixnum_or_float (pid), filename),
/* GC treated elements set to nil. */
Fdelq (Qnil, deleted_pid_list));
else
{
if (p->alive)
- record_kill_process (p);
+ record_kill_process (p, Qnil);
if (p->infd >= 0)
{
DEFUN ("set-process-window-size", Fset_process_window_size,
Sset_process_window_size, 3, 3, 0,
doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH. */)
- (register Lisp_Object process, Lisp_Object height, Lisp_Object width)
+ (Lisp_Object process, Lisp_Object height, Lisp_Object width)
{
CHECK_PROCESS (process);
- CHECK_RANGED_INTEGER (height, 0, INT_MAX);
- CHECK_RANGED_INTEGER (width, 0, INT_MAX);
+
+ /* All known platforms store window sizes as 'unsigned short'. */
+ CHECK_RANGED_INTEGER (height, 0, USHRT_MAX);
+ CHECK_RANGED_INTEGER (width, 0, USHRT_MAX);
if (XPROCESS (process)->infd < 0
- || set_window_size (XPROCESS (process)->infd,
- XINT (height), XINT (width)) <= 0)
+ || (set_window_size (XPROCESS (process)->infd,
+ XINT (height), XINT (width))
+ < 0))
return Qnil;
else
return Qt;
}
DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0,
- doc: /* Return a list of all processes. */)
+ doc: /* Return a list of all processes that are Emacs sub-processes. */)
(void)
{
return Fmapcar (Qcdr, Vprocess_alist);
function. The argument list is protected by the caller, so all
we really have to worry about is buffer. */
{
- struct gcpro gcpro1, gcpro2;
-
- current_dir = BVAR (current_buffer, directory);
-
- GCPRO2 (buffer, current_dir);
-
- current_dir = Funhandled_file_name_directory (current_dir);
- if (NILP (current_dir))
- /* If the file name handler says that current_dir is unreachable, use
- a sensible default. */
- current_dir = build_string ("~/");
- current_dir = expand_and_dir_to_file (current_dir, Qnil);
- if (NILP (Ffile_accessible_directory_p (current_dir)))
- report_file_error ("Setting current directory",
- BVAR (current_buffer, directory));
-
+ struct gcpro gcpro1;
+ GCPRO1 (buffer);
+ current_dir = encode_current_directory ();
UNGCPRO;
}
remove_process (proc);
}
+/* If *FD_ADDR is nonnegative, close it, and mark it as closed. */
+
static void
-create_process_1 (struct atimer *timer)
+close_process_fd (int *fd_addr)
{
- /* Nothing to do. */
+ int fd = *fd_addr;
+ if (0 <= fd)
+ {
+ *fd_addr = -1;
+ emacs_close (fd);
+ }
}
+/* Indexes of file descriptors in open_fds. */
+enum
+ {
+ /* The pipe from Emacs to its subprocess. */
+ SUBPROCESS_STDIN,
+ WRITE_TO_SUBPROCESS,
+
+ /* The main pipe from the subprocess to Emacs. */
+ READ_FROM_SUBPROCESS,
+ SUBPROCESS_STDOUT,
+
+ /* The pipe from the subprocess to Emacs that is closed when the
+ subprocess execs. */
+ READ_FROM_EXEC_MONITOR,
+ EXEC_MONITOR_OUTPUT
+ };
+
+verify (PROCESS_OPEN_FDS == EXEC_MONITOR_OUTPUT + 1);
static void
create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
{
+ struct Lisp_Process *p = XPROCESS (process);
int inchannel, outchannel;
pid_t pid;
int vfork_errno;
- int sv[2];
-#ifndef WINDOWSNT
- int wait_child_setup[2];
-#endif
int forkin, forkout;
bool pty_flag = 0;
char pty_name[PTY_NAME_SIZE];
Lisp_Object lisp_pty_name = Qnil;
- Lisp_Object encoded_current_dir;
inchannel = outchannel = -1;
if (inchannel >= 0)
{
+ p->open_fd[READ_FROM_SUBPROCESS] = inchannel;
#if ! defined (USG) || defined (USG_SUBTTY_WORKS)
/* On most USG systems it does not work to open the pty's tty here,
then close it and reopen it in the child. */
forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0);
if (forkin < 0)
report_file_error ("Opening pty", Qnil);
+ p->open_fd[SUBPROCESS_STDIN] = forkin;
#else
forkin = forkout = -1;
#endif /* not USG, or USG_SUBTTY_WORKS */
}
else
{
- if (emacs_pipe (sv) != 0)
+ if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0
+ || emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0)
report_file_error ("Creating pipe", Qnil);
- inchannel = sv[0];
- forkout = sv[1];
- if (emacs_pipe (sv) != 0)
- {
- int pipe_errno = errno;
- emacs_close (inchannel);
- emacs_close (forkout);
- report_file_errno ("Creating pipe", Qnil, pipe_errno);
- }
- outchannel = sv[1];
- forkin = sv[0];
+ forkin = p->open_fd[SUBPROCESS_STDIN];
+ outchannel = p->open_fd[WRITE_TO_SUBPROCESS];
+ inchannel = p->open_fd[READ_FROM_SUBPROCESS];
+ forkout = p->open_fd[SUBPROCESS_STDOUT];
}
#ifndef WINDOWSNT
- if (emacs_pipe (wait_child_setup) != 0)
+ if (emacs_pipe (p->open_fd + READ_FROM_EXEC_MONITOR) != 0)
report_file_error ("Creating pipe", Qnil);
#endif
/* Record this as an active process, with its channels. */
chan_process[inchannel] = process;
- XPROCESS (process)->infd = inchannel;
- XPROCESS (process)->outfd = outchannel;
+ p->infd = inchannel;
+ p->outfd = outchannel;
/* Previously we recorded the tty descriptor used in the subprocess.
It was only used for getting the foreground tty process, so now
we just reopen the device (see emacs_get_tty_pgrp) as this is
more portable (see USG_SUBTTY_WORKS above). */
- XPROCESS (process)->pty_flag = pty_flag;
- pset_status (XPROCESS (process), Qrun);
+ p->pty_flag = pty_flag;
+ pset_status (p, Qrun);
FD_SET (inchannel, &input_wait_mask);
FD_SET (inchannel, &non_keyboard_wait_mask);
/* This may signal an error. */
setup_process_coding_systems (process);
- encoded_current_dir = ENCODE_FILE (current_dir);
-
block_input ();
block_child_signal ();
#ifndef WINDOWSNT
/* vfork, and prevent local vars from being clobbered by the vfork. */
{
- Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir;
+ Lisp_Object volatile current_dir_volatile = current_dir;
Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name;
- Lisp_Object volatile process_volatile = process;
char **volatile new_argv_volatile = new_argv;
int volatile forkin_volatile = forkin;
int volatile forkout_volatile = forkout;
- int volatile wait_child_setup_0_volatile = wait_child_setup[0];
- int volatile wait_child_setup_1_volatile = wait_child_setup[1];
+ struct Lisp_Process *p_volatile = p;
pid = vfork ();
- encoded_current_dir = encoded_current_dir_volatile;
+ current_dir = current_dir_volatile;
lisp_pty_name = lisp_pty_name_volatile;
- process = process_volatile;
new_argv = new_argv_volatile;
forkin = forkin_volatile;
forkout = forkout_volatile;
- wait_child_setup[0] = wait_child_setup_0_volatile;
- wait_child_setup[1] = wait_child_setup_1_volatile;
+ p = p_volatile;
- pty_flag = XPROCESS (process)->pty_flag;
+ pty_flag = p->pty_flag;
}
if (pid == 0)
if (pty_flag)
child_setup_tty (xforkout);
#ifdef WINDOWSNT
- pid = child_setup (xforkin, xforkout, xforkout,
- new_argv, 1, encoded_current_dir);
+ pid = child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir);
#else /* not WINDOWSNT */
- child_setup (xforkin, xforkout, xforkout,
- new_argv, 1, encoded_current_dir);
+ child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir);
#endif /* not WINDOWSNT */
}
/* Back in the parent process. */
vfork_errno = errno;
- XPROCESS (process)->pid = pid;
+ p->pid = pid;
if (pid >= 0)
- XPROCESS (process)->alive = 1;
+ p->alive = 1;
/* Stop blocking in the parent. */
unblock_child_signal ();
unblock_input ();
if (pid < 0)
- {
- if (forkin >= 0)
- emacs_close (forkin);
- if (forkin != forkout && forkout >= 0)
- emacs_close (forkout);
- report_file_errno ("Doing vfork", Qnil, vfork_errno);
- }
+ report_file_errno ("Doing vfork", Qnil, vfork_errno);
else
{
/* vfork succeeded. */
+ /* Close the pipe ends that the child uses, or the child's pty. */
+ close_process_fd (&p->open_fd[SUBPROCESS_STDIN]);
+ close_process_fd (&p->open_fd[SUBPROCESS_STDOUT]);
+
#ifdef WINDOWSNT
register_child (pid, inchannel);
#endif /* WINDOWSNT */
- /* If the subfork execv fails, and it exits,
- this close hangs. I don't know why.
- So have an interrupt jar it loose. */
- {
- struct atimer *timer;
- EMACS_TIME offset = make_emacs_time (1, 0);
-
- stop_polling ();
- timer = start_atimer (ATIMER_RELATIVE, offset, create_process_1, 0);
-
- if (forkin >= 0)
- emacs_close (forkin);
-
- cancel_atimer (timer);
- start_polling ();
- }
-
- if (forkin != forkout && forkout >= 0)
- emacs_close (forkout);
-
- pset_tty_name (XPROCESS (process), lisp_pty_name);
+ pset_tty_name (p, lisp_pty_name);
#ifndef WINDOWSNT
/* Wait for child_setup to complete in case that vfork is
- actually defined as fork. The descriptor wait_child_setup[1]
+ actually defined as fork. The descriptor
+ XPROCESS (proc)->open_fd[EXEC_MONITOR_OUTPUT]
of a pipe is closed at the child side either by close-on-exec
on successful execve 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]);
+ close_process_fd (&p->open_fd[EXEC_MONITOR_OUTPUT]);
+ emacs_read (p->open_fd[READ_FROM_EXEC_MONITOR], &dummy, 1);
+ close_process_fd (&p->open_fd[READ_FROM_EXEC_MONITOR]);
}
#endif
}
static void
create_pty (Lisp_Object process)
{
+ struct Lisp_Process *p = XPROCESS (process);
char pty_name[PTY_NAME_SIZE];
- int inchannel, outchannel;
-
- inchannel = outchannel = -1;
-
- if (!NILP (Vprocess_connection_type))
- outchannel = inchannel = allocate_pty (pty_name);
+ int pty_fd = NILP (Vprocess_connection_type) ? -1 : allocate_pty (pty_name);
- if (inchannel >= 0)
+ if (pty_fd >= 0)
{
+ p->open_fd[SUBPROCESS_STDIN] = pty_fd;
#if ! defined (USG) || defined (USG_SUBTTY_WORKS)
/* On most USG systems it does not work to open the pty's tty here,
then close it and reopen it in the child. */
int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0);
if (forkout < 0)
report_file_error ("Opening pty", Qnil);
+ p->open_fd[WRITE_TO_SUBPROCESS] = forkout;
#if defined (DONT_REOPEN_PTY)
/* In the case that vfork is defined as fork, the parent process
(Emacs) may send some data before the child process completes
#endif /* DONT_REOPEN_PTY */
#endif /* not USG, or USG_SUBTTY_WORKS */
- fcntl (inchannel, F_SETFL, O_NONBLOCK);
- fcntl (outchannel, F_SETFL, O_NONBLOCK);
+ fcntl (pty_fd, F_SETFL, O_NONBLOCK);
/* Record this as an active process, with its channels.
As a result, child_setup will close Emacs's side of the pipes. */
- chan_process[inchannel] = process;
- XPROCESS (process)->infd = inchannel;
- XPROCESS (process)->outfd = outchannel;
+ chan_process[pty_fd] = process;
+ p->infd = pty_fd;
+ p->outfd = pty_fd;
/* Previously we recorded the tty descriptor used in the subprocess.
It was only used for getting the foreground tty process, so now
we just reopen the device (see emacs_get_tty_pgrp) as this is
more portable (see USG_SUBTTY_WORKS above). */
- XPROCESS (process)->pty_flag = 1;
- pset_status (XPROCESS (process), Qrun);
+ p->pty_flag = 1;
+ pset_status (p, Qrun);
setup_process_coding_systems (process);
- FD_SET (inchannel, &input_wait_mask);
- FD_SET (inchannel, &non_keyboard_wait_mask);
- if (inchannel > max_process_desc)
- max_process_desc = inchannel;
+ FD_SET (pty_fd, &input_wait_mask);
+ FD_SET (pty_fd, &non_keyboard_wait_mask);
+ if (pty_fd > max_process_desc)
+ max_process_desc = pty_fd;
- pset_tty_name (XPROCESS (process), build_string (pty_name));
+ pset_tty_name (p, build_string (pty_name));
}
- XPROCESS (process)->pid = -2;
+ p->pid = -2;
}
\f
p = XPROCESS (proc);
fd = serial_open (port);
+ p->open_fd[SUBPROCESS_STDIN] = fd;
p->infd = fd;
p->outfd = fd;
if (fd > max_process_desc)
}
#endif
- /* Discard the unwind protect for closing S, if any. */
- specpdl_ptr = specpdl + count1;
-
- /* Unwind bind_polling_period and request_sigio. */
- unbind_to (count, Qnil);
-
if (s < 0)
{
/* If non-blocking got this far - and failed - assume non-blocking is
if ((tem = Fplist_get (contact, QCstop), !NILP (tem)))
pset_command (p, Qt);
p->pid = 0;
+
+ p->open_fd[SUBPROCESS_STDIN] = inch;
p->infd = inch;
p->outfd = outch;
+
+ /* Discard the unwind protect for closing S, if any. */
+ specpdl_ptr = specpdl + count1;
+
+ /* Unwind bind_polling_period and request_sigio. */
+ unbind_to (count, Qnil);
+
if (is_server && socktype != SOCK_DGRAM)
pset_status (p, Qlisten);
static void
deactivate_process (Lisp_Object proc)
{
- register int inchannel, outchannel;
- register struct Lisp_Process *p = XPROCESS (proc);
+ int inchannel;
+ struct Lisp_Process *p = XPROCESS (proc);
+ int i;
#ifdef HAVE_GNUTLS
/* Delete GnuTLS structures in PROC, if any. */
emacs_gnutls_deinit (proc);
#endif /* HAVE_GNUTLS */
- inchannel = p->infd;
- outchannel = p->outfd;
-
#ifdef ADAPTIVE_READ_BUFFERING
if (p->read_output_delay > 0)
{
}
#endif
+ /* Beware SIGCHLD hereabouts. */
+
+ for (i = 0; i < PROCESS_OPEN_FDS; i++)
+ close_process_fd (&p->open_fd[i]);
+
+ inchannel = p->infd;
if (inchannel >= 0)
{
- /* Beware SIGCHLD hereabouts. */
- flush_pending_output (inchannel);
- emacs_close (inchannel);
- if (outchannel >= 0 && outchannel != inchannel)
- emacs_close (outchannel);
-
p->infd = -1;
p->outfd = -1;
#ifdef DATAGRAM_SOCKETS
#endif
if (inchannel == max_process_desc)
{
- int i;
/* We just closed the highest-numbered process input descriptor,
so recompute the highest-numbered one now. */
- max_process_desc = 0;
- for (i = 0; i < MAXDESC; i++)
- if (!NILP (chan_process[i]))
- max_process_desc = i;
+ int i = inchannel;
+ do
+ i--;
+ while (0 <= i && NILP (chan_process[i]));
+
+ max_process_desc = i;
}
}
}
/* Discard the unwind protect for closing S. */
specpdl_ptr = specpdl + count;
+ p->open_fd[SUBPROCESS_STDIN] = s;
p->infd = s;
p->outfd = s;
pset_status (p, Qrun);
#endif
(max (max_process_desc, max_input_desc) + 1,
&Available,
- (check_write ? &Writeok : (SELECT_TYPE *)0),
+ (check_write ? &Writeok : 0),
NULL, &timeout, NULL);
#ifdef HAVE_GNUTLS
return;
}
- switch (signo)
- {
#ifdef SIGCONT
- case SIGCONT:
+ if (signo == SIGCONT)
+ {
p->raw_status_new = 0;
pset_status (p, Qrun);
p->tick = ++process_tick;
status_notify (NULL);
redisplay_preserve_echo_area (13);
}
- break;
-#endif /* ! defined (SIGCONT) */
- case SIGINT:
- case SIGQUIT:
- case SIGKILL:
- flush_pending_output (p->infd);
- break;
}
+#endif
/* If we don't have process groups, send the signal to the immediate
subprocess. That isn't really right, but it's better than any
}
else
{
- int old_outfd, new_outfd;
+ int old_outfd = XPROCESS (proc)->outfd;
+ int new_outfd;
#ifdef HAVE_SHUTDOWN
/* If this is a network connection, or socketpair is used
(In some old system, shutdown to socketpair doesn't work.
Then we just can't win.) */
if (EQ (XPROCESS (proc)->type, Qnetwork)
- || XPROCESS (proc)->outfd == XPROCESS (proc)->infd)
- shutdown (XPROCESS (proc)->outfd, 1);
- /* In case of socketpair, outfd == infd, so don't close it. */
- if (XPROCESS (proc)->outfd != XPROCESS (proc)->infd)
- emacs_close (XPROCESS (proc)->outfd);
-#else /* not HAVE_SHUTDOWN */
- emacs_close (XPROCESS (proc)->outfd);
-#endif /* not HAVE_SHUTDOWN */
+ || XPROCESS (proc)->infd == old_outfd)
+ shutdown (old_outfd, 1);
+#endif
+ close_process_fd (&XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS]);
new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0);
if (new_outfd < 0)
- emacs_abort ();
- old_outfd = XPROCESS (proc)->outfd;
+ report_file_error ("Opening null device", Qnil);
+ XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS] = new_outfd;
+ XPROCESS (proc)->outfd = new_outfd;
if (!proc_encode_coding_system[new_outfd])
proc_encode_coding_system[new_outfd]
= *proc_encode_coding_system[old_outfd];
memset (proc_encode_coding_system[old_outfd], 0,
sizeof (struct coding_system));
-
- XPROCESS (proc)->outfd = new_outfd;
}
return process;
}
static void
handle_child_signal (int sig)
{
- Lisp_Object tail;
+ Lisp_Object tail, proc;
/* Find the process that signaled us, and record its status. */
bool all_pids_are_fixnums
= (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t)
&& TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM);
- Lisp_Object xpid = XCAR (tail);
+ Lisp_Object head = XCAR (tail);
+ Lisp_Object xpid;
+ if (! CONSP (head))
+ continue;
+ xpid = XCAR (head);
if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid))
{
pid_t deleted_pid;
else
deleted_pid = XFLOAT_DATA (xpid);
if (child_status_changed (deleted_pid, 0, 0))
- XSETCAR (tail, Qnil);
+ {
+ if (STRINGP (XCDR (head)))
+ unlink (SSDATA (XCDR (head)));
+ XSETCAR (tail, Qnil);
+ }
}
}
/* Otherwise, if it is asynchronous, it is in Vprocess_alist. */
- for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
+ FOR_EACH_PROCESS (tail, proc)
{
- Lisp_Object proc = XCDR (XCAR (tail));
struct Lisp_Process *p = XPROCESS (proc);
int status;
that we run, we get called again to handle their status changes. */
update_tick = process_tick;
- for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
+ FOR_EACH_PROCESS (tail, proc)
{
Lisp_Object symbol;
- register struct Lisp_Process *p;
-
- proc = Fcdr (XCAR (tail));
- p = XPROCESS (proc);
+ register struct Lisp_Process *p = XPROCESS (proc);
if (p->tick != p->update_tick)
{
delete_keyboard_wait_descriptor (int desc)
{
#ifdef subprocesses
- int fd;
- int lim = max_input_desc;
-
FD_CLR (desc, &input_wait_mask);
FD_CLR (desc, &non_process_wait_mask);
-
- if (desc == max_input_desc)
- for (fd = 0; fd < lim; fd++)
- if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask))
- max_input_desc = fd;
+ delete_input_desc (desc);
#endif
}
buf = Fget_buffer (buffer);
if (NILP (buf)) return Qnil;
- for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
- {
- proc = Fcdr (XCAR (tail));
- if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf))
- return proc;
- }
+ FOR_EACH_PROCESS (tail, proc)
+ if (EQ (XPROCESS (proc)->buffer, buf))
+ return proc;
#endif /* subprocesses */
return Qnil;
}
#ifdef subprocesses
Lisp_Object tail, proc;
- for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
- {
- proc = XCDR (XCAR (tail));
- if (PROCESSP (proc)
- && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)))
- {
- if (NETCONN_P (proc) || SERIALCONN_P (proc))
- Fdelete_process (proc);
- else if (XPROCESS (proc)->infd >= 0)
- process_send_signal (proc, SIGHUP, Qnil, 1);
- }
- }
+ FOR_EACH_PROCESS (tail, proc)
+ if (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer))
+ {
+ if (NETCONN_P (proc) || SERIALCONN_P (proc))
+ Fdelete_process (proc);
+ else if (XPROCESS (proc)->infd >= 0)
+ process_send_signal (proc, SIGHUP, Qnil, 1);
+ }
#else /* subprocesses */
/* Since we have no subprocesses, this does nothing. */
#endif /* subprocesses */
FD_ZERO (&non_keyboard_wait_mask);
FD_ZERO (&non_process_wait_mask);
FD_ZERO (&write_mask);
- max_process_desc = 0;
+ max_process_desc = max_input_desc = -1;
memset (fd_callback_info, 0, sizeof (fd_callback_info));
#ifdef NON_BLOCKING_CONNECT