Imported from ../bash-3.0.tar.gz.
[platform/upstream/bash.git] / input.c
1 /* input.c -- functions to perform buffered input with synchronization. */
2
3 /* Copyright (C) 1992 Free Software Foundation, Inc.
4
5    This file is part of GNU Bash, the Bourne Again SHell.
6
7    Bash is free software; you can redistribute it and/or modify it under
8    the terms of the GNU General Public License as published by the Free
9    Software Foundation; either version 2, or (at your option) any later
10    version.
11
12    Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13    WARRANTY; without even the implied warranty of MERCHANTABILITY or
14    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15    for more details.
16
17    You should have received a copy of the GNU General Public License along
18    with Bash; see the file COPYING.  If not, write to the Free Software
19    Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
20
21 #include "config.h"
22
23 #include "bashtypes.h"
24 #if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
25 #  include <sys/file.h>
26 #endif
27 #include "filecntl.h"
28 #include "posixstat.h"
29 #include <stdio.h>
30 #include <errno.h>
31
32 #if defined (HAVE_UNISTD_H)
33 #  include <unistd.h>
34 #endif
35
36 #include "bashansi.h"
37 #include "bashintl.h"
38
39 #include "command.h"
40 #include "general.h"
41 #include "input.h"
42 #include "error.h"
43 #include "externs.h"
44
45 #if !defined (errno)
46 extern int errno;
47 #endif /* !errno */
48
49 /* Functions to handle reading input on systems that don't restart read(2)
50    if a signal is received. */
51
52 static char localbuf[128];
53 static int local_index, local_bufused;
54
55 /* Posix and USG systems do not guarantee to restart read () if it is
56    interrupted by a signal.  We do the read ourselves, and restart it
57    if it returns EINTR. */
58 int
59 getc_with_restart (stream)
60      FILE *stream;
61 {
62   unsigned char uc;
63
64   /* Try local buffering to reduce the number of read(2) calls. */
65   if (local_index == local_bufused || local_bufused == 0)
66     {
67       while (1)
68         {
69           local_bufused = read (fileno (stream), localbuf, sizeof(localbuf));
70           if (local_bufused > 0)
71             break;
72           else if (local_bufused == 0 || errno != EINTR)
73             {
74               local_index = 0;
75               return EOF;
76             }
77         }
78       local_index = 0;
79     }
80   uc = localbuf[local_index++];
81   return uc;
82 }
83
84 int
85 ungetc_with_restart (c, stream)
86      int c;
87      FILE *stream;
88 {
89   if (local_index == 0 || c == EOF)
90     return EOF;
91   localbuf[--local_index] = c;
92   return c;
93 }
94
95 #if defined (BUFFERED_INPUT)
96
97 /* A facility similar to stdio, but input-only. */
98
99 #if defined (USING_BASH_MALLOC)
100 #  define MAX_INPUT_BUFFER_SIZE 8176
101 #else
102 #  define MAX_INPUT_BUFFER_SIZE 8192
103 #endif
104
105 #if !defined (SEEK_CUR)
106 #  define SEEK_CUR 1
107 #endif /* !SEEK_CUR */
108
109 #ifdef max
110 #  undef max
111 #endif
112 #define max(a, b)       (((a) > (b)) ? (a) : (b))
113 #ifdef min
114 #  undef min
115 #endif
116 #define min(a, b)       ((a) > (b) ? (b) : (a))
117
118 extern int interactive_shell;
119
120 int bash_input_fd_changed;
121
122 /* This provides a way to map from a file descriptor to the buffer
123    associated with that file descriptor, rather than just the other
124    way around.  This is needed so that buffers are managed properly
125    in constructs like 3<&4.  buffers[x]->b_fd == x -- that is how the
126    correspondence is maintained. */
127 static BUFFERED_STREAM **buffers = (BUFFERED_STREAM **)NULL;
128 static int nbuffers;
129
130 #define ALLOCATE_BUFFERS(n) \
131         do { if ((n) >= nbuffers) allocate_buffers (n); } while (0)
132
133 /* Make sure `buffers' has at least N elements. */
134 static void
135 allocate_buffers (n)
136      int n;
137 {
138   register int i, orig_nbuffers;
139
140   orig_nbuffers = nbuffers;
141   nbuffers = n + 20;
142   buffers = (BUFFERED_STREAM **)xrealloc
143     (buffers, nbuffers * sizeof (BUFFERED_STREAM *));
144
145   /* Zero out the new buffers. */
146   for (i = orig_nbuffers; i < nbuffers; i++)
147     buffers[i] = (BUFFERED_STREAM *)NULL;
148 }
149
150 /* Construct and return a BUFFERED_STREAM corresponding to file descriptor
151    FD, using BUFFER. */
152 static BUFFERED_STREAM *
153 make_buffered_stream (fd, buffer, bufsize)
154      int fd;
155      char *buffer;
156      size_t bufsize;
157 {
158   BUFFERED_STREAM *bp;
159
160   bp = (BUFFERED_STREAM *)xmalloc (sizeof (BUFFERED_STREAM));
161   ALLOCATE_BUFFERS (fd);
162   buffers[fd] = bp;
163   bp->b_fd = fd;
164   bp->b_buffer = buffer;
165   bp->b_size = bufsize;
166   bp->b_used = bp->b_inputp = bp->b_flag = 0;
167   if (bufsize == 1)
168     bp->b_flag |= B_UNBUFF;
169   return (bp);
170 }
171
172 /* Allocate a new BUFFERED_STREAM, copy BP to it, and return the new copy. */
173 static BUFFERED_STREAM *
174 copy_buffered_stream (bp)
175      BUFFERED_STREAM *bp;
176 {
177   BUFFERED_STREAM *nbp;
178
179   if (!bp)
180     return ((BUFFERED_STREAM *)NULL);
181
182   nbp = (BUFFERED_STREAM *)xmalloc (sizeof (BUFFERED_STREAM));
183   xbcopy ((char *)bp, (char *)nbp, sizeof (BUFFERED_STREAM));
184   return (nbp);
185 }
186
187 int
188 set_bash_input_fd (fd)
189      int fd;
190 {
191   if (bash_input.type == st_bstream)
192     bash_input.location.buffered_fd = fd;
193   else if (interactive_shell == 0)
194     default_buffered_input = fd;
195   return 0;
196 }
197
198 int
199 fd_is_bash_input (fd)
200      int fd;
201 {
202   if (bash_input.type == st_bstream && bash_input.location.buffered_fd == fd)
203     return 1;
204   else if (interactive_shell == 0 && default_buffered_input == fd)
205     return 1;
206   return 0;
207 }
208
209 /* Save the buffered stream corresponding to file descriptor FD (which bash
210    is using to read input) to a buffered stream associated with NEW_FD.  If
211    NEW_FD is -1, a new file descriptor is allocated with fcntl.  The new
212    file descriptor is returned on success, -1 on error. */
213 int
214 save_bash_input (fd, new_fd)
215      int fd, new_fd;
216 {
217   int nfd;
218
219   /* Sync the stream so we can re-read from the new file descriptor.  We
220      might be able to avoid this by copying the buffered stream verbatim
221      to the new file descriptor. */
222   if (buffers[fd])
223     sync_buffered_stream (fd);
224
225   /* Now take care of duplicating the file descriptor that bash is
226      using for input, so we can reinitialize it later. */
227   nfd = (new_fd == -1) ? fcntl (fd, F_DUPFD, 10) : new_fd;
228   if (nfd == -1)
229     {
230       if (fcntl (fd, F_GETFD, 0) == 0)
231         sys_error (_("cannot allocate new file descriptor for bash input from fd %d"), fd);
232       return -1;
233     }
234
235   if (buffers[nfd])
236     {
237       /* What's this?  A stray buffer without an associated open file
238          descriptor?  Free up the buffer and report the error. */
239       internal_error (_("save_bash_input: buffer already exists for new fd %d"), nfd);
240       free_buffered_stream (buffers[nfd]);
241     }
242
243   /* Reinitialize bash_input.location. */
244   if (bash_input.type == st_bstream)
245     {
246       bash_input.location.buffered_fd = nfd;
247       fd_to_buffered_stream (nfd);
248       close_buffered_fd (fd);   /* XXX */
249     }
250   else
251     /* If the current input type is not a buffered stream, but the shell
252        is not interactive and therefore using a buffered stream to read
253        input (e.g. with an `eval exec 3>output' inside a script), note
254        that the input fd has been changed.  pop_stream() looks at this
255        value and adjusts the input fd to the new value of
256        default_buffered_input accordingly. */
257     bash_input_fd_changed++;
258
259   if (default_buffered_input == fd)
260     default_buffered_input = nfd;
261
262   SET_CLOSE_ON_EXEC (nfd);
263   return nfd;
264 }
265
266 /* Check that file descriptor FD is not the one that bash is currently
267    using to read input from a script.  FD is about to be duplicated onto,
268    which means that the kernel will close it for us.  If FD is the bash
269    input file descriptor, we need to seek backwards in the script (if
270    possible and necessary -- scripts read from stdin are still unbuffered),
271    allocate a new file descriptor to use for bash input, and re-initialize
272    the buffered stream.  Make sure the file descriptor used to save bash
273    input is set close-on-exec. Returns 0 on success, -1 on failure.  This
274    works only if fd is > 0 -- if fd == 0 and bash is reading input from
275    fd 0, save_bash_input is used instead, to cooperate with input
276    redirection (look at redir.c:add_undo_redirect()). */
277 int
278 check_bash_input (fd)
279      int fd;
280 {
281   if (fd_is_bash_input (fd))
282     {
283       if (fd > 0)
284         return ((save_bash_input (fd, -1) == -1) ? -1 : 0);
285       else if (fd == 0)
286         return ((sync_buffered_stream (fd) == -1) ? -1 : 0);
287     }
288   return 0;
289 }
290       
291 /* This is the buffered stream analogue of dup2(fd1, fd2).  The
292    BUFFERED_STREAM corresponding to fd2 is deallocated, if one exists.
293    BUFFERS[fd1] is copied to BUFFERS[fd2].  This is called by the
294    redirect code for constructs like 4<&0 and 3</etc/rc.local. */
295 int
296 duplicate_buffered_stream (fd1, fd2)
297      int fd1, fd2;
298 {
299   int is_bash_input, m;
300
301   if (fd1 == fd2)
302     return 0;
303
304   m = max (fd1, fd2);
305   ALLOCATE_BUFFERS (m);
306
307   /* If FD2 is the file descriptor bash is currently using for shell input,
308      we need to do some extra work to make sure that the buffered stream
309      actually exists (it might not if fd1 was not active, and the copy
310      didn't actually do anything). */
311   is_bash_input = (bash_input.type == st_bstream) &&
312                   (bash_input.location.buffered_fd == fd2);
313
314   if (buffers[fd2])
315     free_buffered_stream (buffers[fd2]);
316   buffers[fd2] = copy_buffered_stream (buffers[fd1]);
317   if (buffers[fd2])
318     buffers[fd2]->b_fd = fd2;
319
320   if (is_bash_input)
321     {
322       if (!buffers[fd2])
323         fd_to_buffered_stream (fd2);
324       buffers[fd2]->b_flag |= B_WASBASHINPUT;
325     }
326
327   return (fd2);
328 }
329
330 /* Return 1 if a seek on FD will succeed. */
331 #ifndef __CYGWIN__
332 #  define fd_is_seekable(fd) (lseek ((fd), 0L, SEEK_CUR) >= 0)
333 #else
334 #  define fd_is_seekable(fd) 0
335 #endif /* __CYGWIN__ */
336
337 /* Take FD, a file descriptor, and create and return a buffered stream
338    corresponding to it.  If something is wrong and the file descriptor
339    is invalid, return a NULL stream. */
340 BUFFERED_STREAM *
341 fd_to_buffered_stream (fd)
342      int fd;
343 {
344   char *buffer;
345   size_t size;
346   struct stat sb;
347
348   if (fstat (fd, &sb) < 0)
349     {
350       close (fd);
351       return ((BUFFERED_STREAM *)NULL);
352     }
353
354   size = (fd_is_seekable (fd)) ? min (sb.st_size, MAX_INPUT_BUFFER_SIZE) : 1;
355   if (size == 0)
356     size = 1;
357   buffer = (char *)xmalloc (size);
358
359   return (make_buffered_stream (fd, buffer, size));
360 }
361
362 /* Return a buffered stream corresponding to FILE, a file name. */
363 BUFFERED_STREAM *
364 open_buffered_stream (file)
365      char *file;
366 {
367   int fd;
368
369   fd = open (file, O_RDONLY);
370   return ((fd >= 0) ? fd_to_buffered_stream (fd) : (BUFFERED_STREAM *)NULL);
371 }
372
373 /* Deallocate a buffered stream and free up its resources.  Make sure we
374    zero out the slot in BUFFERS that points to BP. */
375 void
376 free_buffered_stream (bp)
377      BUFFERED_STREAM *bp;
378 {
379   int n;
380
381   if (!bp)
382     return;
383
384   n = bp->b_fd;
385   if (bp->b_buffer)
386     free (bp->b_buffer);
387   free (bp);
388   buffers[n] = (BUFFERED_STREAM *)NULL;
389 }
390
391 /* Close the file descriptor associated with BP, a buffered stream, and free
392    up the stream.  Return the status of closing BP's file descriptor. */
393 int
394 close_buffered_stream (bp)
395      BUFFERED_STREAM *bp;
396 {
397   int fd;
398
399   if (!bp)
400     return (0);
401   fd = bp->b_fd;
402   free_buffered_stream (bp);
403   return (close (fd));
404 }
405
406 /* Deallocate the buffered stream associated with file descriptor FD, and
407    close FD.  Return the status of the close on FD. */
408 int
409 close_buffered_fd (fd)
410      int fd;
411 {
412   if (fd < 0)
413     {
414       errno = EBADF;
415       return -1;
416     }
417   if (fd >= nbuffers || !buffers || !buffers[fd])
418     return (close (fd));
419   return (close_buffered_stream (buffers[fd]));
420 }
421
422 /* Make the BUFFERED_STREAM associcated with buffers[FD] be BP, and return
423    the old BUFFERED_STREAM. */
424 BUFFERED_STREAM *
425 set_buffered_stream (fd, bp)
426      int fd;
427      BUFFERED_STREAM *bp;
428 {
429   BUFFERED_STREAM *ret;
430
431   ret = buffers[fd];
432   buffers[fd] = bp;
433   return ret;
434 }
435
436 /* Read a buffer full of characters from BP, a buffered stream. */
437 static int
438 b_fill_buffer (bp)
439      BUFFERED_STREAM *bp;
440 {
441   ssize_t nr;
442
443   nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);
444   if (nr <= 0)
445     {
446       bp->b_used = 0;
447       bp->b_buffer[0] = 0;
448       if (nr == 0)
449         bp->b_flag |= B_EOF;
450       else
451         bp->b_flag |= B_ERROR;
452       return (EOF);
453     }
454
455 #if defined (__CYGWIN__)
456   /* If on cygwin, translate \r\n to \n. */
457   if (nr >= 2 && bp->b_buffer[nr - 2] == '\r' && bp->b_buffer[nr - 1] == '\n')
458     {
459       bp->b_buffer[nr - 2] = '\n';
460       nr--;
461     }
462 #endif
463
464   bp->b_used = nr;
465   bp->b_inputp = 0;
466   return (bp->b_buffer[bp->b_inputp++] & 0xFF);
467 }
468
469 /* Get a character from buffered stream BP. */
470 #define bufstream_getc(bp) \
471   (bp->b_inputp == bp->b_used || !bp->b_used) \
472                 ? b_fill_buffer (bp) \
473                 : bp->b_buffer[bp->b_inputp++] & 0xFF
474
475 /* Push C back onto buffered stream BP. */
476 static int
477 bufstream_ungetc(c, bp)
478      int c;
479      BUFFERED_STREAM *bp;
480 {
481   if (c == EOF || bp->b_inputp == 0)
482     return (EOF);
483
484   bp->b_buffer[--bp->b_inputp] = c;
485   return (c);
486 }
487
488 /* Seek backwards on file BFD to synchronize what we've read so far
489    with the underlying file pointer. */
490 int
491 sync_buffered_stream (bfd)
492      int bfd;
493 {
494   BUFFERED_STREAM *bp;
495   off_t chars_left;
496
497   if (buffers == 0 || (bp = buffers[bfd]) == 0)
498     return (-1);
499
500   chars_left = bp->b_used - bp->b_inputp;
501   if (chars_left)
502     lseek (bp->b_fd, -chars_left, SEEK_CUR);
503   bp->b_used = bp->b_inputp = 0;
504   return (0);
505 }
506
507 int
508 buffered_getchar ()
509 {
510 #if !defined (DJGPP)
511   return (bufstream_getc (buffers[bash_input.location.buffered_fd]));
512 #else
513   /* On DJGPP, ignore \r. */
514   int ch;
515   while ((ch = bufstream_getc (buffers[bash_input.location.buffered_fd])) == '\r')
516     ;
517   return ch;
518 #endif
519 }
520
521 int
522 buffered_ungetchar (c)
523      int c;
524 {
525   return (bufstream_ungetc (c, buffers[bash_input.location.buffered_fd]));
526 }
527
528 /* Make input come from file descriptor BFD through a buffered stream. */
529 void
530 with_input_from_buffered_stream (bfd, name)
531      int bfd;
532      char *name;
533 {
534   INPUT_STREAM location;
535   BUFFERED_STREAM *bp;
536
537   location.buffered_fd = bfd;
538   /* Make sure the buffered stream exists. */
539   bp = fd_to_buffered_stream (bfd);
540   init_yy_io (bp == 0 ? return_EOF : buffered_getchar,
541               buffered_ungetchar, st_bstream, name, location);
542 }
543
544 #if defined (TEST)
545 void *
546 xmalloc(s)
547 int s;
548 {
549         return (malloc (s));
550 }
551
552 void *
553 xrealloc(s, size)
554 char    *s;
555 int     size;
556 {
557         if (!s)
558                 return(malloc (size));
559         else
560                 return(realloc (s, size));
561 }
562
563 void
564 init_yy_io ()
565 {
566 }
567
568 process(bp)
569 BUFFERED_STREAM *bp;
570 {
571         int c;
572
573         while ((c = bufstream_getc(bp)) != EOF)
574                 putchar(c);
575 }
576
577 BASH_INPUT bash_input;
578
579 struct stat dsb;                /* can be used from gdb */
580
581 /* imitate /bin/cat */
582 main(argc, argv)
583 int     argc;
584 char    **argv;
585 {
586         register int i;
587         BUFFERED_STREAM *bp;
588
589         if (argc == 1) {
590                 bp = fd_to_buffered_stream (0);
591                 process(bp);
592                 exit(0);
593         }
594         for (i = 1; i < argc; i++) {
595                 if (argv[i][0] == '-' && argv[i][1] == '\0') {
596                         bp = fd_to_buffered_stream (0);
597                         if (!bp)
598                                 continue;
599                         process(bp);
600                         free_buffered_stream (bp);
601                 } else {
602                         bp = open_buffered_stream (argv[i]);
603                         if (!bp)
604                                 continue;
605                         process(bp);
606                         close_buffered_stream (bp);
607                 }
608         }
609         exit(0);
610 }
611 #endif /* TEST */
612 #endif /* BUFFERED_INPUT */