#define NUMERIC_ADDR_ERROR (numeric_addr == -1)
#endif
-#if defined(BSD) || defined(STRIDE)
+#if defined(BSD_SYSTEM) || defined(STRIDE)
#include <sys/ioctl.h>
#if !defined (O_NDELAY) && defined (HAVE_PTYS) && !defined(USG5)
#include <fcntl.h>
#endif /* HAVE_PTYS and no O_NDELAY */
-#endif /* BSD or STRIDE */
+#endif /* BSD_SYSTEM || STRIDE */
#ifdef BROKEN_O_NONBLOCK
#undef O_NONBLOCK
/* Qexit is declared and initialized in eval.c. */
/* a process object is a network connection when its childp field is neither
- Qt nor Qnil but is instead a string (name of foreign host we
- are connected to + name of port we are connected to) */
+ Qt nor Qnil but is instead a cons cell (HOSTNAME PORTNUM). */
#ifdef HAVE_SOCKETS
-static Lisp_Object stream_process;
-
-#define NETCONN_P(p) (GC_STRINGP (XPROCESS (p)->childp))
+#define NETCONN_P(p) (GC_CONSP (XPROCESS (p)->childp))
#else
#define NETCONN_P(p) 0
#endif /* HAVE_SOCKETS */
static Lisp_Object get_process ();
extern EMACS_TIME timer_check ();
+extern int timers_run;
/* Maximum number of bytes to send to a pty without an eof. */
static int pty_max_bytes;
return Fnull (tem);
}
+DEFUN ("process-contact", Fprocess_contact, Sprocess_contact,
+ 1, 1, 0,
+ "Return the contact info of PROCESS; t for a real child.\n\
+For a net connection, the value is a cons cell of the form (HOST SERVICE).")
+ (process)
+ register Lisp_Object process;
+{
+ CHECK_PROCESS (process, 0);
+ return XPROCESS (process)->childp;
+}
+
#if 0 /* Turned off because we don't currently record this info
in the process. Perhaps add it. */
DEFUN ("process-connection", Fprocess_connection, Sprocess_connection, 1, 1, 0,
if (NETCONN_P (proc))
{
sprintf (tembuf, "(network stream connection to %s)\n",
- XSTRING (p->childp)->data);
+ XSTRING (XCONS (p->childp)->car)->data);
insert_string (tembuf);
}
else
create_process_1 (signo)
int signo;
{
-#ifdef USG
+#if defined (USG) && !defined (POSIX_SIGNALS)
/* USG systems forget handlers when they are used;
must reestablish each time */
signal (signo, create_process_1);
}
#else /* not SKTPAIR */
{
-#ifdef WINDOWSNT
- pipe_with_inherited_out (sv);
- inchannel = sv[0];
- forkout = sv[1];
-
- pipe_with_inherited_in (sv);
- forkin = sv[0];
- outchannel = sv[1];
-#else /* not WINDOWSNT */
pipe (sv);
inchannel = sv[0];
forkout = sv[1];
pipe (sv);
outchannel = sv[1];
forkin = sv[0];
-#endif /* not WINDOWSNT */
}
#endif /* not SKTPAIR */
#ifdef BSD4_1
sighold (SIGCHLD);
#else /* not BSD4_1 */
-#if defined (BSD) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
sigsetmask (sigmask (SIGCHLD));
#else /* ordinary USG */
#if 0
/* In order to get a controlling terminal on some versions
of BSD, it is necessary to put the process in pgrp 0
before it opens the terminal. */
-#ifdef OSF1
+#ifdef HAVE_SETPGID
setpgid (0, 0);
#else
setpgrp (0, 0);
}
#endif /* TIOCNOTTY */
-#if !defined (RTU) && !defined (UNIPLUS)
+#if !defined (RTU) && !defined (UNIPLUS) && !defined (DONT_REOPEN_PTY)
/*** There is a suggestion that this ought to be a
- conditional on TIOCSPGRP. */
+ conditional on TIOCSPGRP,
+ or !(defined (HAVE_SETSID) && defined (TIOCSCTTY)).
+ Trying the latter gave the wrong results on Debian GNU/Linux 1.1;
+ that system does seem to need this code, even though
+ both HAVE_SETSID and TIOCSCTTY are defined. */
/* Now close the pty (if we had it open) and reopen it.
This makes the pty the controlling terminal of the subprocess. */
if (pty_flag)
ioctl (xforkout, TIOCSPGRP, &pgrp);
#endif
}
-#endif /* not UNIPLUS and not RTU */
+#endif /* not UNIPLUS and not RTU and not DONT_REOPEN_PTY */
+
#ifdef SETUP_SLAVE_PTY
if (pty_flag)
{
#ifdef BSD4_1
sigrelse (SIGCHLD);
#else /* not BSD4_1 */
-#if defined (BSD) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
sigsetmask (SIGEMPTYMASK);
#else /* ordinary USG */
#if 0
#ifdef BSD4_1
sigrelse (SIGCHLD);
#else /* not BSD4_1 */
-#if defined (BSD) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
sigsetmask (SIGEMPTYMASK);
#else /* ordinary USG */
#if 0
int retry = 0;
int count = specpdl_ptr - specpdl;
+#ifdef WINDOWSNT
+ /* Ensure socket support is loaded if available. */
+ init_winsock (TRUE);
+#endif
+
GCPRO4 (name, buffer, host, service);
CHECK_STRING (name, 0);
CHECK_STRING (host, 0);
#ifdef TRY_AGAIN
h_errno = 0;
#endif
+ immediate_quit = 1;
+ QUIT;
host_info_ptr = gethostbyname (XSTRING (host)->data);
+ immediate_quit = 0;
#ifdef TRY_AGAIN
if (! (host_info_ptr == 0 && h_errno == TRY_AGAIN))
#endif
#endif
#endif
- XPROCESS (proc)->childp = host;
+ XPROCESS (proc)->childp = Fcons (host, Fcons (service, Qnil));
XPROCESS (proc)->command_channel_p = Qnil;
XPROCESS (proc)->buffer = buffer;
XPROCESS (proc)->sentinel = Qnil;
XPROCESS (proc)->filter = Qnil;
XPROCESS (proc)->command = Qnil;
XPROCESS (proc)->pid = Qnil;
- XSETINT (XPROCESS (proc)->infd, s);
+ XSETINT (XPROCESS (proc)->infd, inch);
XSETINT (XPROCESS (proc)->outfd, outch);
XPROCESS (proc)->status = Qrun;
FD_SET (inch, &input_wait_mask);
when not inside wait_reading_process_input. */
static int waiting_for_user_input_p;
+/* This is here so breakpoints can be put on it. */
+static
+wait_reading_process_input_1 ()
+{
+}
+
/* Read and dispose of subprocess output while waiting for timeout to
elapse and/or keyboard input to be available.
EMACS_SET_SECS_USECS (timeout, time_limit, microsecs);
EMACS_ADD_TIME (end_time, end_time, timeout);
}
+#ifdef hpux
+ /* AlainF 5-Jul-1996
+ HP-UX 10.10 seem to have problems with signals coming in
+ Causes "poll: interrupted system call" messages when Emacs is run
+ in an X window
+ Turn off periodic alarms (in case they are in use) */
+ stop_polling ();
+#endif
while (1)
{
EMACS_SET_SECS_USECS (timeout, 100000, 0);
}
- /* If our caller will not immediately handle keyboard events,
- run timer events directly.
- (Callers that will immediately read keyboard events
- call timer_delay on their own.) */
- if (read_kbd >= 0)
+ /* Normally we run timers here.
+ 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 (! wait_for_cell)
{
EMACS_TIME timer_delay;
+ int old_timers_run;
+
+ retry:
+ old_timers_run = timers_run;
timer_delay = timer_check (1);
+ if (timers_run != old_timers_run && do_display)
+ {
+ redisplay_preserve_echo_area ();
+ /* We must retry, since a timer may have requeued itself
+ and that could alter the time_delay. */
+ goto retry;
+ }
+
if (! EMACS_TIME_NEG_P (timer_delay) && time_limit != -1)
{
EMACS_TIME difference;
timeout_reduced_for_timers = 1;
}
}
+ /* If time_limit is -1, we are not going to wait at all. */
+ else if (time_limit != -1)
+ {
+ /* This is so a breakpoint can be put here. */
+ wait_reading_process_input_1 ();
+ }
}
/* Cause C-g and alarm signals to take immediate action,
/* If there is any, return immediately
to give it higher priority than subprocesses */
- if (XINT (read_kbd) < 0 && detect_input_pending ())
+ if ((XINT (read_kbd) != 0)
+ && detect_input_pending_run_timers (do_display))
{
swallow_events (do_display);
- if (detect_input_pending ())
+ if (detect_input_pending_run_timers (do_display))
break;
}
- if ((XINT (read_kbd) > 0 || wait_for_cell)
- && detect_input_pending_run_timers ())
+ /* If wait_for_cell. check for keyboard input
+ but don't run any timers.
+ ??? (It seems wrong to me to check for keyboard
+ input at all when wait_for_cell, but the code
+ has been this way since July 1994.
+ Try changing this after version 19.31.) */
+ if (wait_for_cell
+ && detect_input_pending ())
{
swallow_events (do_display);
- if (detect_input_pending_run_timers ())
+ if (detect_input_pending ())
break;
}
if (XINT (read_kbd) && interrupt_input
&& (keyboard_bit_set (&Available)))
- kill (0, SIGIO);
+ kill (getpid (), SIGIO);
#endif
if (! wait_proc)
#ifdef EWOULDBLOCK
else if (nread == -1 && errno == EWOULDBLOCK)
;
-#else
+#endif
+ /* ISC 4.1 defines both EWOULDBLOCK and O_NONBLOCK,
+ and Emacs uses O_NONBLOCK, so what we get is EAGAIN. */
#ifdef O_NONBLOCK
else if (nread == -1 && errno == EAGAIN)
;
;
#endif /* O_NDELAY */
#endif /* O_NONBLOCK */
-#endif /* EWOULDBLOCK */
#ifdef HAVE_PTYS
/* On some OSs with ptys, when the process on one end of
a pty exits, the other end gets an error reading with
clear_input_pending ();
QUIT;
}
-
+#ifdef hpux
+ /* AlainF 5-Jul-1996
+ HP-UX 10.10 seems to have problems with signals coming in
+ Causes "poll: interrupted system call" messages when Emacs is run
+ in an X window
+ Turn periodic alarms back on */
+ start_polling();
+#endif
+
return got_some_input;
}
\f
#else /* not VMS */
if (proc_buffered_char[channel] < 0)
-#ifdef WINDOWSNT
- nchars = read_child_output (channel, chars, sizeof (chars));
-#else
- nchars = read (channel, chars, sizeof chars);
-#endif
+ nchars = read (channel, chars, sizeof (chars));
else
{
chars[0] = proc_buffered_char[channel];
proc_buffered_char[channel] = -1;
-#ifdef WINDOWSNT
- nchars = read_child_output (channel, chars + 1, sizeof (chars) - 1);
-#else
- nchars = read (channel, chars + 1, sizeof chars - 1);
-#endif
+ nchars = read (channel, chars + 1, sizeof (chars) - 1);
if (nchars < 0)
nchars = 1;
else
int count = specpdl_ptr - specpdl;
Lisp_Object odeactivate;
Lisp_Object obuffer, okeymap;
+ int outer_running_asynch_code = running_asynch_code;
/* No need to gcpro these, because all we do with them later
is test them for EQness, and none of them should be a string. */
specbind (Qinhibit_quit, Qt);
specbind (Qlast_nonmenu_event, Qt);
+ /* In case we get recursively called,
+ and we already saved the match data nonrecursively,
+ save the same match data in safely recursive fashion. */
+ if (outer_running_asynch_code)
+ {
+ Lisp_Object tem;
+ /* Don't clobber the CURRENT match data, either! */
+ tem = Fmatch_data ();
+ restore_match_data ();
+ record_unwind_protect (Fstore_match_data, Fmatch_data ());
+ Fstore_match_data (tem);
+ }
+
+ /* For speed, if a search happens within this code,
+ save the match data in a special nonrecursive fashion. */
running_asynch_code = 1;
+
+ /* Read and dispose of the process output. */
internal_condition_case_1 (read_process_output_call,
Fcons (outstream,
Fcons (proc,
Qnil))),
!NILP (Vdebug_on_error) ? Qnil : Qerror,
read_process_output_error_handler);
- running_asynch_code = 0;
+
+ /* If we saved the match data nonrecursively, restore it now. */
restore_match_data ();
+ running_asynch_code = outer_running_asynch_code;
/* Handling the process output should not deactivate the mark. */
Vdeactivate_mark = odeactivate;
odeactivate = Vdeactivate_mark;
Fset_buffer (p->buffer);
- opoint = point;
+ opoint = PT;
old_read_only = current_buffer->read_only;
XSETFASTINT (old_begv, BEGV);
XSETFASTINT (old_zv, ZV);
/* If the output marker is outside of the visible region, save
the restriction and widen. */
- if (! (BEGV <= point && point <= ZV))
+ if (! (BEGV <= PT && PT <= ZV))
Fwiden ();
/* Make sure opoint floats ahead of any new text, just as point
would. */
- if (point <= opoint)
+ if (PT <= opoint)
opoint += nchars;
/* Insert after old_begv, but before old_zv. */
- if (point < XFASTINT (old_begv))
+ if (PT < XFASTINT (old_begv))
XSETFASTINT (old_begv, XFASTINT (old_begv) + nchars);
- if (point <= XFASTINT (old_zv))
+ if (PT <= XFASTINT (old_zv))
XSETFASTINT (old_zv, XFASTINT (old_zv) + nchars);
/* Insert before markers in case we are inserting where
the buffer's mark is, and the user's next command is Meta-y. */
insert_before_markers (chars, nchars);
- Fset_marker (p->mark, make_number (point), p->buffer);
+ Fset_marker (p->mark, make_number (PT), p->buffer);
update_mode_lines++;
/* Use volatile to protect variables from being clobbered by longjmp. */
int rv;
volatile unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data;
+ struct gcpro gcpro1;
+
+ GCPRO1 (object);
#ifdef VMS
struct Lisp_Process *p = XPROCESS (proc);
error ("SIGPIPE raised on process %s; closed it", procname);
#endif
}
+
+ UNGCPRO;
}
DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region,
#undef handle_signal
-#ifdef WINDOWSNT
- /* Only works for kill-type signals */
- return make_number (win32_kill_process (XINT (pid), XINT (sigcode)));
-#else
return make_number (kill (XINT (pid), XINT (sigcode)));
-#endif
}
DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0,
/* USG systems forget handlers when they are used;
must reestablish each time */
-#ifdef USG
+#if defined (USG) && !defined (POSIX_SIGNALS)
signal (signo, sigchld_handler); /* WARNING - must come after wait3() */
#endif
#ifdef BSD4_1
Otherwise (on systems that have WNOHANG), loop around
to use up all the processes that have something to tell us. */
#if defined (USG) && ! (defined (HPUX) && defined (WNOHANG)) || defined (WINDOWSNT)
-#ifdef USG
+#if defined (USG) && ! defined (POSIX_SIGNALS)
signal (signo, sigchld_handler);
#endif
errno = old_errno;
Lisp_Object sentinel, obuffer, odeactivate, okeymap;
register struct Lisp_Process *p = XPROCESS (proc);
int count = specpdl_ptr - specpdl;
+ int outer_running_asynch_code = running_asynch_code;
/* No need to gcpro these, because all we do with them later
is test them for EQness, and none of them should be a string. */
specbind (Qinhibit_quit, Qt);
specbind (Qlast_nonmenu_event, Qt);
+ /* In case we get recursively called,
+ and we already saved the match data nonrecursively,
+ save the same match data in safely recursive fashion. */
+ if (outer_running_asynch_code)
+ {
+ Lisp_Object tem;
+ tem = Fmatch_data ();
+ restore_match_data ();
+ record_unwind_protect (Fstore_match_data, Fmatch_data ());
+ Fstore_match_data (tem);
+ }
+
+ /* For speed, if a search happens within this code,
+ save the match data in a special nonrecursive fashion. */
running_asynch_code = 1;
+
internal_condition_case_1 (read_process_output_call,
Fcons (sentinel,
Fcons (proc, Fcons (reason, Qnil))),
!NILP (Vdebug_on_error) ? Qnil : Qerror,
exec_sentinel_error_handler);
- running_asynch_code = 0;
+
+ /* If we saved the match data nonrecursively, restore it now. */
restore_match_data ();
+ running_asynch_code = outer_running_asynch_code;
Vdeactivate_mark = odeactivate;
#if 0
XSETINT (p->update_tick, XINT (p->tick));
/* If process is still active, read any output that remains. */
- if (XINT (p->infd) >= 0)
- while (! EQ (p->filter, Qt)
- && read_process_output (proc, XINT (p->infd)) > 0);
+ while (! EQ (p->filter, Qt)
+ && XINT (p->infd) >= 0
+ && read_process_output (proc, XINT (p->infd)) > 0);
buffer = p->buffer;
deactivate_process (proc);
}
+ /* The actions above may have further incremented p->tick.
+ So set p->update_tick again
+ so that an error in the sentinel will not cause
+ this code to be run again. */
+ XSETINT (p->update_tick, XINT (p->tick));
/* Now output the message suitably. */
if (!NILP (p->sentinel))
exec_sentinel (proc, msg);
if (NILP (XBUFFER (buffer)->name))
continue;
Fset_buffer (buffer);
- opoint = point;
+ opoint = PT;
/* Insert new output into buffer
at the current end-of-output marker,
thus preserving logical ordering of input and output. */
SET_PT (marker_position (p->mark));
else
SET_PT (ZV);
- if (point <= opoint)
+ if (PT <= opoint)
opoint += XSTRING (msg)->size + XSTRING (p->name)->size + 10;
tem = current_buffer->read_only;
insert_string (" ");
Finsert (1, &msg);
current_buffer->read_only = tem;
- Fset_marker (p->mark, make_number (point), p->buffer);
+ Fset_marker (p->mark, make_number (PT), p->buffer);
SET_PT (opoint);
set_buffer_internal (old);
syms_of_process ()
{
-#ifdef HAVE_SOCKETS
- stream_process = intern ("stream");
-#endif
Qprocessp = intern ("processp");
staticpro (&Qprocessp);
Qrun = intern ("run");
defsubr (&Sset_process_filter);
defsubr (&Sprocess_filter);
defsubr (&Sset_process_sentinel);
- defsubr (&Sset_process_window_size);
defsubr (&Sprocess_sentinel);
+ defsubr (&Sset_process_window_size);
defsubr (&Sprocess_kill_without_query);
+ defsubr (&Sprocess_contact);
defsubr (&Slist_processes);
defsubr (&Sprocess_list);
defsubr (&Sstart_process);
extern int frame_garbaged;
+extern EMACS_TIME timer_check ();
+extern int timers_run;
/* As described above, except assuming that there are no subprocesses:
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.
Lisp_Object read_kbd;
int do_display;
{
- EMACS_TIME end_time, timeout, *timeout_p;
+ EMACS_TIME end_time, timeout;
SELECT_TYPE waitchannels;
+ int xerrno;
+ Lisp_Object *wait_for_cell = 0;
+
+ /* If waiting for non-nil in a cell, record where. */
+ if (CONSP (read_kbd))
+ {
+ wait_for_cell = &XCONS (read_kbd)->car;
+ XSETFASTINT (read_kbd, 0);
+ }
/* What does time_limit really mean? */
if (time_limit || microsecs)
{
- /* It's not infinite. */
- timeout_p = &timeout;
-
if (time_limit == -1)
/* In fact, it's zero. */
EMACS_SET_SECS_USECS (timeout, 0, 0);
}
else
/* It's infinite. */
- timeout_p = 0;
+ EMACS_SET_SECS_USECS (timeout, 100000, 0);
/* Turn off periodic alarms (in case they are in use)
because the select emulator uses alarms. */
for (;;)
{
int nfds;
-
- if (XINT (read_kbd))
- FD_SET (0, &waitchannels);
- else
- FD_ZERO (&waitchannels);
+ int timeout_reduced_for_timers = 0;
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
if (XINT (read_kbd) >= 0)
QUIT;
- if (timeout_p)
+ /* Exit now if the cell we're waiting for became non-nil. */
+ if (wait_for_cell && ! NILP (*wait_for_cell))
+ break;
+
+ /* Compute time from now till when time limit is up */
+ /* Exit if already run out */
+ if (time_limit > 0 || microsecs)
{
- EMACS_GET_TIME (*timeout_p);
- EMACS_SUB_TIME (*timeout_p, end_time, *timeout_p);
- if (EMACS_TIME_NEG_P (*timeout_p))
+ EMACS_GET_TIME (timeout);
+ EMACS_SUB_TIME (timeout, end_time, timeout);
+ if (EMACS_TIME_NEG_P (timeout))
break;
}
+ /* If our caller will not immediately handle keyboard events,
+ run timer events directly.
+ (Callers that will immediately read keyboard events
+ call timer_delay on their own.) */
+ if (! wait_for_cell)
+ {
+ EMACS_TIME timer_delay;
+ int old_timers_run;
+
+ retry:
+ old_timers_run = timers_run;
+ timer_delay = timer_check (1);
+ if (timers_run != old_timers_run && do_display)
+ {
+ redisplay_preserve_echo_area ();
+ /* We must retry, since a timer may have requeued itself
+ and that could alter the time delay. */
+ goto retry;
+ }
+
+ if (! EMACS_TIME_NEG_P (timer_delay) && time_limit != -1)
+ {
+ EMACS_TIME difference;
+ EMACS_SUB_TIME (difference, timer_delay, timeout);
+ if (EMACS_TIME_NEG_P (difference))
+ {
+ timeout = timer_delay;
+ timeout_reduced_for_timers = 1;
+ }
+ }
+ }
+
/* Cause C-g and alarm signals to take immediate action,
and cause input available signals to zero out timeout. */
if (XINT (read_kbd) < 0)
set_waiting_for_input (&timeout);
+ /* Wait till there is something to do. */
+
+ if (! XINT (read_kbd) && wait_for_cell == 0)
+ FD_ZERO (&waitchannels);
+ else
+ FD_SET (0, &waitchannels);
+
/* If a frame has been newly mapped and needs updating,
reprocess its display stuff. */
if (frame_garbaged && do_display)
- redisplay_preserve_echo_area ();
+ {
+ clear_waiting_for_input ();
+ redisplay_preserve_echo_area ();
+ if (XINT (read_kbd) < 0)
+ set_waiting_for_input (&timeout);
+ }
if (XINT (read_kbd) && detect_input_pending ())
- nfds = 0;
+ {
+ nfds = 0;
+ FD_ZERO (&waitchannels);
+ }
else
nfds = select (1, &waitchannels, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
- timeout_p);
+ &timeout);
+
+ xerrno = errno;
/* Make C-g and alarm signals set flags again */
clear_waiting_for_input ();
/* If we woke up due to SIGWINCH, actually change size now. */
do_pending_window_change ();
+ if (time_limit && nfds == 0 && ! timeout_reduced_for_timers)
+ /* We waited the full specified time, so return now. */
+ break;
+
if (nfds == -1)
{
/* If the system call was interrupted, then go around the
loop again. */
- if (errno == EINTR)
+ if (xerrno == EINTR)
FD_ZERO (&waitchannels);
+ else
+ error ("select error: %s", strerror (xerrno));
}
#ifdef sun
else if (nfds > 0 && (waitchannels & 1) && interrupt_input)
#endif
#ifdef SIGIO
if (XINT (read_kbd) && interrupt_input && (waitchannels & 1))
- kill (0, SIGIO);
+ kill (getpid (), SIGIO);
#endif
- /* If we have timed out (nfds == 0) or found some input (nfds > 0),
- we should exit. */
- if (nfds >= 0)
+ /* Check for keyboard input */
+
+ if ((XINT (read_kbd) != 0)
+ && detect_input_pending_run_timers (do_display))
+ {
+ swallow_events (do_display);
+ if (detect_input_pending_run_timers (do_display))
+ break;
+ }
+
+ /* If wait_for_cell. check for keyboard input
+ but don't run any timers.
+ ??? (It seems wrong to me to check for keyboard
+ input at all when wait_for_cell, but the code
+ has been this way since July 1994.
+ Try changing this after version 19.31.) */
+ if (wait_for_cell
+ && detect_input_pending ())
+ {
+ swallow_events (do_display);
+ if (detect_input_pending ())
+ break;
+ }
+
+ /* Exit now if the cell we're waiting for became non-nil. */
+ if (wait_for_cell && ! NILP (*wait_for_cell))
break;
}