Annotation of embedaddon/readline/input.c, revision 1.1
1.1 ! misho 1: /* input.c -- character input functions for readline. */
! 2:
! 3: /* Copyright (C) 1994-2013 Free Software Foundation, Inc.
! 4:
! 5: This file is part of the GNU Readline Library (Readline), a library
! 6: for reading lines of text with interactive input and history editing.
! 7:
! 8: Readline is free software: you can redistribute it and/or modify
! 9: it under the terms of the GNU General Public License as published by
! 10: the Free Software Foundation, either version 3 of the License, or
! 11: (at your option) any later version.
! 12:
! 13: Readline is distributed in the hope that it will be useful,
! 14: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 16: GNU General Public License for more details.
! 17:
! 18: You should have received a copy of the GNU General Public License
! 19: along with Readline. If not, see <http://www.gnu.org/licenses/>.
! 20: */
! 21:
! 22: #define READLINE_LIBRARY
! 23:
! 24: #if defined (__TANDEM)
! 25: # include <floss.h>
! 26: #endif
! 27:
! 28: #if defined (HAVE_CONFIG_H)
! 29: # include <config.h>
! 30: #endif
! 31:
! 32: #include <sys/types.h>
! 33: #include <fcntl.h>
! 34: #if defined (HAVE_SYS_FILE_H)
! 35: # include <sys/file.h>
! 36: #endif /* HAVE_SYS_FILE_H */
! 37:
! 38: #if defined (HAVE_UNISTD_H)
! 39: # include <unistd.h>
! 40: #endif /* HAVE_UNISTD_H */
! 41:
! 42: #if defined (HAVE_STDLIB_H)
! 43: # include <stdlib.h>
! 44: #else
! 45: # include "ansi_stdlib.h"
! 46: #endif /* HAVE_STDLIB_H */
! 47:
! 48: #include <signal.h>
! 49:
! 50: #include "posixselect.h"
! 51:
! 52: #if defined (FIONREAD_IN_SYS_IOCTL)
! 53: # include <sys/ioctl.h>
! 54: #endif
! 55:
! 56: #include <stdio.h>
! 57: #include <errno.h>
! 58:
! 59: #if !defined (errno)
! 60: extern int errno;
! 61: #endif /* !errno */
! 62:
! 63: /* System-specific feature definitions and include files. */
! 64: #include "rldefs.h"
! 65: #include "rlmbutil.h"
! 66:
! 67: /* Some standard library routines. */
! 68: #include "readline.h"
! 69:
! 70: #include "rlprivate.h"
! 71: #include "rlshell.h"
! 72: #include "xmalloc.h"
! 73:
! 74: /* What kind of non-blocking I/O do we have? */
! 75: #if !defined (O_NDELAY) && defined (O_NONBLOCK)
! 76: # define O_NDELAY O_NONBLOCK /* Posix style */
! 77: #endif
! 78:
! 79: /* Non-null means it is a pointer to a function to run while waiting for
! 80: character input. */
! 81: rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
! 82:
! 83: /* A function to call if a read(2) is interrupted by a signal. */
! 84: rl_hook_func_t *rl_signal_event_hook = (rl_hook_func_t *)NULL;
! 85:
! 86: /* A function to replace _rl_input_available for applications using the
! 87: callback interface. */
! 88: rl_hook_func_t *rl_input_available_hook = (rl_hook_func_t *)NULL;
! 89:
! 90: rl_getc_func_t *rl_getc_function = rl_getc;
! 91:
! 92: static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */
! 93:
! 94: static int ibuffer_space PARAMS((void));
! 95: static int rl_get_char PARAMS((int *));
! 96: static int rl_gather_tyi PARAMS((void));
! 97:
! 98: /* **************************************************************** */
! 99: /* */
! 100: /* Character Input Buffering */
! 101: /* */
! 102: /* **************************************************************** */
! 103:
! 104: static int pop_index, push_index;
! 105: static unsigned char ibuffer[512];
! 106: static int ibuffer_len = sizeof (ibuffer) - 1;
! 107:
! 108: #define any_typein (push_index != pop_index)
! 109:
! 110: int
! 111: _rl_any_typein ()
! 112: {
! 113: return any_typein;
! 114: }
! 115:
! 116: int
! 117: _rl_pushed_input_available ()
! 118: {
! 119: return (push_index != pop_index);
! 120: }
! 121:
! 122: /* Return the amount of space available in the buffer for stuffing
! 123: characters. */
! 124: static int
! 125: ibuffer_space ()
! 126: {
! 127: if (pop_index > push_index)
! 128: return (pop_index - push_index - 1);
! 129: else
! 130: return (ibuffer_len - (push_index - pop_index));
! 131: }
! 132:
! 133: /* Get a key from the buffer of characters to be read.
! 134: Return the key in KEY.
! 135: Result is non-zero if there was a key, or 0 if there wasn't. */
! 136: static int
! 137: rl_get_char (key)
! 138: int *key;
! 139: {
! 140: if (push_index == pop_index)
! 141: return (0);
! 142:
! 143: *key = ibuffer[pop_index++];
! 144: #if 0
! 145: if (pop_index >= ibuffer_len)
! 146: #else
! 147: if (pop_index > ibuffer_len)
! 148: #endif
! 149: pop_index = 0;
! 150:
! 151: return (1);
! 152: }
! 153:
! 154: /* Stuff KEY into the *front* of the input buffer.
! 155: Returns non-zero if successful, zero if there is
! 156: no space left in the buffer. */
! 157: int
! 158: _rl_unget_char (key)
! 159: int key;
! 160: {
! 161: if (ibuffer_space ())
! 162: {
! 163: pop_index--;
! 164: if (pop_index < 0)
! 165: pop_index = ibuffer_len;
! 166: ibuffer[pop_index] = key;
! 167: return (1);
! 168: }
! 169: return (0);
! 170: }
! 171:
! 172: /* If a character is available to be read, then read it and stuff it into
! 173: IBUFFER. Otherwise, just return. Returns number of characters read
! 174: (0 if none available) and -1 on error (EIO). */
! 175: static int
! 176: rl_gather_tyi ()
! 177: {
! 178: int tty;
! 179: register int tem, result;
! 180: int chars_avail, k;
! 181: char input;
! 182: #if defined(HAVE_SELECT)
! 183: fd_set readfds, exceptfds;
! 184: struct timeval timeout;
! 185: #endif
! 186:
! 187: chars_avail = 0;
! 188: tty = fileno (rl_instream);
! 189:
! 190: #if defined (HAVE_SELECT)
! 191: FD_ZERO (&readfds);
! 192: FD_ZERO (&exceptfds);
! 193: FD_SET (tty, &readfds);
! 194: FD_SET (tty, &exceptfds);
! 195: USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout);
! 196: result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
! 197: if (result <= 0)
! 198: return 0; /* Nothing to read. */
! 199: #endif
! 200:
! 201: result = -1;
! 202: #if defined (FIONREAD)
! 203: errno = 0;
! 204: result = ioctl (tty, FIONREAD, &chars_avail);
! 205: if (result == -1 && errno == EIO)
! 206: return -1;
! 207: #endif
! 208:
! 209: #if defined (O_NDELAY)
! 210: if (result == -1)
! 211: {
! 212: tem = fcntl (tty, F_GETFL, 0);
! 213:
! 214: fcntl (tty, F_SETFL, (tem | O_NDELAY));
! 215: chars_avail = read (tty, &input, 1);
! 216:
! 217: fcntl (tty, F_SETFL, tem);
! 218: if (chars_avail == -1 && errno == EAGAIN)
! 219: return 0;
! 220: if (chars_avail == 0) /* EOF */
! 221: {
! 222: rl_stuff_char (EOF);
! 223: return (0);
! 224: }
! 225: }
! 226: #endif /* O_NDELAY */
! 227:
! 228: #if defined (__MINGW32__)
! 229: /* Use getch/_kbhit to check for available console input, in the same way
! 230: that we read it normally. */
! 231: chars_avail = isatty (tty) ? _kbhit () : 0;
! 232: result = 0;
! 233: #endif
! 234:
! 235: /* If there's nothing available, don't waste time trying to read
! 236: something. */
! 237: if (chars_avail <= 0)
! 238: return 0;
! 239:
! 240: tem = ibuffer_space ();
! 241:
! 242: if (chars_avail > tem)
! 243: chars_avail = tem;
! 244:
! 245: /* One cannot read all of the available input. I can only read a single
! 246: character at a time, or else programs which require input can be
! 247: thwarted. If the buffer is larger than one character, I lose.
! 248: Damn! */
! 249: if (tem < ibuffer_len)
! 250: chars_avail = 0;
! 251:
! 252: if (result != -1)
! 253: {
! 254: while (chars_avail--)
! 255: {
! 256: RL_CHECK_SIGNALS ();
! 257: k = (*rl_getc_function) (rl_instream);
! 258: if (rl_stuff_char (k) == 0)
! 259: break; /* some problem; no more room */
! 260: if (k == NEWLINE || k == RETURN)
! 261: break;
! 262: }
! 263: }
! 264: else
! 265: {
! 266: if (chars_avail)
! 267: rl_stuff_char (input);
! 268: }
! 269:
! 270: return 1;
! 271: }
! 272:
! 273: int
! 274: rl_set_keyboard_input_timeout (u)
! 275: int u;
! 276: {
! 277: int o;
! 278:
! 279: o = _keyboard_input_timeout;
! 280: if (u >= 0)
! 281: _keyboard_input_timeout = u;
! 282: return (o);
! 283: }
! 284:
! 285: /* Is there input available to be read on the readline input file
! 286: descriptor? Only works if the system has select(2) or FIONREAD.
! 287: Uses the value of _keyboard_input_timeout as the timeout; if another
! 288: readline function wants to specify a timeout and not leave it up to
! 289: the user, it should use _rl_input_queued(timeout_value_in_microseconds)
! 290: instead. */
! 291: int
! 292: _rl_input_available ()
! 293: {
! 294: #if defined(HAVE_SELECT)
! 295: fd_set readfds, exceptfds;
! 296: struct timeval timeout;
! 297: #endif
! 298: #if !defined (HAVE_SELECT) && defined(FIONREAD)
! 299: int chars_avail;
! 300: #endif
! 301: int tty;
! 302:
! 303: if (rl_input_available_hook)
! 304: return (*rl_input_available_hook) ();
! 305:
! 306: tty = fileno (rl_instream);
! 307:
! 308: #if defined (HAVE_SELECT)
! 309: FD_ZERO (&readfds);
! 310: FD_ZERO (&exceptfds);
! 311: FD_SET (tty, &readfds);
! 312: FD_SET (tty, &exceptfds);
! 313: timeout.tv_sec = 0;
! 314: timeout.tv_usec = _keyboard_input_timeout;
! 315: return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
! 316: #else
! 317:
! 318: #if defined (FIONREAD)
! 319: if (ioctl (tty, FIONREAD, &chars_avail) == 0)
! 320: return (chars_avail);
! 321: #endif
! 322:
! 323: #endif
! 324:
! 325: #if defined (__MINGW32__)
! 326: if (isatty (tty))
! 327: return (_kbhit ());
! 328: #endif
! 329:
! 330: return 0;
! 331: }
! 332:
! 333: int
! 334: _rl_input_queued (t)
! 335: int t;
! 336: {
! 337: int old_timeout, r;
! 338:
! 339: old_timeout = rl_set_keyboard_input_timeout (t);
! 340: r = _rl_input_available ();
! 341: rl_set_keyboard_input_timeout (old_timeout);
! 342: return r;
! 343: }
! 344:
! 345: void
! 346: _rl_insert_typein (c)
! 347: int c;
! 348: {
! 349: int key, t, i;
! 350: char *string;
! 351:
! 352: i = key = 0;
! 353: string = (char *)xmalloc (ibuffer_len + 1);
! 354: string[i++] = (char) c;
! 355:
! 356: while ((t = rl_get_char (&key)) &&
! 357: _rl_keymap[key].type == ISFUNC &&
! 358: _rl_keymap[key].function == rl_insert)
! 359: string[i++] = key;
! 360:
! 361: if (t)
! 362: _rl_unget_char (key);
! 363:
! 364: string[i] = '\0';
! 365: rl_insert_text (string);
! 366: xfree (string);
! 367: }
! 368:
! 369: /* Add KEY to the buffer of characters to be read. Returns 1 if the
! 370: character was stuffed correctly; 0 otherwise. */
! 371: int
! 372: rl_stuff_char (key)
! 373: int key;
! 374: {
! 375: if (ibuffer_space () == 0)
! 376: return 0;
! 377:
! 378: if (key == EOF)
! 379: {
! 380: key = NEWLINE;
! 381: rl_pending_input = EOF;
! 382: RL_SETSTATE (RL_STATE_INPUTPENDING);
! 383: }
! 384: ibuffer[push_index++] = key;
! 385: #if 0
! 386: if (push_index >= ibuffer_len)
! 387: #else
! 388: if (push_index > ibuffer_len)
! 389: #endif
! 390: push_index = 0;
! 391:
! 392: return 1;
! 393: }
! 394:
! 395: /* Make C be the next command to be executed. */
! 396: int
! 397: rl_execute_next (c)
! 398: int c;
! 399: {
! 400: rl_pending_input = c;
! 401: RL_SETSTATE (RL_STATE_INPUTPENDING);
! 402: return 0;
! 403: }
! 404:
! 405: /* Clear any pending input pushed with rl_execute_next() */
! 406: int
! 407: rl_clear_pending_input ()
! 408: {
! 409: rl_pending_input = 0;
! 410: RL_UNSETSTATE (RL_STATE_INPUTPENDING);
! 411: return 0;
! 412: }
! 413:
! 414: /* **************************************************************** */
! 415: /* */
! 416: /* Character Input */
! 417: /* */
! 418: /* **************************************************************** */
! 419:
! 420: /* Read a key, including pending input. */
! 421: int
! 422: rl_read_key ()
! 423: {
! 424: int c, r;
! 425:
! 426: if (rl_pending_input)
! 427: {
! 428: c = rl_pending_input;
! 429: rl_clear_pending_input ();
! 430: }
! 431: else
! 432: {
! 433: /* If input is coming from a macro, then use that. */
! 434: if (c = _rl_next_macro_key ())
! 435: return (c);
! 436:
! 437: /* If the user has an event function, then call it periodically. */
! 438: if (rl_event_hook)
! 439: {
! 440: while (rl_event_hook)
! 441: {
! 442: if (rl_get_char (&c) != 0)
! 443: break;
! 444:
! 445: if ((r = rl_gather_tyi ()) < 0) /* XXX - EIO */
! 446: {
! 447: rl_done = 1;
! 448: return ('\n');
! 449: }
! 450: else if (r > 0) /* read something */
! 451: continue;
! 452:
! 453: RL_CHECK_SIGNALS ();
! 454: if (rl_done) /* XXX - experimental */
! 455: return ('\n');
! 456: (*rl_event_hook) ();
! 457: }
! 458: }
! 459: else
! 460: {
! 461: if (rl_get_char (&c) == 0)
! 462: c = (*rl_getc_function) (rl_instream);
! 463: /* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d", _rl_caught_signal); */
! 464: RL_CHECK_SIGNALS ();
! 465: }
! 466: }
! 467:
! 468: return (c);
! 469: }
! 470:
! 471: int
! 472: rl_getc (stream)
! 473: FILE *stream;
! 474: {
! 475: int result;
! 476: unsigned char c;
! 477:
! 478: while (1)
! 479: {
! 480: RL_CHECK_SIGNALS ();
! 481:
! 482: /* We know at this point that _rl_caught_signal == 0 */
! 483:
! 484: #if defined (__MINGW32__)
! 485: if (isatty (fileno (stream)))
! 486: return (getch ());
! 487: #endif
! 488: result = read (fileno (stream), &c, sizeof (unsigned char));
! 489:
! 490: if (result == sizeof (unsigned char))
! 491: return (c);
! 492:
! 493: /* If zero characters are returned, then the file that we are
! 494: reading from is empty! Return EOF in that case. */
! 495: if (result == 0)
! 496: return (EOF);
! 497:
! 498: #if defined (__BEOS__)
! 499: if (errno == EINTR)
! 500: continue;
! 501: #endif
! 502:
! 503: #if defined (EWOULDBLOCK)
! 504: # define X_EWOULDBLOCK EWOULDBLOCK
! 505: #else
! 506: # define X_EWOULDBLOCK -99
! 507: #endif
! 508:
! 509: #if defined (EAGAIN)
! 510: # define X_EAGAIN EAGAIN
! 511: #else
! 512: # define X_EAGAIN -99
! 513: #endif
! 514:
! 515: if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)
! 516: {
! 517: if (sh_unset_nodelay_mode (fileno (stream)) < 0)
! 518: return (EOF);
! 519: continue;
! 520: }
! 521:
! 522: #undef X_EWOULDBLOCK
! 523: #undef X_EAGAIN
! 524:
! 525: /* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */
! 526:
! 527: /* If the error that we received was EINTR, then try again,
! 528: this is simply an interrupted system call to read (). We allow
! 529: the read to be interrupted if we caught SIGHUP or SIGTERM (but
! 530: not SIGINT; let the signal handler deal with that), but if the
! 531: application sets an event hook, call it for other signals.
! 532: Otherwise (not EINTR), some error occurred, also signifying EOF. */
! 533: if (errno != EINTR)
! 534: return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
! 535: else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM)
! 536: return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
! 537: else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT)
! 538: RL_CHECK_SIGNALS ();
! 539:
! 540: if (rl_signal_event_hook)
! 541: (*rl_signal_event_hook) ();
! 542: }
! 543: }
! 544:
! 545: #if defined (HANDLE_MULTIBYTE)
! 546: /* read multibyte char */
! 547: int
! 548: _rl_read_mbchar (mbchar, size)
! 549: char *mbchar;
! 550: int size;
! 551: {
! 552: int mb_len, c;
! 553: size_t mbchar_bytes_length;
! 554: wchar_t wc;
! 555: mbstate_t ps, ps_back;
! 556:
! 557: memset(&ps, 0, sizeof (mbstate_t));
! 558: memset(&ps_back, 0, sizeof (mbstate_t));
! 559:
! 560: mb_len = 0;
! 561: while (mb_len < size)
! 562: {
! 563: RL_SETSTATE(RL_STATE_MOREINPUT);
! 564: c = rl_read_key ();
! 565: RL_UNSETSTATE(RL_STATE_MOREINPUT);
! 566:
! 567: if (c < 0)
! 568: break;
! 569:
! 570: mbchar[mb_len++] = c;
! 571:
! 572: mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
! 573: if (mbchar_bytes_length == (size_t)(-1))
! 574: break; /* invalid byte sequence for the current locale */
! 575: else if (mbchar_bytes_length == (size_t)(-2))
! 576: {
! 577: /* shorted bytes */
! 578: ps = ps_back;
! 579: continue;
! 580: }
! 581: else if (mbchar_bytes_length == 0)
! 582: {
! 583: mbchar[0] = '\0'; /* null wide character */
! 584: mb_len = 1;
! 585: break;
! 586: }
! 587: else if (mbchar_bytes_length > (size_t)(0))
! 588: break;
! 589: }
! 590:
! 591: return mb_len;
! 592: }
! 593:
! 594: /* Read a multibyte-character string whose first character is FIRST into
! 595: the buffer MB of length MLEN. Returns the last character read, which
! 596: may be FIRST. Used by the search functions, among others. Very similar
! 597: to _rl_read_mbchar. */
! 598: int
! 599: _rl_read_mbstring (first, mb, mlen)
! 600: int first;
! 601: char *mb;
! 602: int mlen;
! 603: {
! 604: int i, c;
! 605: mbstate_t ps;
! 606:
! 607: c = first;
! 608: memset (mb, 0, mlen);
! 609: for (i = 0; c >= 0 && i < mlen; i++)
! 610: {
! 611: mb[i] = (char)c;
! 612: memset (&ps, 0, sizeof (mbstate_t));
! 613: if (_rl_get_char_len (mb, &ps) == -2)
! 614: {
! 615: /* Read more for multibyte character */
! 616: RL_SETSTATE (RL_STATE_MOREINPUT);
! 617: c = rl_read_key ();
! 618: RL_UNSETSTATE (RL_STATE_MOREINPUT);
! 619: }
! 620: else
! 621: break;
! 622: }
! 623: return c;
! 624: }
! 625: #endif /* HANDLE_MULTIBYTE */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>