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>