]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/readline/input.c
Imported from ../bash-2.04.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. */
81Function *rl_event_hook = (Function *)NULL;
82
83Function *rl_getc_function = rl_getc;
84
85/* **************************************************************** */
86/* */
87/* Character Input Buffering */
88/* */
89/* **************************************************************** */
90
91static int pop_index, push_index;
92static unsigned char ibuffer[512];
93static int ibuffer_len = sizeof (ibuffer) - 1;
94
95#define any_typein (push_index != pop_index)
96
97int
98_rl_any_typein ()
99{
100 return any_typein;
101}
102
b72432fd
JA
103/* Return the amount of space available in the buffer for stuffing
104 characters. */
ccc6cda3
JA
105static int
106ibuffer_space ()
107{
108 if (pop_index > push_index)
b72432fd 109 return (pop_index - push_index - 1);
ccc6cda3
JA
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. */
117static int
118rl_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. */
135static int
136rl_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. */
152static void
153rl_gather_tyi ()
154{
ccc6cda3
JA
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 }
ccc6cda3
JA
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
b72432fd
JA
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
ccc6cda3
JA
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{
bb70624e 361 int result;
ccc6cda3
JA
362 unsigned char c;
363
ccc6cda3
JA
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
b72432fd
JA
376#if defined (__BEOS__)
377 if (errno == EINTR)
378 continue;
379#endif
380
ccc6cda3 381#if defined (EWOULDBLOCK)
bb70624e
JA
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)
ccc6cda3 394 {
bb70624e 395 if (unset_nodelay_mode (fileno (stream)) < 0)
ccc6cda3 396 return (EOF);
ccc6cda3
JA
397 continue;
398 }
ccc6cda3 399
bb70624e
JA
400#undef X_EWOULDBLOCK
401#undef X_EAGAIN
ccc6cda3 402
ccc6cda3
JA
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);
ccc6cda3
JA
408 }
409}