1 /* input.c -- character input functions for readline. */ 2 3 /* Copyright (C) 1994 Free Software Foundation, Inc. 4 5 This file is part of the GNU Readline Library, a library for 6 reading lines of text with interactive input and history editing. 7 8 The GNU Readline Library is free software; you can redistribute it 9 and/or modify it under the terms of the GNU General Public License 10 as published by the Free Software Foundation; either version 2, or 11 (at your option) any later version. 12 13 The GNU Readline Library is distributed in the hope that it will be 14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 The GNU General Public License is often shipped with GNU software, and 19 is generally kept in a file called COPYING or LICENSE. If you do not 20 have a copy of the license, write to the Free Software Foundation, 21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 22 #define READLINE_LIBRARY 23 24 #if defined (HAVE_CONFIG_H) 25 # include <config.h> 26 #endif 27 28 #include <sys/types.h> 29 #include <fcntl.h> 30 #if defined (HAVE_SYS_FILE_H) 31 # include <sys/file.h> 32 #endif /* HAVE_SYS_FILE_H */ 33 34 #if defined (HAVE_UNISTD_H) 35 # include <unistd.h> 36 #endif /* HAVE_UNISTD_H */ 37 38 #if defined (HAVE_STDLIB_H) 39 # include <stdlib.h> 40 #else 41 # include "ansi_stdlib.h" 42 #endif /* HAVE_STDLIB_H */ 43 44 #if defined (HAVE_SELECT) 45 # if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) 46 # include <sys/time.h> 47 # endif 48 #endif /* HAVE_SELECT */ 49 #if defined (HAVE_SYS_SELECT_H) 50 # include <sys/select.h> 51 #endif 52 53 #if defined (FIONREAD_IN_SYS_IOCTL) 54 # include <sys/ioctl.h> 55 #endif 56 57 #include <stdio.h> 58 #include <errno.h> 59 60 #if !defined (errno) 61 extern int errno; 62 #endif /* !errno */ 63 64 /* System-specific feature definitions and include files. */ 65 #include "rldefs.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 Function *rl_event_hook = (Function *)NULL; 82 83 Function *rl_getc_function = rl_getc; 84 85 /* **************************************************************** */ 86 /* */ 87 /* Character Input Buffering */ 88 /* */ 89 /* **************************************************************** */ 90 91 static int pop_index, push_index; 92 static unsigned char ibuffer[512]; 93 static int ibuffer_len = sizeof (ibuffer) - 1; 94 95 #define any_typein (push_index != pop_index) 96 97 int 98 _rl_any_typein () 99 { 100 return any_typein; 101 } 102 103 /* Return the amount of space available in the buffer for stuffing 104 characters. */ 105 static int 106 ibuffer_space () 107 { 108 if (pop_index > push_index) 109 return (pop_index - push_index - 1); 110 else 111 return (ibuffer_len - (push_index - pop_index)); 112 } 113 114 /* Get a key from the buffer of characters to be read. 115 Return the key in KEY. 116 Result is KEY if there was a key, or 0 if there wasn't. */ 117 static int 118 rl_get_char (key) 119 int *key; 120 { 121 if (push_index == pop_index) 122 return (0); 123 124 *key = ibuffer[pop_index++]; 125 126 if (pop_index >= ibuffer_len) 127 pop_index = 0; 128 129 return (1); 130 } 131 132 /* Stuff KEY into the *front* of the input buffer. 133 Returns non-zero if successful, zero if there is 134 no space left in the buffer. */ 135 static int 136 rl_unget_char (key) 137 int key; 138 { 139 if (ibuffer_space ()) 140 { 141 pop_index--; 142 if (pop_index < 0) 143 pop_index = ibuffer_len - 1; 144 ibuffer[pop_index] = key; 145 return (1); 146 } 147 return (0); 148 } 149 150 /* If a character is available to be read, then read it 151 and stuff it into IBUFFER. Otherwise, just return. */ 152 static void 153 rl_gather_tyi () 154 { 155 int tty; 156 register int tem, result; 157 int chars_avail; 158 char input; 159 #if defined(HAVE_SELECT) 160 fd_set readfds, exceptfds; 161 struct timeval timeout; 162 #endif 163 164 tty = fileno (rl_instream); 165 166 #if defined (HAVE_SELECT) 167 FD_ZERO (&readfds); 168 FD_ZERO (&exceptfds); 169 FD_SET (tty, &readfds); 170 FD_SET (tty, &exceptfds); 171 timeout.tv_sec = 0; 172 timeout.tv_usec = 100000; /* 0.1 seconds */ 173 if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0) 174 return; /* Nothing to read. */ 175 #endif 176 177 result = -1; 178 #if defined (FIONREAD) 179 result = ioctl (tty, FIONREAD, &chars_avail); 180 #endif 181 182 #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. */ 227 int 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 259 void 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. */ 285 int 286 rl_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. */ 305 int 306 rl_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. */ 320 int 321 rl_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 357 int 358 rl_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