#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)
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
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;
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;
}
bool pty_flag = 0;
char pty_name[PTY_NAME_SIZE];
Lisp_Object lisp_pty_name = Qnil;
- Lisp_Object encoded_current_dir;
inchannel = outchannel = -1;
/* 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;
char **volatile new_argv_volatile = new_argv;
int volatile forkin_volatile = forkin;
pid = vfork ();
- encoded_current_dir = encoded_current_dir_volatile;
+ current_dir = current_dir_volatile;
lisp_pty_name = lisp_pty_name_volatile;
new_argv = new_argv_volatile;
forkin = forkin_volatile;
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 */
}
#ifndef WINDOWSNT
/* Wait for child_setup to complete in case that vfork is
actually defined as fork. The descriptor
- XPROCESS (proc)->open_fd[EXEC_MOINTOR_OUTPUT]
+ 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. */
{
}
#endif
- inchannel = p->infd;
-
/* Beware SIGCHLD hereabouts. */
- if (inchannel >= 0)
- flush_pending_output (inchannel);
for (i = 0; i < PROCESS_OPEN_FDS; i++)
close_process_fd (&p->open_fd[i]);
+ inchannel = p->infd;
if (inchannel >= 0)
{
p->infd = -1;
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
static void
handle_child_signal (int sig)
{
- Lisp_Object tail;
+ Lisp_Object tail, proc;
/* Find the process that signaled us, and record its status. */
= (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t)
&& TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM);
Lisp_Object head = XCAR (tail);
- Lisp_Object xpid = XCAR (head);
+ Lisp_Object xpid;
+ if (! CONSP (head))
+ continue;
+ xpid = XCAR (head);
if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid))
{
pid_t deleted_pid;
}
/* 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)
{
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 */