summaryrefslogtreecommitdiff
path: root/src/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c55
1 files changed, 43 insertions, 12 deletions
diff --git a/src/process.c b/src/process.c
index 3beb9cf7146..c3186eed750 100644
--- a/src/process.c
+++ b/src/process.c
@@ -473,8 +473,15 @@ add_read_fd (int fd, fd_callback func, void *data)
fd_callback_info[fd].data = data;
}
+void
+add_non_keyboard_read_fd (int fd, fd_callback func, void *data)
+{
+ add_read_fd(fd, func, data);
+ fd_callback_info[fd].flags &= ~KEYBOARD_FD;
+}
+
static void
-add_non_keyboard_read_fd (int fd)
+add_process_read_fd (int fd)
{
eassert (fd >= 0 && fd < FD_SETSIZE);
eassert (fd_callback_info[fd].func == NULL);
@@ -483,12 +490,6 @@ add_non_keyboard_read_fd (int fd)
fd_callback_info[fd].flags |= FOR_READ;
if (fd > max_desc)
max_desc = fd;
-}
-
-static void
-add_process_read_fd (int fd)
-{
- add_non_keyboard_read_fd (fd);
eassert (0 <= fd && fd < FD_SETSIZE);
fd_callback_info[fd].flags |= PROCESS_FD;
}
@@ -1754,7 +1755,7 @@ usage: (make-process &rest ARGS) */)
buffer's current directory, or its unhandled equivalent. We
can't just have the child check for an error when it does the
chdir, since it's in a vfork. */
- current_dir = encode_current_directory ();
+ current_dir = get_current_directory (true);
name = Fplist_get (contact, QCname);
CHECK_STRING (name);
@@ -1936,7 +1937,7 @@ usage: (make-process &rest ARGS) */)
{
tem = Qnil;
openp (Vexec_path, program, Vexec_suffixes, &tem,
- make_fixnum (X_OK), false);
+ make_fixnum (X_OK), false, false);
if (NILP (tem))
report_file_error ("Searching for program", program);
tem = Fexpand_file_name (tem, Qnil);
@@ -5133,6 +5134,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
Lisp_Object wait_for_cell,
struct Lisp_Process *wait_proc, int just_wait_proc)
{
+ static int last_read_channel = -1;
int channel, nfds;
fd_set Available;
fd_set Writeok;
@@ -5187,6 +5189,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
while (1)
{
bool process_skipped = false;
+ bool wrapped;
+ int channel_start;
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
@@ -5228,7 +5232,10 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
#ifdef HAVE_GNUTLS
/* Continue TLS negotiation. */
if (p->gnutls_initstage == GNUTLS_STAGE_HANDSHAKE_TRIED
- && p->is_non_blocking_client)
+ && p->is_non_blocking_client
+ /* Don't proceed until we have established a connection. */
+ && !(fd_callback_info[p->outfd].flags
+ & NON_BLOCKING_CONNECT_FD))
{
gnutls_try_handshake (p);
p->gnutls_handshakes_tried++;
@@ -5721,8 +5728,21 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
d->func (channel, d->data);
}
- for (channel = 0; channel <= max_desc; channel++)
+ /* Do round robin if `process-pritoritize-lower-fds' is nil. */
+ channel_start
+ = process_prioritize_lower_fds ? 0 : last_read_channel + 1;
+
+ for (channel = channel_start, wrapped = false;
+ !wrapped || (channel < channel_start && channel <= max_desc);
+ channel++)
{
+ if (channel > max_desc)
+ {
+ wrapped = true;
+ channel = -1;
+ continue;
+ }
+
if (FD_ISSET (channel, &Available)
&& ((fd_callback_info[channel].flags & (KEYBOARD_FD | PROCESS_FD))
== PROCESS_FD))
@@ -5760,6 +5780,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
don't try to read from any other processes
before doing the select again. */
FD_ZERO (&Available);
+ last_read_channel = channel;
if (do_display)
redisplay_preserve_echo_area (12);
@@ -8255,7 +8276,7 @@ init_process_emacs (int sockfd)
private SIGCHLD handler, allowing catch_child_signal to copy
it into lib_child_handler.
- Unfortunatly in glib commit 2e471acf, the behavior changed to
+ Unfortunately in glib commit 2e471acf, the behavior changed to
always install a signal handler when g_child_watch_source_new
is called and not just the first time it's called. Glib also
now resets signal handlers to SIG_DFL when it no longer has a
@@ -8476,6 +8497,16 @@ non-nil value means that the delay is not reset on write.
The variable takes effect when `start-process' is called. */);
Vprocess_adaptive_read_buffering = Qt;
+ DEFVAR_BOOL ("process-prioritize-lower-fds", process_prioritize_lower_fds,
+ doc: /* Whether to start checking for subprocess output from first file descriptor.
+Emacs loops through file descriptors to check for output from subprocesses.
+If this variable is nil, the default, then after accepting output from a
+subprocess, Emacs will continue checking the rest of descriptors, starting
+from the one following the descriptor it just read. If this variable is
+non-nil, Emacs will always restart the loop from the first file descriptor,
+thus favoring processes with lower descriptors. */);
+ process_prioritize_lower_fds = 0;
+
DEFVAR_LISP ("interrupt-process-functions", Vinterrupt_process_functions,
doc: /* List of functions to be called for `interrupt-process'.
The arguments of the functions are the same as for `interrupt-process'.