input.c revision 58310
1279264Sdelphij/* input.c -- character input functions for readline. */
2110010Smarkm
3110010Smarkm/* Copyright (C) 1994 Free Software Foundation, Inc.
4160819Ssimon
5110010Smarkm   This file is part of the GNU Readline Library, a library for
6110010Smarkm   reading lines of text with interactive input and history editing.
7110010Smarkm
8110010Smarkm   The GNU Readline Library is free software; you can redistribute it
9110010Smarkm   and/or modify it under the terms of the GNU General Public License
10110010Smarkm   as published by the Free Software Foundation; either version 2, or
11110010Smarkm   (at your option) any later version.
12110010Smarkm
13110010Smarkm   The GNU Readline Library is distributed in the hope that it will be
14110010Smarkm   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15110010Smarkm   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16110010Smarkm   GNU General Public License for more details.
17110010Smarkm
18110010Smarkm   The GNU General Public License is often shipped with GNU software, and
19110010Smarkm   is generally kept in a file called COPYING or LICENSE.  If you do not
20215698Ssimon   have a copy of the license, write to the Free Software Foundation,
21215698Ssimon   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22215698Ssimon#define READLINE_LIBRARY
23215698Ssimon
24215698Ssimon#if defined (HAVE_CONFIG_H)
25110010Smarkm#  include <config.h>
26110010Smarkm#endif
27110010Smarkm
28110010Smarkm#include <sys/types.h>
29110010Smarkm#include <fcntl.h>
30110010Smarkm#if defined (HAVE_SYS_FILE_H)
31110010Smarkm#  include <sys/file.h>
32110010Smarkm#endif /* HAVE_SYS_FILE_H */
33110010Smarkm
34110010Smarkm#if defined (HAVE_UNISTD_H)
35110010Smarkm#  include <unistd.h>
36110010Smarkm#endif /* HAVE_UNISTD_H */
37110010Smarkm
38110010Smarkm#if defined (HAVE_STDLIB_H)
39110010Smarkm#  include <stdlib.h>
40110010Smarkm#else
41279264Sdelphij#  include "ansi_stdlib.h"
42279264Sdelphij#endif /* HAVE_STDLIB_H */
43110010Smarkm
44110010Smarkm#if defined (HAVE_SELECT)
45215698Ssimon#  if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
46215698Ssimon#    include <sys/time.h>
47215698Ssimon#  endif
48215698Ssimon#endif /* HAVE_SELECT */
49160819Ssimon#if defined (HAVE_SYS_SELECT_H)
50215698Ssimon#  include <sys/select.h>
51160819Ssimon#endif
52160819Ssimon
53279264Sdelphij#if defined (FIONREAD_IN_SYS_IOCTL)
54279264Sdelphij#  include <sys/ioctl.h>
55279264Sdelphij#endif
56110010Smarkm
57279264Sdelphij#include <stdio.h>
58279264Sdelphij#include <errno.h>
59279264Sdelphij
60279264Sdelphij#if !defined (errno)
61279264Sdelphijextern int errno;
62279264Sdelphij#endif /* !errno */
63215698Ssimon
64279264Sdelphij/* System-specific feature definitions and include files. */
65279264Sdelphij#include "rldefs.h"
66279264Sdelphij
67279264Sdelphij/* Some standard library routines. */
68279264Sdelphij#include "readline.h"
69215698Ssimon
70279264Sdelphij#include "rlprivate.h"
71110010Smarkm#include "rlshell.h"
72110010Smarkm#include "xmalloc.h"
73110010Smarkm
74110010Smarkm/* What kind of non-blocking I/O do we have? */
75110010Smarkm#if !defined (O_NDELAY) && defined (O_NONBLOCK)
76110010Smarkm#  define O_NDELAY O_NONBLOCK	/* Posix style */
77110010Smarkm#endif
78110010Smarkm
79110010Smarkm/* Non-null means it is a pointer to a function to run while waiting for
80110010Smarkm   character input. */
81110010SmarkmFunction *rl_event_hook = (Function *)NULL;
82110010Smarkm
83110010SmarkmFunction *rl_getc_function = rl_getc;
84110010Smarkm
85110010Smarkm/* **************************************************************** */
86110010Smarkm/*								    */
87110010Smarkm/*			Character Input Buffering       	    */
88110010Smarkm/*								    */
89110010Smarkm/* **************************************************************** */
90110010Smarkm
91110010Smarkmstatic int pop_index, push_index;
92110010Smarkmstatic unsigned char ibuffer[512];
93110010Smarkmstatic int ibuffer_len = sizeof (ibuffer) - 1;
94110010Smarkm
95110010Smarkm#define any_typein (push_index != pop_index)
96110010Smarkm
97110010Smarkmint
98110010Smarkm_rl_any_typein ()
99110010Smarkm{
100110010Smarkm  return any_typein;
101110010Smarkm}
102110010Smarkm
103110010Smarkm/* Return the amount of space available in the buffer for stuffing
104110010Smarkm   characters. */
105110010Smarkmstatic int
106110010Smarkmibuffer_space ()
107110010Smarkm{
108110010Smarkm  if (pop_index > push_index)
109110010Smarkm    return (pop_index - push_index - 1);
110110010Smarkm  else
111110010Smarkm    return (ibuffer_len - (push_index - pop_index));
112110010Smarkm}
113110010Smarkm
114110010Smarkm/* Get a key from the buffer of characters to be read.
115110010Smarkm   Return the key in KEY.
116110010Smarkm   Result is KEY if there was a key, or 0 if there wasn't. */
117110010Smarkmstatic int
118110010Smarkmrl_get_char (key)
119110010Smarkm     int *key;
120110010Smarkm{
121110010Smarkm  if (push_index == pop_index)
122110010Smarkm    return (0);
123110010Smarkm
124110010Smarkm  *key = ibuffer[pop_index++];
125110010Smarkm
126110010Smarkm  if (pop_index >= ibuffer_len)
127110010Smarkm    pop_index = 0;
128110010Smarkm
129110010Smarkm  return (1);
130110010Smarkm}
131110010Smarkm
132110010Smarkm/* Stuff KEY into the *front* of the input buffer.
133160819Ssimon   Returns non-zero if successful, zero if there is
134110010Smarkm   no space left in the buffer. */
135110010Smarkmstatic int
136279264Sdelphijrl_unget_char (key)
137215698Ssimon     int key;
138215698Ssimon{
139215698Ssimon  if (ibuffer_space ())
140215698Ssimon    {
141110010Smarkm      pop_index--;
142110010Smarkm      if (pop_index < 0)
143110010Smarkm	pop_index = ibuffer_len - 1;
144110010Smarkm      ibuffer[pop_index] = key;
145110010Smarkm      return (1);
146110010Smarkm    }
147215698Ssimon  return (0);
148160819Ssimon}
149110010Smarkm
150110010Smarkm/* If a character is available to be read, then read it
151110010Smarkm   and stuff it into IBUFFER.  Otherwise, just return. */
152110010Smarkmstatic void
153110010Smarkmrl_gather_tyi ()
154110010Smarkm{
155110010Smarkm  int tty;
156110010Smarkm  register int tem, result;
157110010Smarkm  int chars_avail;
158110010Smarkm  char input;
159110010Smarkm#if defined(HAVE_SELECT)
160110010Smarkm  fd_set readfds, exceptfds;
161110010Smarkm  struct timeval timeout;
162110010Smarkm#endif
163110010Smarkm
164110010Smarkm  tty = fileno (rl_instream);
165110010Smarkm
166110010Smarkm#if defined (HAVE_SELECT)
167110010Smarkm  FD_ZERO (&readfds);
168160819Ssimon  FD_ZERO (&exceptfds);
169110010Smarkm  FD_SET (tty, &readfds);
170110010Smarkm  FD_SET (tty, &exceptfds);
171110010Smarkm  timeout.tv_sec = 0;
172160819Ssimon  timeout.tv_usec = 100000;	/* 0.1 seconds */
173110010Smarkm  if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0)
174110010Smarkm    return;	/* Nothing to read. */
175160819Ssimon#endif
176110010Smarkm
177160819Ssimon  result = -1;
178110010Smarkm#if defined (FIONREAD)
179110010Smarkm  result = ioctl (tty, FIONREAD, &chars_avail);
180160819Ssimon#endif
181160819Ssimon
182160819Ssimon#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. */
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
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
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{
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