diff options
Diffstat (limited to 'src/process.c')
-rw-r--r-- | src/process.c | 55 |
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'. |