input.c revision 75406
121308Sache/* input.c -- character input functions for readline. */ 221308Sache 321308Sache/* Copyright (C) 1994 Free Software Foundation, Inc. 421308Sache 521308Sache This file is part of the GNU Readline Library, a library for 621308Sache reading lines of text with interactive input and history editing. 721308Sache 821308Sache The GNU Readline Library is free software; you can redistribute it 921308Sache and/or modify it under the terms of the GNU General Public License 1021308Sache as published by the Free Software Foundation; either version 2, or 1121308Sache (at your option) any later version. 1221308Sache 1321308Sache The GNU Readline Library is distributed in the hope that it will be 1421308Sache useful, but WITHOUT ANY WARRANTY; without even the implied warranty 1521308Sache of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1621308Sache GNU General Public License for more details. 1721308Sache 1821308Sache The GNU General Public License is often shipped with GNU software, and 1921308Sache is generally kept in a file called COPYING or LICENSE. If you do not 2021308Sache have a copy of the license, write to the Free Software Foundation, 2158310Sache 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 2221308Sache#define READLINE_LIBRARY 2321308Sache 2421308Sache#if defined (HAVE_CONFIG_H) 2521308Sache# include <config.h> 2621308Sache#endif 2721308Sache 2821308Sache#include <sys/types.h> 2921308Sache#include <fcntl.h> 3021308Sache#if defined (HAVE_SYS_FILE_H) 3121308Sache# include <sys/file.h> 3221308Sache#endif /* HAVE_SYS_FILE_H */ 3321308Sache 3421308Sache#if defined (HAVE_UNISTD_H) 3521308Sache# include <unistd.h> 3621308Sache#endif /* HAVE_UNISTD_H */ 3721308Sache 3821308Sache#if defined (HAVE_STDLIB_H) 3921308Sache# include <stdlib.h> 4021308Sache#else 4121308Sache# include "ansi_stdlib.h" 4221308Sache#endif /* HAVE_STDLIB_H */ 4321308Sache 4421308Sache#if defined (HAVE_SELECT) 4521308Sache# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) 4621308Sache# include <sys/time.h> 4721308Sache# endif 4821308Sache#endif /* HAVE_SELECT */ 4921308Sache#if defined (HAVE_SYS_SELECT_H) 5021308Sache# include <sys/select.h> 5121308Sache#endif 5221308Sache 5321308Sache#if defined (FIONREAD_IN_SYS_IOCTL) 5421308Sache# include <sys/ioctl.h> 5521308Sache#endif 5621308Sache 5721308Sache#include <stdio.h> 5821308Sache#include <errno.h> 5921308Sache 6021308Sache#if !defined (errno) 6121308Sacheextern int errno; 6221308Sache#endif /* !errno */ 6321308Sache 6421308Sache/* System-specific feature definitions and include files. */ 6521308Sache#include "rldefs.h" 6621308Sache 6721308Sache/* Some standard library routines. */ 6821308Sache#include "readline.h" 6921308Sache 7058310Sache#include "rlprivate.h" 7158310Sache#include "rlshell.h" 7258310Sache#include "xmalloc.h" 7358310Sache 7421308Sache/* What kind of non-blocking I/O do we have? */ 7521308Sache#if !defined (O_NDELAY) && defined (O_NONBLOCK) 7621308Sache# define O_NDELAY O_NONBLOCK /* Posix style */ 7721308Sache#endif 7821308Sache 7921308Sache/* Non-null means it is a pointer to a function to run while waiting for 8021308Sache character input. */ 8175406Sacherl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; 8221308Sache 8375406Sacherl_getc_func_t *rl_getc_function = rl_getc; 8421308Sache 8575406Sachestatic int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */ 8675406Sache 8721308Sache/* **************************************************************** */ 8821308Sache/* */ 8921308Sache/* Character Input Buffering */ 9021308Sache/* */ 9121308Sache/* **************************************************************** */ 9221308Sache 9321308Sachestatic int pop_index, push_index; 9421308Sachestatic unsigned char ibuffer[512]; 9521308Sachestatic int ibuffer_len = sizeof (ibuffer) - 1; 9621308Sache 9721308Sache#define any_typein (push_index != pop_index) 9821308Sache 9921308Sacheint 10021308Sache_rl_any_typein () 10121308Sache{ 10221308Sache return any_typein; 10321308Sache} 10421308Sache 10547558Sache/* Return the amount of space available in the buffer for stuffing 10647558Sache characters. */ 10721308Sachestatic int 10821308Sacheibuffer_space () 10921308Sache{ 11021308Sache if (pop_index > push_index) 11147558Sache return (pop_index - push_index - 1); 11221308Sache else 11321308Sache return (ibuffer_len - (push_index - pop_index)); 11421308Sache} 11521308Sache 11621308Sache/* Get a key from the buffer of characters to be read. 11721308Sache Return the key in KEY. 11821308Sache Result is KEY if there was a key, or 0 if there wasn't. */ 11921308Sachestatic int 12021308Sacherl_get_char (key) 12121308Sache int *key; 12221308Sache{ 12321308Sache if (push_index == pop_index) 12421308Sache return (0); 12521308Sache 12621308Sache *key = ibuffer[pop_index++]; 12721308Sache 12821308Sache if (pop_index >= ibuffer_len) 12921308Sache pop_index = 0; 13021308Sache 13121308Sache return (1); 13221308Sache} 13321308Sache 13421308Sache/* Stuff KEY into the *front* of the input buffer. 13521308Sache Returns non-zero if successful, zero if there is 13621308Sache no space left in the buffer. */ 13721308Sachestatic int 13821308Sacherl_unget_char (key) 13921308Sache int key; 14021308Sache{ 14121308Sache if (ibuffer_space ()) 14221308Sache { 14321308Sache pop_index--; 14421308Sache if (pop_index < 0) 14521308Sache pop_index = ibuffer_len - 1; 14621308Sache ibuffer[pop_index] = key; 14721308Sache return (1); 14821308Sache } 14921308Sache return (0); 15021308Sache} 15121308Sache 15221308Sache/* If a character is available to be read, then read it 15321308Sache and stuff it into IBUFFER. Otherwise, just return. */ 15421308Sachestatic void 15521308Sacherl_gather_tyi () 15621308Sache{ 15721308Sache int tty; 15821308Sache register int tem, result; 15921308Sache int chars_avail; 16021308Sache char input; 16121308Sache#if defined(HAVE_SELECT) 16221308Sache fd_set readfds, exceptfds; 16321308Sache struct timeval timeout; 16421308Sache#endif 16521308Sache 16621308Sache tty = fileno (rl_instream); 16721308Sache 16821308Sache#if defined (HAVE_SELECT) 16921308Sache FD_ZERO (&readfds); 17021308Sache FD_ZERO (&exceptfds); 17121308Sache FD_SET (tty, &readfds); 17221308Sache FD_SET (tty, &exceptfds); 17321308Sache timeout.tv_sec = 0; 17475406Sache timeout.tv_usec = _keyboard_input_timeout; 17521308Sache if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0) 17621308Sache return; /* Nothing to read. */ 17721308Sache#endif 17821308Sache 17921308Sache result = -1; 18021308Sache#if defined (FIONREAD) 18121308Sache result = ioctl (tty, FIONREAD, &chars_avail); 18221308Sache#endif 18321308Sache 18421308Sache#if defined (O_NDELAY) 18521308Sache if (result == -1) 18621308Sache { 18721308Sache tem = fcntl (tty, F_GETFL, 0); 18821308Sache 18921308Sache fcntl (tty, F_SETFL, (tem | O_NDELAY)); 19021308Sache chars_avail = read (tty, &input, 1); 19121308Sache 19221308Sache fcntl (tty, F_SETFL, tem); 19321308Sache if (chars_avail == -1 && errno == EAGAIN) 19421308Sache return; 19521308Sache } 19621308Sache#endif /* O_NDELAY */ 19721308Sache 19821308Sache /* If there's nothing available, don't waste time trying to read 19921308Sache something. */ 20021308Sache if (chars_avail <= 0) 20121308Sache return; 20221308Sache 20321308Sache tem = ibuffer_space (); 20421308Sache 20521308Sache if (chars_avail > tem) 20621308Sache chars_avail = tem; 20721308Sache 20821308Sache /* One cannot read all of the available input. I can only read a single 20921308Sache character at a time, or else programs which require input can be 21021308Sache thwarted. If the buffer is larger than one character, I lose. 21121308Sache Damn! */ 21221308Sache if (tem < ibuffer_len) 21321308Sache chars_avail = 0; 21421308Sache 21521308Sache if (result != -1) 21621308Sache { 21721308Sache while (chars_avail--) 21821308Sache rl_stuff_char ((*rl_getc_function) (rl_instream)); 21921308Sache } 22021308Sache else 22121308Sache { 22221308Sache if (chars_avail) 22321308Sache rl_stuff_char (input); 22421308Sache } 22521308Sache} 22621308Sache 22775406Sacheint 22875406Sacherl_set_keyboard_input_timeout (u) 22975406Sache int u; 23075406Sache{ 23175406Sache int o; 23275406Sache 23375406Sache o = _keyboard_input_timeout; 23475406Sache if (u > 0) 23575406Sache _keyboard_input_timeout = u; 23675406Sache return (o); 23775406Sache} 23875406Sache 23921308Sache/* Is there input available to be read on the readline input file 24021308Sache descriptor? Only works if the system has select(2) or FIONREAD. */ 24121308Sacheint 24221308Sache_rl_input_available () 24321308Sache{ 24421308Sache#if defined(HAVE_SELECT) 24521308Sache fd_set readfds, exceptfds; 24621308Sache struct timeval timeout; 24721308Sache#endif 24821308Sache#if defined(FIONREAD) 24921308Sache int chars_avail; 25021308Sache#endif 25121308Sache int tty; 25221308Sache 25321308Sache tty = fileno (rl_instream); 25421308Sache 25521308Sache#if defined (HAVE_SELECT) 25621308Sache FD_ZERO (&readfds); 25721308Sache FD_ZERO (&exceptfds); 25821308Sache FD_SET (tty, &readfds); 25921308Sache FD_SET (tty, &exceptfds); 26021308Sache timeout.tv_sec = 0; 26175406Sache timeout.tv_usec = _keyboard_input_timeout; 26221308Sache return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0); 26321308Sache#endif 26421308Sache 26521308Sache#if defined (FIONREAD) 26621308Sache if (ioctl (tty, FIONREAD, &chars_avail) == 0) 26721308Sache return (chars_avail); 26821308Sache#endif 26921308Sache 27021308Sache return 0; 27121308Sache} 27221308Sache 27321308Sachevoid 27421308Sache_rl_insert_typein (c) 27521308Sache int c; 27621308Sache{ 27721308Sache int key, t, i; 27821308Sache char *string; 27921308Sache 28021308Sache i = key = 0; 28121308Sache string = xmalloc (ibuffer_len + 1); 28221308Sache string[i++] = (char) c; 28321308Sache 28421308Sache while ((t = rl_get_char (&key)) && 28521308Sache _rl_keymap[key].type == ISFUNC && 28621308Sache _rl_keymap[key].function == rl_insert) 28721308Sache string[i++] = key; 28821308Sache 28921308Sache if (t) 29021308Sache rl_unget_char (key); 29121308Sache 29221308Sache string[i] = '\0'; 29321308Sache rl_insert_text (string); 29421308Sache free (string); 29521308Sache} 29621308Sache 29747558Sache/* Add KEY to the buffer of characters to be read. Returns 1 if the 29847558Sache character was stuffed correctly; 0 otherwise. */ 29947558Sacheint 30047558Sacherl_stuff_char (key) 30147558Sache int key; 30247558Sache{ 30347558Sache if (ibuffer_space () == 0) 30447558Sache return 0; 30547558Sache 30647558Sache if (key == EOF) 30747558Sache { 30847558Sache key = NEWLINE; 30947558Sache rl_pending_input = EOF; 31075406Sache RL_SETSTATE (RL_STATE_INPUTPENDING); 31147558Sache } 31247558Sache ibuffer[push_index++] = key; 31347558Sache if (push_index >= ibuffer_len) 31447558Sache push_index = 0; 31547558Sache 31647558Sache return 1; 31747558Sache} 31847558Sache 31947558Sache/* Make C be the next command to be executed. */ 32047558Sacheint 32147558Sacherl_execute_next (c) 32247558Sache int c; 32347558Sache{ 32447558Sache rl_pending_input = c; 32575406Sache RL_SETSTATE (RL_STATE_INPUTPENDING); 32647558Sache return 0; 32747558Sache} 32847558Sache 32975406Sache/* Clear any pending input pushed with rl_execute_next() */ 33075406Sacheint 33175406Sacherl_clear_pending_input () 33275406Sache{ 33375406Sache rl_pending_input = 0; 33475406Sache RL_UNSETSTATE (RL_STATE_INPUTPENDING); 33575406Sache return 0; 33675406Sache} 33775406Sache 33821308Sache/* **************************************************************** */ 33921308Sache/* */ 34021308Sache/* Character Input */ 34121308Sache/* */ 34221308Sache/* **************************************************************** */ 34321308Sache 34421308Sache/* Read a key, including pending input. */ 34521308Sacheint 34621308Sacherl_read_key () 34721308Sache{ 34821308Sache int c; 34921308Sache 35021308Sache rl_key_sequence_length++; 35121308Sache 35221308Sache if (rl_pending_input) 35321308Sache { 35421308Sache c = rl_pending_input; 35575406Sache rl_clear_pending_input (); 35621308Sache } 35721308Sache else 35821308Sache { 35921308Sache /* If input is coming from a macro, then use that. */ 36021308Sache if (c = _rl_next_macro_key ()) 36121308Sache return (c); 36221308Sache 36321308Sache /* If the user has an event function, then call it periodically. */ 36421308Sache if (rl_event_hook) 36521308Sache { 36621308Sache while (rl_event_hook && rl_get_char (&c) == 0) 36721308Sache { 36821308Sache (*rl_event_hook) (); 36975406Sache if (rl_done) /* XXX - experimental */ 37075406Sache return ('\n'); 37121308Sache rl_gather_tyi (); 37221308Sache } 37321308Sache } 37421308Sache else 37521308Sache { 37621308Sache if (rl_get_char (&c) == 0) 37721308Sache c = (*rl_getc_function) (rl_instream); 37821308Sache } 37921308Sache } 38021308Sache 38121308Sache return (c); 38221308Sache} 38321308Sache 38421308Sacheint 38521308Sacherl_getc (stream) 38621308Sache FILE *stream; 38721308Sache{ 38858310Sache int result; 38921308Sache unsigned char c; 39021308Sache 39121308Sache while (1) 39221308Sache { 39321308Sache result = read (fileno (stream), &c, sizeof (unsigned char)); 39421308Sache 39521308Sache if (result == sizeof (unsigned char)) 39621308Sache return (c); 39721308Sache 39821308Sache /* If zero characters are returned, then the file that we are 39921308Sache reading from is empty! Return EOF in that case. */ 40021308Sache if (result == 0) 40121308Sache return (EOF); 40221308Sache 40347558Sache#if defined (__BEOS__) 40447558Sache if (errno == EINTR) 40547558Sache continue; 40647558Sache#endif 40747558Sache 40821308Sache#if defined (EWOULDBLOCK) 40958310Sache# define X_EWOULDBLOCK EWOULDBLOCK 41058310Sache#else 41158310Sache# define X_EWOULDBLOCK -99 41258310Sache#endif 41358310Sache 41458310Sache#if defined (EAGAIN) 41558310Sache# define X_EAGAIN EAGAIN 41658310Sache#else 41758310Sache# define X_EAGAIN -99 41858310Sache#endif 41958310Sache 42058310Sache if (errno == X_EWOULDBLOCK || errno == X_EAGAIN) 42121308Sache { 42275406Sache if (sh_unset_nodelay_mode (fileno (stream)) < 0) 42321308Sache return (EOF); 42421308Sache continue; 42521308Sache } 42621308Sache 42758310Sache#undef X_EWOULDBLOCK 42858310Sache#undef X_EAGAIN 42921308Sache 43021308Sache /* If the error that we received was SIGINT, then try again, 43121308Sache this is simply an interrupted system call to read (). 43221308Sache Otherwise, some error ocurred, also signifying EOF. */ 43321308Sache if (errno != EINTR) 43421308Sache return (EOF); 43521308Sache } 43621308Sache} 437