/* input.c -- character input functions for readline. */
-/* Copyright (C) 1994-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2013 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
-#if defined (HAVE_SELECT)
-# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
-# include <sys/time.h>
-# endif
-#endif /* HAVE_SELECT */
-#if defined (HAVE_SYS_SELECT_H)
-# include <sys/select.h>
-#endif
+#include <signal.h>
+
+#include "posixselect.h"
#if defined (FIONREAD_IN_SYS_IOCTL)
# include <sys/ioctl.h>
character input. */
rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
+/* A function to call if a read(2) is interrupted by a signal. */
+rl_hook_func_t *rl_signal_event_hook = (rl_hook_func_t *)NULL;
+
+/* A function to replace _rl_input_available for applications using the
+ callback interface. */
+rl_hook_func_t *rl_input_available_hook = (rl_hook_func_t *)NULL;
+
rl_getc_func_t *rl_getc_function = rl_getc;
static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */
return any_typein;
}
+int
+_rl_pushed_input_available ()
+{
+ return (push_index != pop_index);
+}
+
/* Return the amount of space available in the buffer for stuffing
characters. */
static int
/* Get a key from the buffer of characters to be read.
Return the key in KEY.
- Result is KEY if there was a key, or 0 if there wasn't. */
+ Result is non-zero if there was a key, or 0 if there wasn't. */
static int
rl_get_char (key)
int *key;
return (0);
}
-int
-_rl_pushed_input_available ()
-{
- return (push_index != pop_index);
-}
-
/* If a character is available to be read, then read it and stuff it into
IBUFFER. Otherwise, just return. Returns number of characters read
(0 if none available) and -1 on error (EIO). */
FD_ZERO (&exceptfds);
FD_SET (tty, &readfds);
FD_SET (tty, &exceptfds);
- timeout.tv_sec = 0;
- timeout.tv_usec = _keyboard_input_timeout;
+ USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout);
result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
if (result <= 0)
return 0; /* Nothing to read. */
#endif
int tty;
+ if (rl_input_available_hook)
+ return (*rl_input_available_hook) ();
+
tty = fileno (rl_instream);
#if defined (HAVE_SELECT)
int
rl_read_key ()
{
- int c;
-
- rl_key_sequence_length++;
+ int c, r;
if (rl_pending_input)
{
/* If the user has an event function, then call it periodically. */
if (rl_event_hook)
{
- while (rl_event_hook && rl_get_char (&c) == 0)
+ while (rl_event_hook)
{
- (*rl_event_hook) ();
- RL_CHECK_SIGNALS ();
- if (rl_done) /* XXX - experimental */
- return ('\n');
- if (rl_gather_tyi () < 0) /* XXX - EIO */
+ if (rl_get_char (&c) != 0)
+ break;
+
+ if ((r = rl_gather_tyi ()) < 0) /* XXX - EIO */
{
rl_done = 1;
return ('\n');
}
+ else if (r > 0) /* read something */
+ continue;
+
+ RL_CHECK_SIGNALS ();
+ if (rl_done) /* XXX - experimental */
+ return ('\n');
+ (*rl_event_hook) ();
}
}
else
{
if (rl_get_char (&c) == 0)
c = (*rl_getc_function) (rl_instream);
+/* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d", _rl_caught_signal); */
RL_CHECK_SIGNALS ();
}
}
{
RL_CHECK_SIGNALS ();
+ /* We know at this point that _rl_caught_signal == 0 */
+
#if defined (__MINGW32__)
if (isatty (fileno (stream)))
return (getch ());
#undef X_EWOULDBLOCK
#undef X_EAGAIN
- /* If the error that we received was SIGINT, then try again,
- this is simply an interrupted system call to read ().
- Otherwise, some error ocurred, also signifying EOF. */
+/* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */
+
+ /* If the error that we received was EINTR, then try again,
+ this is simply an interrupted system call to read (). We allow
+ the read to be interrupted if we caught SIGHUP or SIGTERM (but
+ not SIGINT; let the signal handler deal with that), but if the
+ application sets an event hook, call it for other signals.
+ Otherwise (not EINTR), some error occurred, also signifying EOF. */
if (errno != EINTR)
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
+ else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM)
+ return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
+ /* keyboard-generated signals of interest */
+ else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT)
+ RL_CHECK_SIGNALS ();
+ /* non-keyboard-generated signals of interest */
+ else if (_rl_caught_signal == SIGALRM
+#if defined (SIGVTALRM)
+ || _rl_caught_signal == SIGVTALRM
+#endif
+ )
+ RL_CHECK_SIGNALS ();
+
+ if (rl_signal_event_hook)
+ (*rl_signal_event_hook) ();
}
}