xref: /openbsd-src/gnu/lib/libreadline/input.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
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