version 1.1.1.2, 2016/11/03 13:35:37
|
version 1.1.1.3, 2021/03/17 01:01:01
|
Line 1
|
Line 1
|
/* input.c -- character input functions for readline. */ |
/* input.c -- character input functions for readline. */ |
|
|
/* Copyright (C) 1994-2013 Free Software Foundation, Inc. | /* Copyright (C) 1994-2017 Free Software Foundation, Inc. |
|
|
This file is part of the GNU Readline Library (Readline), a library |
This file is part of the GNU Readline Library (Readline), a library |
for reading lines of text with interactive input and history editing. |
for reading lines of text with interactive input and history editing. |
Line 22
|
Line 22
|
#define READLINE_LIBRARY |
#define READLINE_LIBRARY |
|
|
#if defined (__TANDEM) |
#if defined (__TANDEM) |
|
# define _XOPEN_SOURCE_EXTENDED 1 |
|
# define _TANDEM_SOURCE 1 |
# include <floss.h> |
# include <floss.h> |
#endif |
#endif |
|
|
Line 76 extern int errno;
|
Line 78 extern int errno;
|
# define O_NDELAY O_NONBLOCK /* Posix style */ |
# define O_NDELAY O_NONBLOCK /* Posix style */ |
#endif |
#endif |
|
|
|
#if defined (HAVE_PSELECT) |
|
extern sigset_t _rl_orig_sigset; |
|
#endif |
|
|
/* Non-null means it is a pointer to a function to run while waiting for |
/* Non-null means it is a pointer to a function to run while waiting for |
character input. */ |
character input. */ |
rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; |
rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; |
Line 95 static int ibuffer_space PARAMS((void));
|
Line 101 static int ibuffer_space PARAMS((void));
|
static int rl_get_char PARAMS((int *)); |
static int rl_get_char PARAMS((int *)); |
static int rl_gather_tyi PARAMS((void)); |
static int rl_gather_tyi PARAMS((void)); |
|
|
|
/* Windows isatty returns true for every character device, including the null |
|
device, so we need to perform additional checks. */ |
|
#if defined (_WIN32) && !defined (__CYGWIN__) |
|
#include <io.h> |
|
#include <conio.h> |
|
#define WIN32_LEAN_AND_MEAN 1 |
|
#include <windows.h> |
|
|
|
int |
|
win32_isatty (int fd) |
|
{ |
|
if (_isatty(fd)) |
|
{ |
|
HANDLE h; |
|
DWORD ignored; |
|
|
|
if ((h = (HANDLE) _get_osfhandle (fd)) == INVALID_HANDLE_VALUE) |
|
{ |
|
errno = EBADF; |
|
return 0; |
|
} |
|
if (GetConsoleMode (h, &ignored) != 0) |
|
return 1; |
|
} |
|
errno = ENOTTY; |
|
return 0; |
|
} |
|
|
|
#define isatty(x) win32_isatty(x) |
|
#endif |
|
|
/* **************************************************************** */ |
/* **************************************************************** */ |
/* */ |
/* */ |
/* Character Input Buffering */ |
/* Character Input Buffering */ |
Line 108 static int ibuffer_len = sizeof (ibuffer) - 1;
|
Line 145 static int ibuffer_len = sizeof (ibuffer) - 1;
|
#define any_typein (push_index != pop_index) |
#define any_typein (push_index != pop_index) |
|
|
int |
int |
_rl_any_typein () | _rl_any_typein (void) |
{ |
{ |
return any_typein; |
return any_typein; |
} |
} |
|
|
int |
int |
_rl_pushed_input_available () | _rl_pushed_input_available (void) |
{ |
{ |
return (push_index != pop_index); |
return (push_index != pop_index); |
} |
} |
Line 122 _rl_pushed_input_available ()
|
Line 159 _rl_pushed_input_available ()
|
/* Return the amount of space available in the buffer for stuffing |
/* Return the amount of space available in the buffer for stuffing |
characters. */ |
characters. */ |
static int |
static int |
ibuffer_space () | ibuffer_space (void) |
{ |
{ |
if (pop_index > push_index) |
if (pop_index > push_index) |
return (pop_index - push_index - 1); |
return (pop_index - push_index - 1); |
Line 134 ibuffer_space ()
|
Line 171 ibuffer_space ()
|
Return the key in KEY. |
Return the key in KEY. |
Result is non-zero 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 |
static int |
rl_get_char (key) | rl_get_char (int *key) |
int *key; | |
{ |
{ |
if (push_index == pop_index) |
if (push_index == pop_index) |
return (0); |
return (0); |
Line 155 rl_get_char (key)
|
Line 191 rl_get_char (key)
|
Returns non-zero if successful, zero if there is |
Returns non-zero if successful, zero if there is |
no space left in the buffer. */ |
no space left in the buffer. */ |
int |
int |
_rl_unget_char (key) | _rl_unget_char (int key) |
int key; | |
{ |
{ |
if (ibuffer_space ()) |
if (ibuffer_space ()) |
{ |
{ |
Line 173 _rl_unget_char (key)
|
Line 208 _rl_unget_char (key)
|
IBUFFER. Otherwise, just return. Returns number of characters read |
IBUFFER. Otherwise, just return. Returns number of characters read |
(0 if none available) and -1 on error (EIO). */ |
(0 if none available) and -1 on error (EIO). */ |
static int |
static int |
rl_gather_tyi () | rl_gather_tyi (void) |
{ |
{ |
int tty; |
int tty; |
register int tem, result; |
register int tem, result; |
Line 185 rl_gather_tyi ()
|
Line 220 rl_gather_tyi ()
|
#endif |
#endif |
|
|
chars_avail = 0; |
chars_avail = 0; |
|
input = 0; |
tty = fileno (rl_instream); |
tty = fileno (rl_instream); |
|
|
#if defined (HAVE_SELECT) |
#if defined (HAVE_SELECT) |
Line 199 rl_gather_tyi ()
|
Line 235 rl_gather_tyi ()
|
#endif |
#endif |
|
|
result = -1; |
result = -1; |
#if defined (FIONREAD) |
|
errno = 0; |
errno = 0; |
|
#if defined (FIONREAD) |
result = ioctl (tty, FIONREAD, &chars_avail); |
result = ioctl (tty, FIONREAD, &chars_avail); |
if (result == -1 && errno == EIO) |
if (result == -1 && errno == EIO) |
return -1; |
return -1; |
|
if (result == -1) |
|
chars_avail = 0; |
#endif |
#endif |
|
|
#if defined (O_NDELAY) |
#if defined (O_NDELAY) |
Line 217 rl_gather_tyi ()
|
Line 255 rl_gather_tyi ()
|
fcntl (tty, F_SETFL, tem); |
fcntl (tty, F_SETFL, tem); |
if (chars_avail == -1 && errno == EAGAIN) |
if (chars_avail == -1 && errno == EAGAIN) |
return 0; |
return 0; |
|
if (chars_avail == -1 && errno == EIO) |
|
return -1; |
if (chars_avail == 0) /* EOF */ |
if (chars_avail == 0) /* EOF */ |
{ |
{ |
rl_stuff_char (EOF); |
rl_stuff_char (EOF); |
Line 271 rl_gather_tyi ()
|
Line 311 rl_gather_tyi ()
|
} |
} |
|
|
int |
int |
rl_set_keyboard_input_timeout (u) | rl_set_keyboard_input_timeout (int u) |
int u; | |
{ |
{ |
int o; |
int o; |
|
|
Line 289 rl_set_keyboard_input_timeout (u)
|
Line 328 rl_set_keyboard_input_timeout (u)
|
the user, it should use _rl_input_queued(timeout_value_in_microseconds) |
the user, it should use _rl_input_queued(timeout_value_in_microseconds) |
instead. */ |
instead. */ |
int |
int |
_rl_input_available () | _rl_input_available (void) |
{ |
{ |
#if defined(HAVE_SELECT) |
#if defined(HAVE_SELECT) |
fd_set readfds, exceptfds; |
fd_set readfds, exceptfds; |
Line 310 _rl_input_available ()
|
Line 349 _rl_input_available ()
|
FD_ZERO (&exceptfds); |
FD_ZERO (&exceptfds); |
FD_SET (tty, &readfds); |
FD_SET (tty, &readfds); |
FD_SET (tty, &exceptfds); |
FD_SET (tty, &exceptfds); |
timeout.tv_sec = 0; | USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout); |
timeout.tv_usec = _keyboard_input_timeout; | |
return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0); |
return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0); |
#else |
#else |
|
|
Line 331 _rl_input_available ()
|
Line 369 _rl_input_available ()
|
} |
} |
|
|
int |
int |
_rl_input_queued (t) | _rl_nchars_available () |
int t; | |
{ |
{ |
|
int chars_avail, fd, result; |
|
|
|
chars_avail = 0; |
|
|
|
#if defined (FIONREAD) |
|
fd = fileno (rl_instream); |
|
errno = 0; |
|
result = ioctl (fd, FIONREAD, &chars_avail); |
|
if (result == -1 && errno == EIO) |
|
return -1; |
|
#endif |
|
|
|
return chars_avail; |
|
} |
|
|
|
int |
|
_rl_input_queued (int t) |
|
{ |
int old_timeout, r; |
int old_timeout, r; |
|
|
old_timeout = rl_set_keyboard_input_timeout (t); |
old_timeout = rl_set_keyboard_input_timeout (t); |
Line 343 _rl_input_queued (t)
|
Line 398 _rl_input_queued (t)
|
} |
} |
|
|
void |
void |
_rl_insert_typein (c) | _rl_insert_typein (int c) |
int c; | |
{ |
{ |
int key, t, i; |
int key, t, i; |
char *string; |
char *string; |
Line 369 _rl_insert_typein (c)
|
Line 423 _rl_insert_typein (c)
|
/* Add KEY to the buffer of characters to be read. Returns 1 if the |
/* Add KEY to the buffer of characters to be read. Returns 1 if the |
character was stuffed correctly; 0 otherwise. */ |
character was stuffed correctly; 0 otherwise. */ |
int |
int |
rl_stuff_char (key) | rl_stuff_char (int key) |
int key; | |
{ |
{ |
if (ibuffer_space () == 0) |
if (ibuffer_space () == 0) |
return 0; |
return 0; |
Line 394 rl_stuff_char (key)
|
Line 447 rl_stuff_char (key)
|
|
|
/* Make C be the next command to be executed. */ |
/* Make C be the next command to be executed. */ |
int |
int |
rl_execute_next (c) | rl_execute_next (int c) |
int c; | |
{ |
{ |
rl_pending_input = c; |
rl_pending_input = c; |
RL_SETSTATE (RL_STATE_INPUTPENDING); |
RL_SETSTATE (RL_STATE_INPUTPENDING); |
Line 404 rl_execute_next (c)
|
Line 456 rl_execute_next (c)
|
|
|
/* Clear any pending input pushed with rl_execute_next() */ |
/* Clear any pending input pushed with rl_execute_next() */ |
int |
int |
rl_clear_pending_input () | rl_clear_pending_input (void) |
{ |
{ |
rl_pending_input = 0; |
rl_pending_input = 0; |
RL_UNSETSTATE (RL_STATE_INPUTPENDING); |
RL_UNSETSTATE (RL_STATE_INPUTPENDING); |
Line 419 rl_clear_pending_input ()
|
Line 471 rl_clear_pending_input ()
|
|
|
/* Read a key, including pending input. */ |
/* Read a key, including pending input. */ |
int |
int |
rl_read_key () | rl_read_key (void) |
{ |
{ |
int c, r; |
int c, r; |
|
|
if (rl_pending_input) |
if (rl_pending_input) |
{ |
{ |
c = rl_pending_input; | c = rl_pending_input; /* XXX - cast to unsigned char if > 0? */ |
rl_clear_pending_input (); |
rl_clear_pending_input (); |
} |
} |
else |
else |
{ |
{ |
/* If input is coming from a macro, then use that. */ |
/* If input is coming from a macro, then use that. */ |
if (c = _rl_next_macro_key ()) |
if (c = _rl_next_macro_key ()) |
return (c); | return ((unsigned char)c); |
|
|
/* If the user has an event function, then call it periodically. */ |
/* If the user has an event function, then call it periodically. */ |
if (rl_event_hook) |
if (rl_event_hook) |
Line 445 rl_read_key ()
|
Line 497 rl_read_key ()
|
if ((r = rl_gather_tyi ()) < 0) /* XXX - EIO */ |
if ((r = rl_gather_tyi ()) < 0) /* XXX - EIO */ |
{ |
{ |
rl_done = 1; |
rl_done = 1; |
return ('\n'); | return (errno == EIO ? (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF) : '\n'); |
} |
} |
else if (r > 0) /* read something */ |
else if (r > 0) /* read something */ |
continue; |
continue; |
Line 460 rl_read_key ()
|
Line 512 rl_read_key ()
|
{ |
{ |
if (rl_get_char (&c) == 0) |
if (rl_get_char (&c) == 0) |
c = (*rl_getc_function) (rl_instream); |
c = (*rl_getc_function) (rl_instream); |
/* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d", _rl_caught_signal); */ | /* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d\r\n", _rl_caught_signal); */ |
RL_CHECK_SIGNALS (); |
RL_CHECK_SIGNALS (); |
} |
} |
} |
} |
Line 469 rl_read_key ()
|
Line 521 rl_read_key ()
|
} |
} |
|
|
int |
int |
rl_getc (stream) | rl_getc (FILE *stream) |
FILE *stream; | |
{ |
{ |
int result; |
int result; |
unsigned char c; |
unsigned char c; |
|
#if defined (HAVE_PSELECT) |
|
sigset_t empty_set; |
|
fd_set readfds; |
|
#endif |
|
|
while (1) |
while (1) |
{ |
{ |
Line 483 rl_getc (stream)
|
Line 538 rl_getc (stream)
|
|
|
#if defined (__MINGW32__) |
#if defined (__MINGW32__) |
if (isatty (fileno (stream))) |
if (isatty (fileno (stream))) |
return (getch ()); | return (_getch ()); /* "There is no error return." */ |
#endif |
#endif |
result = read (fileno (stream), &c, sizeof (unsigned char)); | result = 0; |
| #if defined (HAVE_PSELECT) |
| FD_ZERO (&readfds); |
| FD_SET (fileno (stream), &readfds); |
| # if defined (HANDLE_SIGNALS) |
| result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &_rl_orig_sigset); |
| # else |
| sigemptyset (&empty_set); |
| sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &empty_set); |
| result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &empty_set); |
| # endif /* HANDLE_SIGNALS */ |
| #endif |
| if (result >= 0) |
| result = read (fileno (stream), &c, sizeof (unsigned char)); |
|
|
if (result == sizeof (unsigned char)) |
if (result == sizeof (unsigned char)) |
return (c); |
return (c); |
Line 524 rl_getc (stream)
|
Line 592 rl_getc (stream)
|
|
|
/* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */ |
/* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */ |
|
|
|
handle_error: |
/* If the error that we received was EINTR, then try again, |
/* If the error that we received was EINTR, then try again, |
this is simply an interrupted system call to read (). We allow |
this is simply an interrupted system call to read (). We allow |
the read to be interrupted if we caught SIGHUP or SIGTERM (but | the read to be interrupted if we caught SIGHUP, SIGTERM, or any |
not SIGINT; let the signal handler deal with that), but if the | of the other signals readline treats specially. If the |
application sets an event hook, call it for other signals. |
application sets an event hook, call it for other signals. |
Otherwise (not EINTR), some error occurred, also signifying EOF. */ |
Otherwise (not EINTR), some error occurred, also signifying EOF. */ |
if (errno != EINTR) |
if (errno != EINTR) |
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF); |
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF); |
|
/* fatal signals of interest */ |
|
#if defined (SIGHUP) |
else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM) |
else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM) |
|
#else |
|
else if (_rl_caught_signal == SIGTERM) |
|
#endif |
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF); |
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF); |
/* keyboard-generated signals of interest */ |
/* keyboard-generated signals of interest */ |
|
#if defined (SIGQUIT) |
else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT) |
else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT) |
|
#else |
|
else if (_rl_caught_signal == SIGINT) |
|
#endif |
RL_CHECK_SIGNALS (); |
RL_CHECK_SIGNALS (); |
|
#if defined (SIGTSTP) |
|
else if (_rl_caught_signal == SIGTSTP) |
|
RL_CHECK_SIGNALS (); |
|
#endif |
/* non-keyboard-generated signals of interest */ |
/* non-keyboard-generated signals of interest */ |
|
#if defined (SIGWINCH) |
|
else if (_rl_caught_signal == SIGWINCH) |
|
RL_CHECK_SIGNALS (); |
|
#endif /* SIGWINCH */ |
|
#if defined (SIGALRM) |
else if (_rl_caught_signal == SIGALRM |
else if (_rl_caught_signal == SIGALRM |
#if defined (SIGVTALRM) | # if defined (SIGVTALRM) |
|| _rl_caught_signal == SIGVTALRM |
|| _rl_caught_signal == SIGVTALRM |
#endif | # endif |
) |
) |
RL_CHECK_SIGNALS (); |
RL_CHECK_SIGNALS (); |
|
#endif /* SIGALRM */ |
|
|
if (rl_signal_event_hook) |
if (rl_signal_event_hook) |
(*rl_signal_event_hook) (); |
(*rl_signal_event_hook) (); |
Line 553 rl_getc (stream)
|
Line 641 rl_getc (stream)
|
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
/* read multibyte char */ |
/* read multibyte char */ |
int |
int |
_rl_read_mbchar (mbchar, size) | _rl_read_mbchar (char *mbchar, int size) |
char *mbchar; | |
int size; | |
{ |
{ |
int mb_len, c; |
int mb_len, c; |
size_t mbchar_bytes_length; |
size_t mbchar_bytes_length; |
Line 568 _rl_read_mbchar (mbchar, size)
|
Line 654 _rl_read_mbchar (mbchar, size)
|
mb_len = 0; |
mb_len = 0; |
while (mb_len < size) |
while (mb_len < size) |
{ |
{ |
RL_SETSTATE(RL_STATE_MOREINPUT); | c = (mb_len == 0) ? _rl_bracketed_read_key () : rl_read_key (); |
c = rl_read_key (); | |
RL_UNSETSTATE(RL_STATE_MOREINPUT); | |
|
|
if (c < 0) |
if (c < 0) |
break; |
break; |
Line 604 _rl_read_mbchar (mbchar, size)
|
Line 688 _rl_read_mbchar (mbchar, size)
|
may be FIRST. Used by the search functions, among others. Very similar |
may be FIRST. Used by the search functions, among others. Very similar |
to _rl_read_mbchar. */ |
to _rl_read_mbchar. */ |
int |
int |
_rl_read_mbstring (first, mb, mlen) | _rl_read_mbstring (int first, char *mb, int mlen) |
int first; | |
char *mb; | |
int mlen; | |
{ |
{ |
int i, c; | int i, c, n; |
mbstate_t ps; |
mbstate_t ps; |
|
|
c = first; |
c = first; |
Line 618 _rl_read_mbstring (first, mb, mlen)
|
Line 699 _rl_read_mbstring (first, mb, mlen)
|
{ |
{ |
mb[i] = (char)c; |
mb[i] = (char)c; |
memset (&ps, 0, sizeof (mbstate_t)); |
memset (&ps, 0, sizeof (mbstate_t)); |
if (_rl_get_char_len (mb, &ps) == -2) | n = _rl_get_char_len (mb, &ps); |
| if (n == -2) |
{ |
{ |
/* Read more for multibyte character */ |
/* Read more for multibyte character */ |
RL_SETSTATE (RL_STATE_MOREINPUT); |
RL_SETSTATE (RL_STATE_MOREINPUT); |