input.c revision 58310
1279264Sdelphij/* input.c -- character input functions for readline. */ 2110010Smarkm 3110010Smarkm/* Copyright (C) 1994 Free Software Foundation, Inc. 4160819Ssimon 5110010Smarkm This file is part of the GNU Readline Library, a library for 6110010Smarkm reading lines of text with interactive input and history editing. 7110010Smarkm 8110010Smarkm The GNU Readline Library is free software; you can redistribute it 9110010Smarkm and/or modify it under the terms of the GNU General Public License 10110010Smarkm as published by the Free Software Foundation; either version 2, or 11110010Smarkm (at your option) any later version. 12110010Smarkm 13110010Smarkm The GNU Readline Library is distributed in the hope that it will be 14110010Smarkm useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15110010Smarkm of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16110010Smarkm GNU General Public License for more details. 17110010Smarkm 18110010Smarkm The GNU General Public License is often shipped with GNU software, and 19110010Smarkm is generally kept in a file called COPYING or LICENSE. If you do not 20215698Ssimon have a copy of the license, write to the Free Software Foundation, 21215698Ssimon 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 22215698Ssimon#define READLINE_LIBRARY 23215698Ssimon 24215698Ssimon#if defined (HAVE_CONFIG_H) 25110010Smarkm# include <config.h> 26110010Smarkm#endif 27110010Smarkm 28110010Smarkm#include <sys/types.h> 29110010Smarkm#include <fcntl.h> 30110010Smarkm#if defined (HAVE_SYS_FILE_H) 31110010Smarkm# include <sys/file.h> 32110010Smarkm#endif /* HAVE_SYS_FILE_H */ 33110010Smarkm 34110010Smarkm#if defined (HAVE_UNISTD_H) 35110010Smarkm# include <unistd.h> 36110010Smarkm#endif /* HAVE_UNISTD_H */ 37110010Smarkm 38110010Smarkm#if defined (HAVE_STDLIB_H) 39110010Smarkm# include <stdlib.h> 40110010Smarkm#else 41279264Sdelphij# include "ansi_stdlib.h" 42279264Sdelphij#endif /* HAVE_STDLIB_H */ 43110010Smarkm 44110010Smarkm#if defined (HAVE_SELECT) 45215698Ssimon# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) 46215698Ssimon# include <sys/time.h> 47215698Ssimon# endif 48215698Ssimon#endif /* HAVE_SELECT */ 49160819Ssimon#if defined (HAVE_SYS_SELECT_H) 50215698Ssimon# include <sys/select.h> 51160819Ssimon#endif 52160819Ssimon 53279264Sdelphij#if defined (FIONREAD_IN_SYS_IOCTL) 54279264Sdelphij# include <sys/ioctl.h> 55279264Sdelphij#endif 56110010Smarkm 57279264Sdelphij#include <stdio.h> 58279264Sdelphij#include <errno.h> 59279264Sdelphij 60279264Sdelphij#if !defined (errno) 61279264Sdelphijextern int errno; 62279264Sdelphij#endif /* !errno */ 63215698Ssimon 64279264Sdelphij/* System-specific feature definitions and include files. */ 65279264Sdelphij#include "rldefs.h" 66279264Sdelphij 67279264Sdelphij/* Some standard library routines. */ 68279264Sdelphij#include "readline.h" 69215698Ssimon 70279264Sdelphij#include "rlprivate.h" 71110010Smarkm#include "rlshell.h" 72110010Smarkm#include "xmalloc.h" 73110010Smarkm 74110010Smarkm/* What kind of non-blocking I/O do we have? */ 75110010Smarkm#if !defined (O_NDELAY) && defined (O_NONBLOCK) 76110010Smarkm# define O_NDELAY O_NONBLOCK /* Posix style */ 77110010Smarkm#endif 78110010Smarkm 79110010Smarkm/* Non-null means it is a pointer to a function to run while waiting for 80110010Smarkm character input. */ 81110010SmarkmFunction *rl_event_hook = (Function *)NULL; 82110010Smarkm 83110010SmarkmFunction *rl_getc_function = rl_getc; 84110010Smarkm 85110010Smarkm/* **************************************************************** */ 86110010Smarkm/* */ 87110010Smarkm/* Character Input Buffering */ 88110010Smarkm/* */ 89110010Smarkm/* **************************************************************** */ 90110010Smarkm 91110010Smarkmstatic int pop_index, push_index; 92110010Smarkmstatic unsigned char ibuffer[512]; 93110010Smarkmstatic int ibuffer_len = sizeof (ibuffer) - 1; 94110010Smarkm 95110010Smarkm#define any_typein (push_index != pop_index) 96110010Smarkm 97110010Smarkmint 98110010Smarkm_rl_any_typein () 99110010Smarkm{ 100110010Smarkm return any_typein; 101110010Smarkm} 102110010Smarkm 103110010Smarkm/* Return the amount of space available in the buffer for stuffing 104110010Smarkm characters. */ 105110010Smarkmstatic int 106110010Smarkmibuffer_space () 107110010Smarkm{ 108110010Smarkm if (pop_index > push_index) 109110010Smarkm return (pop_index - push_index - 1); 110110010Smarkm else 111110010Smarkm return (ibuffer_len - (push_index - pop_index)); 112110010Smarkm} 113110010Smarkm 114110010Smarkm/* Get a key from the buffer of characters to be read. 115110010Smarkm Return the key in KEY. 116110010Smarkm Result is KEY if there was a key, or 0 if there wasn't. */ 117110010Smarkmstatic int 118110010Smarkmrl_get_char (key) 119110010Smarkm int *key; 120110010Smarkm{ 121110010Smarkm if (push_index == pop_index) 122110010Smarkm return (0); 123110010Smarkm 124110010Smarkm *key = ibuffer[pop_index++]; 125110010Smarkm 126110010Smarkm if (pop_index >= ibuffer_len) 127110010Smarkm pop_index = 0; 128110010Smarkm 129110010Smarkm return (1); 130110010Smarkm} 131110010Smarkm 132110010Smarkm/* Stuff KEY into the *front* of the input buffer. 133160819Ssimon Returns non-zero if successful, zero if there is 134110010Smarkm no space left in the buffer. */ 135110010Smarkmstatic int 136279264Sdelphijrl_unget_char (key) 137215698Ssimon int key; 138215698Ssimon{ 139215698Ssimon if (ibuffer_space ()) 140215698Ssimon { 141110010Smarkm pop_index--; 142110010Smarkm if (pop_index < 0) 143110010Smarkm pop_index = ibuffer_len - 1; 144110010Smarkm ibuffer[pop_index] = key; 145110010Smarkm return (1); 146110010Smarkm } 147215698Ssimon return (0); 148160819Ssimon} 149110010Smarkm 150110010Smarkm/* If a character is available to be read, then read it 151110010Smarkm and stuff it into IBUFFER. Otherwise, just return. */ 152110010Smarkmstatic void 153110010Smarkmrl_gather_tyi () 154110010Smarkm{ 155110010Smarkm int tty; 156110010Smarkm register int tem, result; 157110010Smarkm int chars_avail; 158110010Smarkm char input; 159110010Smarkm#if defined(HAVE_SELECT) 160110010Smarkm fd_set readfds, exceptfds; 161110010Smarkm struct timeval timeout; 162110010Smarkm#endif 163110010Smarkm 164110010Smarkm tty = fileno (rl_instream); 165110010Smarkm 166110010Smarkm#if defined (HAVE_SELECT) 167110010Smarkm FD_ZERO (&readfds); 168160819Ssimon FD_ZERO (&exceptfds); 169110010Smarkm FD_SET (tty, &readfds); 170110010Smarkm FD_SET (tty, &exceptfds); 171110010Smarkm timeout.tv_sec = 0; 172160819Ssimon timeout.tv_usec = 100000; /* 0.1 seconds */ 173110010Smarkm if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0) 174110010Smarkm return; /* Nothing to read. */ 175160819Ssimon#endif 176110010Smarkm 177160819Ssimon result = -1; 178110010Smarkm#if defined (FIONREAD) 179110010Smarkm result = ioctl (tty, FIONREAD, &chars_avail); 180160819Ssimon#endif 181160819Ssimon 182160819Ssimon#if defined (O_NDELAY) 183 if (result == -1) 184 { 185 tem = fcntl (tty, F_GETFL, 0); 186 187 fcntl (tty, F_SETFL, (tem | O_NDELAY)); 188 chars_avail = read (tty, &input, 1); 189 190 fcntl (tty, F_SETFL, tem); 191 if (chars_avail == -1 && errno == EAGAIN) 192 return; 193 } 194#endif /* O_NDELAY */ 195 196 /* If there's nothing available, don't waste time trying to read 197 something. */ 198 if (chars_avail <= 0) 199 return; 200 201 tem = ibuffer_space (); 202 203 if (chars_avail > tem) 204 chars_avail = tem; 205 206 /* One cannot read all of the available input. I can only read a single 207 character at a time, or else programs which require input can be 208 thwarted. If the buffer is larger than one character, I lose. 209 Damn! */ 210 if (tem < ibuffer_len) 211 chars_avail = 0; 212 213 if (result != -1) 214 { 215 while (chars_avail--) 216 rl_stuff_char ((*rl_getc_function) (rl_instream)); 217 } 218 else 219 { 220 if (chars_avail) 221 rl_stuff_char (input); 222 } 223} 224 225/* Is there input available to be read on the readline input file 226 descriptor? Only works if the system has select(2) or FIONREAD. */ 227int 228_rl_input_available () 229{ 230#if defined(HAVE_SELECT) 231 fd_set readfds, exceptfds; 232 struct timeval timeout; 233#endif 234#if defined(FIONREAD) 235 int chars_avail; 236#endif 237 int tty; 238 239 tty = fileno (rl_instream); 240 241#if defined (HAVE_SELECT) 242 FD_ZERO (&readfds); 243 FD_ZERO (&exceptfds); 244 FD_SET (tty, &readfds); 245 FD_SET (tty, &exceptfds); 246 timeout.tv_sec = 0; 247 timeout.tv_usec = 100000; /* 0.1 seconds */ 248 return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0); 249#endif 250 251#if defined (FIONREAD) 252 if (ioctl (tty, FIONREAD, &chars_avail) == 0) 253 return (chars_avail); 254#endif 255 256 return 0; 257} 258 259void 260_rl_insert_typein (c) 261 int c; 262{ 263 int key, t, i; 264 char *string; 265 266 i = key = 0; 267 string = xmalloc (ibuffer_len + 1); 268 string[i++] = (char) c; 269 270 while ((t = rl_get_char (&key)) && 271 _rl_keymap[key].type == ISFUNC && 272 _rl_keymap[key].function == rl_insert) 273 string[i++] = key; 274 275 if (t) 276 rl_unget_char (key); 277 278 string[i] = '\0'; 279 rl_insert_text (string); 280 free (string); 281} 282 283/* Add KEY to the buffer of characters to be read. Returns 1 if the 284 character was stuffed correctly; 0 otherwise. */ 285int 286rl_stuff_char (key) 287 int key; 288{ 289 if (ibuffer_space () == 0) 290 return 0; 291 292 if (key == EOF) 293 { 294 key = NEWLINE; 295 rl_pending_input = EOF; 296 } 297 ibuffer[push_index++] = key; 298 if (push_index >= ibuffer_len) 299 push_index = 0; 300 301 return 1; 302} 303 304/* Make C be the next command to be executed. */ 305int 306rl_execute_next (c) 307 int c; 308{ 309 rl_pending_input = c; 310 return 0; 311} 312 313/* **************************************************************** */ 314/* */ 315/* Character Input */ 316/* */ 317/* **************************************************************** */ 318 319/* Read a key, including pending input. */ 320int 321rl_read_key () 322{ 323 int c; 324 325 rl_key_sequence_length++; 326 327 if (rl_pending_input) 328 { 329 c = rl_pending_input; 330 rl_pending_input = 0; 331 } 332 else 333 { 334 /* If input is coming from a macro, then use that. */ 335 if (c = _rl_next_macro_key ()) 336 return (c); 337 338 /* If the user has an event function, then call it periodically. */ 339 if (rl_event_hook) 340 { 341 while (rl_event_hook && rl_get_char (&c) == 0) 342 { 343 (*rl_event_hook) (); 344 rl_gather_tyi (); 345 } 346 } 347 else 348 { 349 if (rl_get_char (&c) == 0) 350 c = (*rl_getc_function) (rl_instream); 351 } 352 } 353 354 return (c); 355} 356 357int 358rl_getc (stream) 359 FILE *stream; 360{ 361 int result; 362 unsigned char c; 363 364 while (1) 365 { 366 result = read (fileno (stream), &c, sizeof (unsigned char)); 367 368 if (result == sizeof (unsigned char)) 369 return (c); 370 371 /* If zero characters are returned, then the file that we are 372 reading from is empty! Return EOF in that case. */ 373 if (result == 0) 374 return (EOF); 375 376#if defined (__BEOS__) 377 if (errno == EINTR) 378 continue; 379#endif 380 381#if defined (EWOULDBLOCK) 382# define X_EWOULDBLOCK EWOULDBLOCK 383#else 384# define X_EWOULDBLOCK -99 385#endif 386 387#if defined (EAGAIN) 388# define X_EAGAIN EAGAIN 389#else 390# define X_EAGAIN -99 391#endif 392 393 if (errno == X_EWOULDBLOCK || errno == X_EAGAIN) 394 { 395 if (unset_nodelay_mode (fileno (stream)) < 0) 396 return (EOF); 397 continue; 398 } 399 400#undef X_EWOULDBLOCK 401#undef X_EAGAIN 402 403 /* If the error that we received was SIGINT, then try again, 404 this is simply an interrupted system call to read (). 405 Otherwise, some error ocurred, also signifying EOF. */ 406 if (errno != EINTR) 407 return (EOF); 408 } 409} 410