static SELECT_TYPE non_process_wait_mask;
+#ifdef NON_BLOCKING_CONNECT
/* Mask of bits indicating the descriptors that we wait for connect to
complete on. Once they complete, they are removed from this mask
and added to the input_wait_mask and non_keyboard_wait_mask. */
/* Number of bits set in connect_wait_mask. */
static int num_pending_connects;
+#define IF_NON_BLOCKING_CONNECT(s) s
+#else
+#define IF_NON_BLOCKING_CONNECT(s)
+#endif
+
/* The largest descriptor currently in use for a process object. */
static int max_process_desc;
int xerrno = 0;
int s = -1, outch, inch;
struct gcpro gcpro1;
- int retry = 0;
int count = SPECPDL_INDEX ();
int count1;
Lisp_Object QCaddress; /* one of QClocal or QCremote */
{
int optn, optbits;
+ retry_connect:
+
s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
if (s < 0)
{
break;
}
- retry_connect:
-
immediate_quit = 1;
QUIT;
immediate_quit = 0;
- if (xerrno == EINTR)
- goto retry_connect;
- if (xerrno == EADDRINUSE && retry < 20)
- {
- /* A delay here is needed on some FreeBSD systems,
- and it is harmless, since this retrying takes time anyway
- and should be infrequent. */
- Fsleep_for (make_number (1), Qnil);
- retry++;
- goto retry_connect;
- }
-
/* Discard the unwind protect closing S. */
specpdl_ptr = specpdl + count1;
emacs_close (s);
s = -1;
+
+ if (xerrno == EINTR)
+ goto retry_connect;
}
if (s >= 0)
chan_process[inchannel] = Qnil;
FD_CLR (inchannel, &input_wait_mask);
FD_CLR (inchannel, &non_keyboard_wait_mask);
+#ifdef NON_BLOCKING_CONNECT
if (FD_ISSET (inchannel, &connect_wait_mask))
{
FD_CLR (inchannel, &connect_wait_mask);
if (--num_pending_connects < 0)
abort ();
}
+#endif
if (inchannel == max_process_desc)
{
int i;
}
\f
DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output,
- 0, 3, 0,
+ 0, 4, 0,
doc: /* Allow any pending output from subprocesses to be read by Emacs.
It is read into the process' buffers or given to their filter functions.
Non-nil arg PROCESS means do not return until some output has been received
Non-nil second arg TIMEOUT and third arg TIMEOUT-MSECS are number of
seconds and microseconds to wait; return after that much time whether
or not there is input.
+If optional fourth arg JUST-THIS-ONE is non-nil, only accept output
+from PROCESS, suspending reading output from other processes.
+If JUST-THIS-ONE is an integer, don't run any timers either.
Return non-nil iff we received any output before the timeout expired. */)
- (process, timeout, timeout_msecs)
- register Lisp_Object process, timeout, timeout_msecs;
+ (process, timeout, timeout_msecs, just_this_one)
+ register Lisp_Object process, timeout, timeout_msecs, just_this_one;
{
int seconds;
int useconds;
if (! NILP (process))
CHECK_PROCESS (process);
+ else
+ just_this_one = Qnil;
if (! NILP (timeout_msecs))
{
else
seconds = NILP (process) ? -1 : 0;
- if (NILP (process))
- XSETFASTINT (process, 0);
-
return
- (wait_reading_process_input (seconds, useconds, process, 0)
+ (wait_reading_process_output (seconds, useconds, 0, 0,
+ Qnil,
+ !NILP (process) ? XPROCESS (process) : NULL,
+ NILP (just_this_one) ? 0 :
+ !INTEGERP (just_this_one) ? 1 : -1)
? Qt : Qnil);
}
lisp code is being evalled.
This is also used in record_asynch_buffer_change.
For that purpose, this must be 0
- when not inside wait_reading_process_input. */
+ when not inside wait_reading_process_output. */
static int waiting_for_user_input_p;
/* This is here so breakpoints can be put on it. */
static void
-wait_reading_process_input_1 ()
+wait_reading_process_output_1 ()
{
}
1 to return when input is available, or
-1 meaning caller will actually read the input, so don't throw to
the quit handler, or
- a cons cell, meaning wait until its car is non-nil
- (and gobble terminal input into the buffer if any arrives), or
- a process object, meaning wait until something arrives from that
- process. The return value is true iff we read some input from
- that process.
DO_DISPLAY != 0 means redisplay should be done to show subprocess
- output that arrives.
+ output that arrives.
+
+ If WAIT_FOR_CELL is a cons cell, wait until its car is non-nil
+ (and gobble terminal input into the buffer if any arrives).
+
+ If WAIT_PROC is specified, wait until something arrives from that
+ process. The return value is true iff we read some input from
+ that process.
- If READ_KBD is a pointer to a struct Lisp_Process, then the
- function returns true iff we received input from that process
- before the timeout elapsed.
+ If JUST_WAIT_PROC is non-nil, handle only output from WAIT_PROC
+ (suspending output from other processes). A negative value
+ means don't run any timers either.
+
+ If WAIT_PROC is specified, then the function returns true iff we
+ received input from that process before the timeout elapsed.
Otherwise, return true iff we received input from any process. */
int
-wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
- int time_limit, microsecs;
- Lisp_Object read_kbd;
- int do_display;
+wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
+ wait_for_cell, wait_proc, just_wait_proc)
+ int time_limit, microsecs, read_kbd, do_display;
+ Lisp_Object wait_for_cell;
+ struct Lisp_Process *wait_proc;
+ int just_wait_proc;
{
register int channel, nfds;
SELECT_TYPE Available;
+#ifdef NON_BLOCKING_CONNECT
SELECT_TYPE Connecting;
- int check_connect, check_delay, no_avail;
+ int check_connect;
+#endif
+ int check_delay, no_avail;
int xerrno;
Lisp_Object proc;
EMACS_TIME timeout, end_time;
int wait_channel = -1;
- struct Lisp_Process *wait_proc = 0;
int got_some_input = 0;
/* Either nil or a cons cell, the car of which is of interest and
may be changed outside of this routine. */
- Lisp_Object wait_for_cell = Qnil;
int saved_waiting_for_user_input_p = waiting_for_user_input_p;
FD_ZERO (&Available);
+#ifdef NON_BLOCKING_CONNECT
FD_ZERO (&Connecting);
+#endif
- /* If read_kbd is a process to watch, set wait_proc and wait_channel
- accordingly. */
- if (PROCESSP (read_kbd))
- {
- wait_proc = XPROCESS (read_kbd);
- wait_channel = XINT (wait_proc->infd);
- XSETFASTINT (read_kbd, 0);
- }
+ /* If wait_proc is a process to watch, set wait_channel accordingly. */
+ if (wait_proc != NULL)
+ wait_channel = XINT (wait_proc->infd);
- /* If waiting for non-nil in a cell, record where. */
- if (CONSP (read_kbd))
- {
- wait_for_cell = read_kbd;
- XSETFASTINT (read_kbd, 0);
- }
-
- waiting_for_user_input_p = XINT (read_kbd);
+ waiting_for_user_input_p = read_kbd;
/* Since we may need to wait several times,
compute the absolute time to return at. */
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
Otherwise, do pending quit if requested. */
- if (XINT (read_kbd) >= 0)
+ if (read_kbd >= 0)
QUIT;
#ifdef SYNC_INPUT
else if (interrupt_input_pending)
But not if wait_for_cell; in those cases,
the wait is supposed to be short,
and those callers cannot handle running arbitrary Lisp code here. */
- if (NILP (wait_for_cell))
+ if (NILP (wait_for_cell)
+ && just_wait_proc >= 0)
{
EMACS_TIME timer_delay;
while (!detect_input_pending ());
/* If there is unread keyboard input, also return. */
- if (XINT (read_kbd) != 0
+ if (read_kbd != 0
&& requeued_events_pending_p ())
break;
else if (time_limit != -1)
{
/* This is so a breakpoint can be put here. */
- wait_reading_process_input_1 ();
+ wait_reading_process_output_1 ();
}
}
It is important that we do this before checking for process
activity. If we get a SIGCHLD after the explicit checks for
process activity, timeout is the only way we will know. */
- if (XINT (read_kbd) < 0)
+ if (read_kbd < 0)
set_waiting_for_input (&timeout);
/* If status of something has changed, and no input is
timeout to get our attention. */
if (update_tick != process_tick && do_display)
{
- SELECT_TYPE Atemp, Ctemp;
+ SELECT_TYPE Atemp;
+#ifdef NON_BLOCKING_CONNECT
+ SELECT_TYPE Ctemp;
+#endif
Atemp = input_wait_mask;
-#ifdef MAC_OSX
- /* On Mac OS X, the SELECT system call always says input is
+#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. */
+ subprocesses are incorrectly discarded.
+ */
FD_CLR (0, &Atemp);
#endif
- Ctemp = connect_wait_mask;
+ IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask);
+
EMACS_SET_SECS_USECS (timeout, 0, 0);
if ((select (max (max_process_desc, max_keyboard_desc) + 1,
&Atemp,
+#ifdef NON_BLOCKING_CONNECT
(num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0),
+#else
+ (SELECT_TYPE *)0,
+#endif
(SELECT_TYPE *)0, &timeout)
<= 0))
{
/* Wait till there is something to do */
- if (!NILP (wait_for_cell))
+ if (wait_proc && just_wait_proc)
+ {
+ if (XINT (wait_proc->infd) < 0) /* Terminated */
+ break;
+ FD_SET (XINT (wait_proc->infd), &Available);
+ check_delay = 0;
+ IF_NON_BLOCKING_CONNECT (check_connect = 0);
+ }
+ else if (!NILP (wait_for_cell))
{
Available = non_process_wait_mask;
- check_connect = check_delay = 0;
+ check_delay = 0;
+ IF_NON_BLOCKING_CONNECT (check_connect = 0);
}
else
{
- if (! XINT (read_kbd))
+ if (! read_kbd)
Available = non_keyboard_wait_mask;
else
Available = input_wait_mask;
- check_connect = (num_pending_connects > 0);
+ IF_NON_BLOCKING_CONNECT (check_connect = (num_pending_connects > 0));
check_delay = wait_channel >= 0 ? 0 : process_output_delay_count;
}
{
clear_waiting_for_input ();
redisplay_preserve_echo_area (11);
- if (XINT (read_kbd) < 0)
+ if (read_kbd < 0)
set_waiting_for_input (&timeout);
}
no_avail = 0;
- if (XINT (read_kbd) && detect_input_pending ())
+ if (read_kbd && detect_input_pending ())
{
nfds = 0;
no_avail = 1;
}
else
{
+#ifdef NON_BLOCKING_CONNECT
if (check_connect)
Connecting = connect_wait_mask;
+#endif
#ifdef ADAPTIVE_READ_BUFFERING
if (process_output_skip && check_delay > 0)
nfds = select (max (max_process_desc, max_keyboard_desc) + 1,
&Available,
+#ifdef NON_BLOCKING_CONNECT
(check_connect ? &Connecting : (SELECT_TYPE *)0),
+#else
+ (SELECT_TYPE *)0,
+#endif
(SELECT_TYPE *)0, &timeout);
}
if (no_avail)
{
FD_ZERO (&Available);
- check_connect = 0;
+ IF_NON_BLOCKING_CONNECT (check_connect = 0);
}
#if defined(sun) && !defined(USG5_4)
/* If we are using polling for input,
and we see input available, make it get read now.
Otherwise it might not actually get read for a second.
- And on hpux, since we turn off polling in wait_reading_process_input,
+ And on hpux, since we turn off polling in wait_reading_process_output,
it might never get read at all if we don't spend much time
- outside of wait_reading_process_input. */
- if (XINT (read_kbd) && interrupt_input
+ outside of wait_reading_process_output. */
+ if (read_kbd && interrupt_input
&& keyboard_bit_set (&Available)
&& input_polling_used ())
kill (getpid (), SIGALRM);
/* If there is any, return immediately
to give it higher priority than subprocesses */
- if (XINT (read_kbd) != 0)
+ if (read_kbd != 0)
{
int old_timers_run = timers_run;
struct buffer *old_buffer = current_buffer;
}
/* If there is unread keyboard input, also return. */
- if (XINT (read_kbd) != 0
+ if (read_kbd != 0
&& requeued_events_pending_p ())
break;
That would causes delays in pasting selections, for example.
(We used to do this only if wait_for_cell.) */
- if (XINT (read_kbd) == 0 && detect_input_pending ())
+ if (read_kbd == 0 && detect_input_pending ())
{
swallow_events (do_display);
#if 0 /* Exiting when read_kbd doesn't request that seems wrong, though. */
In that case, there really is no input and no SIGIO,
but select says there is input. */
- if (XINT (read_kbd) && interrupt_input
+ if (read_kbd && interrupt_input
&& keyboard_bit_set (&Available) && ! noninteractive)
kill (getpid (), SIGIO);
#endif
/* If checking input just got us a size-change event from X,
obey it now if we should. */
- if (XINT (read_kbd) || ! NILP (wait_for_cell))
+ if (read_kbd || ! NILP (wait_for_cell))
do_pending_window_change (0);
/* Check for data from a process. */
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
Otherwise, do pending quit if requested. */
- if (XINT (read_kbd) >= 0)
+ if (read_kbd >= 0)
{
/* Prevent input_pending from remaining set if we quit. */
clear_input_pending ();
if (DATAGRAM_CHAN_P (channel))
{
int len = datagram_address[channel].len;
- nbytes = recvfrom (channel, chars + carryover, readmax - carryover,
+ nbytes = recvfrom (channel, chars + carryover, readmax,
0, datagram_address[channel].sa, &len);
}
else
#endif
if (proc_buffered_char[channel] < 0)
{
- nbytes = emacs_read (channel, chars + carryover, readmax - carryover);
+ nbytes = emacs_read (channel, chars + carryover, readmax);
#ifdef ADAPTIVE_READ_BUFFERING
- if (!NILP (p->adaptive_read_buffering))
+ if (nbytes > 0 && !NILP (p->adaptive_read_buffering))
{
int delay = XINT (p->read_output_delay);
if (nbytes < 256)
delay += READ_OUTPUT_DELAY_INCREMENT * 2;
}
}
- else if (delay > 0 && (nbytes == readmax - carryover))
+ else if (delay > 0 && (nbytes == readmax))
{
delay -= READ_OUTPUT_DELAY_INCREMENT;
if (delay == 0)
{
chars[carryover] = proc_buffered_char[channel];
proc_buffered_char[channel] = -1;
- nbytes = emacs_read (channel, chars + carryover + 1, readmax - 1 - carryover);
+ nbytes = emacs_read (channel, chars + carryover + 1, readmax - 1);
if (nbytes < 0)
nbytes = 1;
else
SIGTYPE
send_process_trap ()
{
+ SIGNAL_THREAD_CHECK (SIGPIPE);
#ifdef BSD4_1
sigrelse (SIGPIPE);
sigrelse (SIGALRM);
object = p->encoding_buf;
encode_coding (coding, (char *) buf, SDATA (object),
len, SBYTES (object));
+ coding_free_composition_data (coding);
len = coding->produced;
buf = SDATA (object);
}
that may allow the program
to finish doing output and read more. */
{
- Lisp_Object zero;
int offset = 0;
#ifdef BROKEN_PTY_READ_AFTER_EAGAIN
else if (STRINGP (object))
offset = buf - SDATA (object);
- XSETFASTINT (zero, 0);
#ifdef EMACS_HAS_USECS
- wait_reading_process_input (0, 20000, zero, 0);
+ wait_reading_process_output (0, 20000, 0, 0, Qnil, NULL, 0);
#else
- wait_reading_process_input (1, 0, zero, 0);
+ wait_reading_process_output (1, 0, 0, 0, Qnil, NULL, 0);
#endif
if (BUFFERP (object))
work. If the system has it, use it. */
#ifdef HAVE_TERMIOS
struct termios t;
+ cc_t *sig_char = NULL;
+
+ tcgetattr (XINT (p->infd), &t);
switch (signo)
{
case SIGINT:
- tcgetattr (XINT (p->infd), &t);
- send_process (proc, &t.c_cc[VINTR], 1, Qnil);
- return;
+ sig_char = &t.c_cc[VINTR];
+ break;
case SIGQUIT:
- tcgetattr (XINT (p->infd), &t);
- send_process (proc, &t.c_cc[VQUIT], 1, Qnil);
- return;
+ sig_char = &t.c_cc[VQUIT];
+ break;
case SIGTSTP:
- tcgetattr (XINT (p->infd), &t);
#if defined (VSWTCH) && !defined (PREFER_VSUSP)
- send_process (proc, &t.c_cc[VSWTCH], 1, Qnil);
+ sig_char = &t.c_cc[VSWTCH];
#else
- send_process (proc, &t.c_cc[VSUSP], 1, Qnil);
+ sig_char = &t.c_cc[VSUSP];
#endif
- return;
+ break;
}
+ if (sig_char && *sig_char != CDISABLE)
+ {
+ send_process (proc, sig_char, 1, Qnil);
+ return;
+ }
+ /* If we can't send the signal with a character,
+ fall through and send it another way. */
#else /* ! HAVE_TERMIOS */
/* On Berkeley descendants, the following IOCTL's retrieve the
you'd better be using one of the alternatives above! */
#endif /* ! defined (TCGETA) */
#endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */
-#endif /* ! defined HAVE_TERMIOS */
+ /* In this case, the code above should alway returns. */
abort ();
- /* The code above always returns from the function. */
+#endif /* ! defined HAVE_TERMIOS */
+
+ /* The code above may fall through if it can't
+ handle the signal. */
#endif /* defined (SIGNALS_VIA_CHARACTERS) */
#ifdef TIOCGPGRP
register struct Lisp_Process *p;
extern EMACS_TIME *input_available_clear_time;
+ SIGNAL_THREAD_CHECK (signo);
+
#ifdef BSD4_1
extern int sigheld;
sigheld |= sigbit (SIGCHLD);
FD_CLR (XINT (p->infd), &non_keyboard_wait_mask);
}
- /* Tell wait_reading_process_input that it needs to wake up and
+ /* Tell wait_reading_process_output that it needs to wake up and
look around. */
if (input_available_clear_time)
EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
else if (WIFSIGNALED (w))
synch_process_termsig = WTERMSIG (w);
- /* Tell wait_reading_process_input that it needs to wake up and
+ /* Tell wait_reading_process_output that it needs to wake up and
look around. */
if (input_available_clear_time)
EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
FD_ZERO (&non_process_wait_mask);
max_process_desc = 0;
+#ifdef NON_BLOCKING_CONNECT
+ FD_ZERO (&connect_wait_mask);
+ num_pending_connects = 0;
+#endif
+
#ifdef ADAPTIVE_READ_BUFFERING
process_output_delay_count = 0;
process_output_skip = 0;
1 to return when input is available, or
-1 means caller will actually read the input, so don't throw to
the quit handler.
- a cons cell, meaning wait until its car is non-nil
- (and gobble terminal input into the buffer if any arrives), or
- We know that read_kbd will never be a Lisp_Process, since
- `subprocesses' isn't defined.
+
+ see full version for other parameters. We know that wait_proc will
+ always be NULL, since `subprocesses' isn't defined.
do_display != 0 means redisplay should be done to show subprocess
output that arrives.
Return true iff we received input from any process. */
int
-wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
- int time_limit, microsecs;
- Lisp_Object read_kbd;
- int do_display;
+wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
+ wait_for_cell, wait_proc, just_wait_proc)
+ int time_limit, microsecs, read_kbd, do_display;
+ Lisp_Object wait_for_cell;
+ struct Lisp_Process *wait_proc;
+ int just_wait_proc;
{
register int nfds;
EMACS_TIME end_time, timeout;
SELECT_TYPE waitchannels;
int xerrno;
- /* Either nil or a cons cell, the car of which is of interest and
- may be changed outside of this routine. */
- Lisp_Object wait_for_cell;
-
- wait_for_cell = Qnil;
-
- /* If waiting for non-nil in a cell, record where. */
- if (CONSP (read_kbd))
- {
- wait_for_cell = read_kbd;
- XSETFASTINT (read_kbd, 0);
- }
/* What does time_limit really mean? */
if (time_limit || microsecs)
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
Otherwise, do pending quit if requested. */
- if (XINT (read_kbd) >= 0)
+ if (read_kbd >= 0)
QUIT;
/* Exit now if the cell we're waiting for became non-nil. */
while (!detect_input_pending ());
/* If there is unread keyboard input, also return. */
- if (XINT (read_kbd) != 0
+ if (read_kbd != 0
&& requeued_events_pending_p ())
break;
/* Cause C-g and alarm signals to take immediate action,
and cause input available signals to zero out timeout. */
- if (XINT (read_kbd) < 0)
+ if (read_kbd < 0)
set_waiting_for_input (&timeout);
/* Wait till there is something to do. */
- if (! XINT (read_kbd) && NILP (wait_for_cell))
+ if (! read_kbd && NILP (wait_for_cell))
FD_ZERO (&waitchannels);
else
FD_SET (0, &waitchannels);
{
clear_waiting_for_input ();
redisplay_preserve_echo_area (15);
- if (XINT (read_kbd) < 0)
+ if (read_kbd < 0)
set_waiting_for_input (&timeout);
}
- if (XINT (read_kbd) && detect_input_pending ())
+ if (read_kbd && detect_input_pending ())
{
nfds = 0;
FD_ZERO (&waitchannels);
kill (getpid (), SIGIO);
#endif
#ifdef SIGIO
- if (XINT (read_kbd) && interrupt_input && (waitchannels & 1))
+ if (read_kbd && interrupt_input && (waitchannels & 1))
kill (getpid (), SIGIO);
#endif
/* Check for keyboard input */
- if ((XINT (read_kbd) != 0)
+ if (read_kbd
&& detect_input_pending_run_timers (do_display))
{
swallow_events (do_display);
}
/* If there is unread keyboard input, also return. */
- if (XINT (read_kbd) != 0
+ if (read_kbd
&& requeued_events_pending_p ())
break;