2996
|
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, |
3284
|
21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ |
2996
|
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 |
3779
|
70 #include "rlprivate.h" |
|
71 #include "rlshell.h" |
|
72 #include "xmalloc.h" |
|
73 |
2996
|
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. */ |
3779
|
81 rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; |
2996
|
82 |
3779
|
83 rl_getc_func_t *rl_getc_function = rl_getc; |
2996
|
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 |
3779
|
103 /* Return the amount of space available in the buffer for stuffing |
|
104 characters. */ |
2996
|
105 static int |
|
106 ibuffer_space () |
|
107 { |
|
108 if (pop_index > push_index) |
3779
|
109 return (pop_index - push_index - 1); |
2996
|
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 |
3779
|
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 RL_SETSTATE (RL_STATE_INPUTPENDING); |
|
297 } |
|
298 ibuffer[push_index++] = key; |
|
299 if (push_index >= ibuffer_len) |
|
300 push_index = 0; |
|
301 |
|
302 return 1; |
|
303 } |
|
304 |
|
305 /* Make C be the next command to be executed. */ |
|
306 int |
|
307 rl_execute_next (c) |
|
308 int c; |
|
309 { |
|
310 rl_pending_input = c; |
|
311 RL_SETSTATE (RL_STATE_INPUTPENDING); |
|
312 return 0; |
|
313 } |
|
314 |
|
315 /* Clear any pending input pushed with rl_execute_next() */ |
|
316 int |
|
317 rl_clear_pending_input () |
|
318 { |
|
319 rl_pending_input = 0; |
|
320 RL_UNSETSTATE (RL_STATE_INPUTPENDING); |
|
321 return 0; |
|
322 } |
|
323 |
2996
|
324 /* **************************************************************** */ |
|
325 /* */ |
|
326 /* Character Input */ |
|
327 /* */ |
|
328 /* **************************************************************** */ |
|
329 |
|
330 /* Read a key, including pending input. */ |
|
331 int |
|
332 rl_read_key () |
|
333 { |
|
334 int c; |
|
335 |
|
336 rl_key_sequence_length++; |
|
337 |
|
338 if (rl_pending_input) |
|
339 { |
|
340 c = rl_pending_input; |
3779
|
341 rl_clear_pending_input (); |
2996
|
342 } |
|
343 else |
|
344 { |
|
345 /* If input is coming from a macro, then use that. */ |
|
346 if (c = _rl_next_macro_key ()) |
|
347 return (c); |
|
348 |
|
349 /* If the user has an event function, then call it periodically. */ |
|
350 if (rl_event_hook) |
|
351 { |
|
352 while (rl_event_hook && rl_get_char (&c) == 0) |
|
353 { |
|
354 (*rl_event_hook) (); |
|
355 rl_gather_tyi (); |
|
356 } |
|
357 } |
|
358 else |
|
359 { |
|
360 if (rl_get_char (&c) == 0) |
|
361 c = (*rl_getc_function) (rl_instream); |
|
362 } |
|
363 } |
|
364 |
|
365 return (c); |
|
366 } |
|
367 |
|
368 int |
|
369 rl_getc (stream) |
|
370 FILE *stream; |
|
371 { |
3779
|
372 int result; |
2996
|
373 unsigned char c; |
|
374 |
|
375 while (1) |
|
376 { |
|
377 result = read (fileno (stream), &c, sizeof (unsigned char)); |
|
378 |
|
379 if (result == sizeof (unsigned char)) |
|
380 return (c); |
|
381 |
|
382 /* If zero characters are returned, then the file that we are |
|
383 reading from is empty! Return EOF in that case. */ |
|
384 if (result == 0) |
|
385 return (EOF); |
|
386 |
3779
|
387 #if defined (__BEOS__) |
|
388 if (errno == EINTR) |
|
389 continue; |
|
390 #endif |
|
391 |
2996
|
392 #if defined (EWOULDBLOCK) |
3779
|
393 # define X_EWOULDBLOCK EWOULDBLOCK |
|
394 #else |
|
395 # define X_EWOULDBLOCK -99 |
|
396 #endif |
|
397 |
|
398 #if defined (EAGAIN) |
|
399 # define X_EAGAIN EAGAIN |
|
400 #else |
|
401 # define X_EAGAIN -99 |
|
402 #endif |
|
403 |
|
404 if (errno == X_EWOULDBLOCK || errno == X_EAGAIN) |
2996
|
405 { |
3779
|
406 if (sh_unset_nodelay_mode (fileno (stream)) < 0) |
2996
|
407 return (EOF); |
|
408 continue; |
|
409 } |
|
410 |
3779
|
411 #undef X_EWOULDBLOCK |
|
412 #undef X_EAGAIN |
2996
|
413 |
|
414 /* If the error that we received was SIGINT, then try again, |
|
415 this is simply an interrupted system call to read (). |
|
416 Otherwise, some error ocurred, also signifying EOF. */ |
|
417 if (errno != EINTR) |
|
418 return (EOF); |
|
419 } |
|
420 } |