Add -O and -T to the SYNOPSIS.
[dragonfly.git] / contrib / libreadline / input.c
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 }