]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/readline/input.c
Imported from ../bash-2.05.tar.gz.
[thirdparty/bash.git] / lib / readline / input.c
CommitLineData
ccc6cda3
JA
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,
bb70624e 21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
ccc6cda3
JA
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)
61extern 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
bb70624e
JA
70#include "rlprivate.h"
71#include "rlshell.h"
72#include "xmalloc.h"
73
ccc6cda3
JA
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
ccc6cda3
JA
79/* Non-null means it is a pointer to a function to run while waiting for
80 character input. */
28ef6c31 81rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
ccc6cda3 82
28ef6c31
JA
83rl_getc_func_t *rl_getc_function = rl_getc;
84
85static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */
ccc6cda3
JA
86
87/* **************************************************************** */
88/* */
89/* Character Input Buffering */
90/* */
91/* **************************************************************** */
92
93static int pop_index, push_index;
94static unsigned char ibuffer[512];
95static int ibuffer_len = sizeof (ibuffer) - 1;
96
97#define any_typein (push_index != pop_index)
98
99int
100_rl_any_typein ()
101{
102 return any_typein;
103}
104
b72432fd
JA
105/* Return the amount of space available in the buffer for stuffing
106 characters. */
ccc6cda3
JA
107static int
108ibuffer_space ()
109{
110 if (pop_index > push_index)
b72432fd 111 return (pop_index - push_index - 1);
ccc6cda3
JA
112 else
113 return (ibuffer_len - (push_index - pop_index));
114}
115
116/* Get a key from the buffer of characters to be read.
117 Return the key in KEY.
118 Result is KEY if there was a key, or 0 if there wasn't. */
119static int
120rl_get_char (key)
121 int *key;
122{
123 if (push_index == pop_index)
124 return (0);
125
126 *key = ibuffer[pop_index++];
127
128 if (pop_index >= ibuffer_len)
129 pop_index = 0;
130
131 return (1);
132}
133
134/* Stuff KEY into the *front* of the input buffer.
135 Returns non-zero if successful, zero if there is
136 no space left in the buffer. */
137static int
138rl_unget_char (key)
139 int key;
140{
141 if (ibuffer_space ())
142 {
143 pop_index--;
144 if (pop_index < 0)
145 pop_index = ibuffer_len - 1;
146 ibuffer[pop_index] = key;
147 return (1);
148 }
149 return (0);
150}
151
152/* If a character is available to be read, then read it
153 and stuff it into IBUFFER. Otherwise, just return. */
154static void
155rl_gather_tyi ()
156{
ccc6cda3
JA
157 int tty;
158 register int tem, result;
159 int chars_avail;
160 char input;
161#if defined(HAVE_SELECT)
162 fd_set readfds, exceptfds;
163 struct timeval timeout;
164#endif
165
166 tty = fileno (rl_instream);
167
168#if defined (HAVE_SELECT)
169 FD_ZERO (&readfds);
170 FD_ZERO (&exceptfds);
171 FD_SET (tty, &readfds);
172 FD_SET (tty, &exceptfds);
173 timeout.tv_sec = 0;
28ef6c31 174 timeout.tv_usec = _keyboard_input_timeout;
ccc6cda3
JA
175 if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0)
176 return; /* Nothing to read. */
177#endif
178
179 result = -1;
180#if defined (FIONREAD)
181 result = ioctl (tty, FIONREAD, &chars_avail);
182#endif
183
184#if defined (O_NDELAY)
185 if (result == -1)
186 {
187 tem = fcntl (tty, F_GETFL, 0);
188
189 fcntl (tty, F_SETFL, (tem | O_NDELAY));
190 chars_avail = read (tty, &input, 1);
191
192 fcntl (tty, F_SETFL, tem);
193 if (chars_avail == -1 && errno == EAGAIN)
194 return;
195 }
196#endif /* O_NDELAY */
197
198 /* If there's nothing available, don't waste time trying to read
199 something. */
200 if (chars_avail <= 0)
201 return;
202
203 tem = ibuffer_space ();
204
205 if (chars_avail > tem)
206 chars_avail = tem;
207
208 /* One cannot read all of the available input. I can only read a single
209 character at a time, or else programs which require input can be
210 thwarted. If the buffer is larger than one character, I lose.
211 Damn! */
212 if (tem < ibuffer_len)
213 chars_avail = 0;
214
215 if (result != -1)
216 {
217 while (chars_avail--)
218 rl_stuff_char ((*rl_getc_function) (rl_instream));
219 }
220 else
221 {
222 if (chars_avail)
223 rl_stuff_char (input);
224 }
ccc6cda3
JA
225}
226
28ef6c31
JA
227int
228rl_set_keyboard_input_timeout (u)
229 int u;
230{
231 int o;
232
233 o = _keyboard_input_timeout;
234 if (u > 0)
235 _keyboard_input_timeout = u;
236 return (o);
237}
238
ccc6cda3
JA
239/* Is there input available to be read on the readline input file
240 descriptor? Only works if the system has select(2) or FIONREAD. */
241int
242_rl_input_available ()
243{
244#if defined(HAVE_SELECT)
245 fd_set readfds, exceptfds;
246 struct timeval timeout;
247#endif
248#if defined(FIONREAD)
249 int chars_avail;
250#endif
251 int tty;
252
253 tty = fileno (rl_instream);
254
255#if defined (HAVE_SELECT)
256 FD_ZERO (&readfds);
257 FD_ZERO (&exceptfds);
258 FD_SET (tty, &readfds);
259 FD_SET (tty, &exceptfds);
260 timeout.tv_sec = 0;
28ef6c31 261 timeout.tv_usec = _keyboard_input_timeout;
ccc6cda3
JA
262 return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
263#endif
264
265#if defined (FIONREAD)
266 if (ioctl (tty, FIONREAD, &chars_avail) == 0)
267 return (chars_avail);
268#endif
269
270 return 0;
271}
272
273void
274_rl_insert_typein (c)
275 int c;
276{
277 int key, t, i;
278 char *string;
279
280 i = key = 0;
281 string = xmalloc (ibuffer_len + 1);
282 string[i++] = (char) c;
283
284 while ((t = rl_get_char (&key)) &&
285 _rl_keymap[key].type == ISFUNC &&
286 _rl_keymap[key].function == rl_insert)
287 string[i++] = key;
288
289 if (t)
290 rl_unget_char (key);
291
292 string[i] = '\0';
293 rl_insert_text (string);
294 free (string);
295}
296
b72432fd
JA
297/* Add KEY to the buffer of characters to be read. Returns 1 if the
298 character was stuffed correctly; 0 otherwise. */
299int
300rl_stuff_char (key)
301 int key;
302{
303 if (ibuffer_space () == 0)
304 return 0;
305
306 if (key == EOF)
307 {
308 key = NEWLINE;
309 rl_pending_input = EOF;
28ef6c31 310 RL_SETSTATE (RL_STATE_INPUTPENDING);
b72432fd
JA
311 }
312 ibuffer[push_index++] = key;
313 if (push_index >= ibuffer_len)
314 push_index = 0;
315
316 return 1;
317}
318
319/* Make C be the next command to be executed. */
320int
321rl_execute_next (c)
322 int c;
323{
324 rl_pending_input = c;
28ef6c31
JA
325 RL_SETSTATE (RL_STATE_INPUTPENDING);
326 return 0;
327}
328
329/* Clear any pending input pushed with rl_execute_next() */
330int
331rl_clear_pending_input ()
332{
333 rl_pending_input = 0;
334 RL_UNSETSTATE (RL_STATE_INPUTPENDING);
b72432fd
JA
335 return 0;
336}
337
ccc6cda3
JA
338/* **************************************************************** */
339/* */
340/* Character Input */
341/* */
342/* **************************************************************** */
343
344/* Read a key, including pending input. */
345int
346rl_read_key ()
347{
348 int c;
349
350 rl_key_sequence_length++;
351
352 if (rl_pending_input)
353 {
354 c = rl_pending_input;
28ef6c31 355 rl_clear_pending_input ();
ccc6cda3
JA
356 }
357 else
358 {
359 /* If input is coming from a macro, then use that. */
360 if (c = _rl_next_macro_key ())
361 return (c);
362
363 /* If the user has an event function, then call it periodically. */
364 if (rl_event_hook)
365 {
366 while (rl_event_hook && rl_get_char (&c) == 0)
367 {
368 (*rl_event_hook) ();
28ef6c31
JA
369 if (rl_done) /* XXX - experimental */
370 return ('\n');
ccc6cda3
JA
371 rl_gather_tyi ();
372 }
373 }
374 else
375 {
376 if (rl_get_char (&c) == 0)
377 c = (*rl_getc_function) (rl_instream);
378 }
379 }
380
381 return (c);
382}
383
384int
385rl_getc (stream)
386 FILE *stream;
387{
bb70624e 388 int result;
ccc6cda3
JA
389 unsigned char c;
390
ccc6cda3
JA
391 while (1)
392 {
393 result = read (fileno (stream), &c, sizeof (unsigned char));
394
395 if (result == sizeof (unsigned char))
396 return (c);
397
398 /* If zero characters are returned, then the file that we are
399 reading from is empty! Return EOF in that case. */
400 if (result == 0)
401 return (EOF);
402
b72432fd
JA
403#if defined (__BEOS__)
404 if (errno == EINTR)
405 continue;
406#endif
407
ccc6cda3 408#if defined (EWOULDBLOCK)
bb70624e
JA
409# define X_EWOULDBLOCK EWOULDBLOCK
410#else
411# define X_EWOULDBLOCK -99
412#endif
413
414#if defined (EAGAIN)
415# define X_EAGAIN EAGAIN
416#else
417# define X_EAGAIN -99
418#endif
419
420 if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)
ccc6cda3 421 {
28ef6c31 422 if (sh_unset_nodelay_mode (fileno (stream)) < 0)
ccc6cda3 423 return (EOF);
ccc6cda3
JA
424 continue;
425 }
ccc6cda3 426
bb70624e
JA
427#undef X_EWOULDBLOCK
428#undef X_EAGAIN
ccc6cda3 429
ccc6cda3
JA
430 /* If the error that we received was SIGINT, then try again,
431 this is simply an interrupted system call to read ().
432 Otherwise, some error ocurred, also signifying EOF. */
433 if (errno != EINTR)
434 return (EOF);
ccc6cda3
JA
435 }
436}