--- embedaddon/readline/input.c 2016/11/03 13:35:37 1.1.1.2 +++ embedaddon/readline/input.c 2021/03/17 01:01:01 1.1.1.3 @@ -1,6 +1,6 @@ /* 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 for reading lines of text with interactive input and history editing. @@ -22,6 +22,8 @@ #define READLINE_LIBRARY #if defined (__TANDEM) +# define _XOPEN_SOURCE_EXTENDED 1 +# define _TANDEM_SOURCE 1 # include #endif @@ -76,6 +78,10 @@ extern int errno; # define O_NDELAY O_NONBLOCK /* Posix style */ #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 character input. */ rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; @@ -95,6 +101,37 @@ static int ibuffer_space PARAMS((void)); static int rl_get_char PARAMS((int *)); 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 +#include +#define WIN32_LEAN_AND_MEAN 1 +#include + +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 */ @@ -108,13 +145,13 @@ static int ibuffer_len = sizeof (ibuffer) - 1; #define any_typein (push_index != pop_index) int -_rl_any_typein () +_rl_any_typein (void) { return any_typein; } int -_rl_pushed_input_available () +_rl_pushed_input_available (void) { return (push_index != pop_index); } @@ -122,7 +159,7 @@ _rl_pushed_input_available () /* Return the amount of space available in the buffer for stuffing characters. */ static int -ibuffer_space () +ibuffer_space (void) { if (pop_index > push_index) return (pop_index - push_index - 1); @@ -134,8 +171,7 @@ ibuffer_space () Return the key in KEY. Result is non-zero if there was a key, or 0 if there wasn't. */ static int -rl_get_char (key) - int *key; +rl_get_char (int *key) { if (push_index == pop_index) return (0); @@ -155,8 +191,7 @@ rl_get_char (key) Returns non-zero if successful, zero if there is no space left in the buffer. */ int -_rl_unget_char (key) - int key; +_rl_unget_char (int key) { if (ibuffer_space ()) { @@ -173,7 +208,7 @@ _rl_unget_char (key) IBUFFER. Otherwise, just return. Returns number of characters read (0 if none available) and -1 on error (EIO). */ static int -rl_gather_tyi () +rl_gather_tyi (void) { int tty; register int tem, result; @@ -185,6 +220,7 @@ rl_gather_tyi () #endif chars_avail = 0; + input = 0; tty = fileno (rl_instream); #if defined (HAVE_SELECT) @@ -199,11 +235,13 @@ rl_gather_tyi () #endif result = -1; -#if defined (FIONREAD) errno = 0; +#if defined (FIONREAD) result = ioctl (tty, FIONREAD, &chars_avail); if (result == -1 && errno == EIO) return -1; + if (result == -1) + chars_avail = 0; #endif #if defined (O_NDELAY) @@ -217,6 +255,8 @@ rl_gather_tyi () fcntl (tty, F_SETFL, tem); if (chars_avail == -1 && errno == EAGAIN) return 0; + if (chars_avail == -1 && errno == EIO) + return -1; if (chars_avail == 0) /* EOF */ { rl_stuff_char (EOF); @@ -271,8 +311,7 @@ rl_gather_tyi () } int -rl_set_keyboard_input_timeout (u) - int u; +rl_set_keyboard_input_timeout (int u) { int o; @@ -289,7 +328,7 @@ rl_set_keyboard_input_timeout (u) the user, it should use _rl_input_queued(timeout_value_in_microseconds) instead. */ int -_rl_input_available () +_rl_input_available (void) { #if defined(HAVE_SELECT) fd_set readfds, exceptfds; @@ -310,8 +349,7 @@ _rl_input_available () 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); return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0); #else @@ -331,9 +369,26 @@ _rl_input_available () } int -_rl_input_queued (t) - int t; +_rl_nchars_available () { + 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; old_timeout = rl_set_keyboard_input_timeout (t); @@ -343,8 +398,7 @@ _rl_input_queued (t) } void -_rl_insert_typein (c) - int c; +_rl_insert_typein (int c) { int key, t, i; char *string; @@ -369,8 +423,7 @@ _rl_insert_typein (c) /* Add KEY to the buffer of characters to be read. Returns 1 if the character was stuffed correctly; 0 otherwise. */ int -rl_stuff_char (key) - int key; +rl_stuff_char (int key) { if (ibuffer_space () == 0) return 0; @@ -394,8 +447,7 @@ rl_stuff_char (key) /* Make C be the next command to be executed. */ int -rl_execute_next (c) - int c; +rl_execute_next (int c) { rl_pending_input = c; RL_SETSTATE (RL_STATE_INPUTPENDING); @@ -404,7 +456,7 @@ rl_execute_next (c) /* Clear any pending input pushed with rl_execute_next() */ int -rl_clear_pending_input () +rl_clear_pending_input (void) { rl_pending_input = 0; RL_UNSETSTATE (RL_STATE_INPUTPENDING); @@ -419,20 +471,20 @@ rl_clear_pending_input () /* Read a key, including pending input. */ int -rl_read_key () +rl_read_key (void) { int c, r; if (rl_pending_input) { - c = rl_pending_input; + c = rl_pending_input; /* XXX - cast to unsigned char if > 0? */ rl_clear_pending_input (); } else { /* If input is coming from a macro, then use that. */ if (c = _rl_next_macro_key ()) - return (c); + return ((unsigned char)c); /* If the user has an event function, then call it periodically. */ if (rl_event_hook) @@ -445,7 +497,7 @@ rl_read_key () if ((r = rl_gather_tyi ()) < 0) /* XXX - EIO */ { rl_done = 1; - return ('\n'); + return (errno == EIO ? (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF) : '\n'); } else if (r > 0) /* read something */ continue; @@ -460,7 +512,7 @@ rl_read_key () { 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); */ +/* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d\r\n", _rl_caught_signal); */ RL_CHECK_SIGNALS (); } } @@ -469,11 +521,14 @@ rl_read_key () } int -rl_getc (stream) - FILE *stream; +rl_getc (FILE *stream) { int result; unsigned char c; +#if defined (HAVE_PSELECT) + sigset_t empty_set; + fd_set readfds; +#endif while (1) { @@ -483,9 +538,22 @@ rl_getc (stream) #if defined (__MINGW32__) if (isatty (fileno (stream))) - return (getch ()); + return (_getch ()); /* "There is no error return." */ #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)) return (c); @@ -524,26 +592,46 @@ rl_getc (stream) /* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */ +handle_error: /* 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 + the read to be interrupted if we caught SIGHUP, SIGTERM, or any + of the other signals readline treats specially. 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); + /* fatal signals of interest */ +#if defined (SIGHUP) 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); /* keyboard-generated signals of interest */ +#if defined (SIGQUIT) else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT) +#else + else if (_rl_caught_signal == SIGINT) +#endif RL_CHECK_SIGNALS (); +#if defined (SIGTSTP) + else if (_rl_caught_signal == SIGTSTP) + RL_CHECK_SIGNALS (); +#endif /* 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 -#if defined (SIGVTALRM) +# if defined (SIGVTALRM) || _rl_caught_signal == SIGVTALRM -#endif +# endif ) RL_CHECK_SIGNALS (); +#endif /* SIGALRM */ if (rl_signal_event_hook) (*rl_signal_event_hook) (); @@ -553,9 +641,7 @@ rl_getc (stream) #if defined (HANDLE_MULTIBYTE) /* read multibyte char */ int -_rl_read_mbchar (mbchar, size) - char *mbchar; - int size; +_rl_read_mbchar (char *mbchar, int size) { int mb_len, c; size_t mbchar_bytes_length; @@ -568,9 +654,7 @@ _rl_read_mbchar (mbchar, size) mb_len = 0; while (mb_len < size) { - RL_SETSTATE(RL_STATE_MOREINPUT); - c = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); + c = (mb_len == 0) ? _rl_bracketed_read_key () : rl_read_key (); if (c < 0) break; @@ -604,12 +688,9 @@ _rl_read_mbchar (mbchar, size) may be FIRST. Used by the search functions, among others. Very similar to _rl_read_mbchar. */ int -_rl_read_mbstring (first, mb, mlen) - int first; - char *mb; - int mlen; +_rl_read_mbstring (int first, char *mb, int mlen) { - int i, c; + int i, c, n; mbstate_t ps; c = first; @@ -618,7 +699,8 @@ _rl_read_mbstring (first, mb, mlen) { mb[i] = (char)c; 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 */ RL_SETSTATE (RL_STATE_MOREINPUT);