Patch-ID: bash32-047
[bash.git] / input.c
blob7933da2f2ee3a5e385817e3b98b337c8dd7bac19
1 /* input.c -- functions to perform buffered input with synchronization. */
3 /* Copyright (C) 1992 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
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.
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.
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. */
21 #include "config.h"
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>
32 #if defined (HAVE_UNISTD_H)
33 # include <unistd.h>
34 #endif
36 #include "bashansi.h"
37 #include "bashintl.h"
39 #include "command.h"
40 #include "general.h"
41 #include "input.h"
42 #include "error.h"
43 #include "externs.h"
44 #include "quit.h"
46 #if !defined (errno)
47 extern int errno;
48 #endif /* !errno */
50 extern void termsig_handler __P((int));
52 /* Functions to handle reading input on systems that don't restart read(2)
53 if a signal is received. */
55 static char localbuf[128];
56 static int local_index = 0, local_bufused = 0;
58 /* Posix and USG systems do not guarantee to restart read () if it is
59 interrupted by a signal. We do the read ourselves, and restart it
60 if it returns EINTR. */
61 int
62 getc_with_restart (stream)
63 FILE *stream;
65 unsigned char uc;
67 CHECK_TERMSIG;
69 /* Try local buffering to reduce the number of read(2) calls. */
70 if (local_index == local_bufused || local_bufused == 0)
72 while (1)
74 CHECK_TERMSIG;
75 local_bufused = read (fileno (stream), localbuf, sizeof(localbuf));
76 if (local_bufused > 0)
77 break;
78 else if (local_bufused == 0 || errno != EINTR)
80 local_index = 0;
81 return EOF;
84 local_index = 0;
86 uc = localbuf[local_index++];
87 return uc;
90 int
91 ungetc_with_restart (c, stream)
92 int c;
93 FILE *stream;
95 if (local_index == 0 || c == EOF)
96 return EOF;
97 localbuf[--local_index] = c;
98 return c;
101 #if defined (BUFFERED_INPUT)
103 /* A facility similar to stdio, but input-only. */
105 #if defined (USING_BASH_MALLOC)
106 # define MAX_INPUT_BUFFER_SIZE 8176
107 #else
108 # define MAX_INPUT_BUFFER_SIZE 8192
109 #endif
111 #if !defined (SEEK_CUR)
112 # define SEEK_CUR 1
113 #endif /* !SEEK_CUR */
115 #ifdef max
116 # undef max
117 #endif
118 #define max(a, b) (((a) > (b)) ? (a) : (b))
119 #ifdef min
120 # undef min
121 #endif
122 #define min(a, b) ((a) > (b) ? (b) : (a))
124 extern int interactive_shell;
126 int bash_input_fd_changed;
128 /* This provides a way to map from a file descriptor to the buffer
129 associated with that file descriptor, rather than just the other
130 way around. This is needed so that buffers are managed properly
131 in constructs like 3<&4. buffers[x]->b_fd == x -- that is how the
132 correspondence is maintained. */
133 static BUFFERED_STREAM **buffers = (BUFFERED_STREAM **)NULL;
134 static int nbuffers;
136 #define ALLOCATE_BUFFERS(n) \
137 do { if ((n) >= nbuffers) allocate_buffers (n); } while (0)
139 /* Make sure `buffers' has at least N elements. */
140 static void
141 allocate_buffers (n)
142 int n;
144 register int i, orig_nbuffers;
146 orig_nbuffers = nbuffers;
147 nbuffers = n + 20;
148 buffers = (BUFFERED_STREAM **)xrealloc
149 (buffers, nbuffers * sizeof (BUFFERED_STREAM *));
151 /* Zero out the new buffers. */
152 for (i = orig_nbuffers; i < nbuffers; i++)
153 buffers[i] = (BUFFERED_STREAM *)NULL;
156 /* Construct and return a BUFFERED_STREAM corresponding to file descriptor
157 FD, using BUFFER. */
158 static BUFFERED_STREAM *
159 make_buffered_stream (fd, buffer, bufsize)
160 int fd;
161 char *buffer;
162 size_t bufsize;
164 BUFFERED_STREAM *bp;
166 bp = (BUFFERED_STREAM *)xmalloc (sizeof (BUFFERED_STREAM));
167 ALLOCATE_BUFFERS (fd);
168 buffers[fd] = bp;
169 bp->b_fd = fd;
170 bp->b_buffer = buffer;
171 bp->b_size = bufsize;
172 bp->b_used = bp->b_inputp = bp->b_flag = 0;
173 if (bufsize == 1)
174 bp->b_flag |= B_UNBUFF;
175 return (bp);
178 /* Allocate a new BUFFERED_STREAM, copy BP to it, and return the new copy. */
179 static BUFFERED_STREAM *
180 copy_buffered_stream (bp)
181 BUFFERED_STREAM *bp;
183 BUFFERED_STREAM *nbp;
185 if (!bp)
186 return ((BUFFERED_STREAM *)NULL);
188 nbp = (BUFFERED_STREAM *)xmalloc (sizeof (BUFFERED_STREAM));
189 xbcopy ((char *)bp, (char *)nbp, sizeof (BUFFERED_STREAM));
190 return (nbp);
194 set_bash_input_fd (fd)
195 int fd;
197 if (bash_input.type == st_bstream)
198 bash_input.location.buffered_fd = fd;
199 else if (interactive_shell == 0)
200 default_buffered_input = fd;
201 return 0;
205 fd_is_bash_input (fd)
206 int fd;
208 if (bash_input.type == st_bstream && bash_input.location.buffered_fd == fd)
209 return 1;
210 else if (interactive_shell == 0 && default_buffered_input == fd)
211 return 1;
212 return 0;
215 /* Save the buffered stream corresponding to file descriptor FD (which bash
216 is using to read input) to a buffered stream associated with NEW_FD. If
217 NEW_FD is -1, a new file descriptor is allocated with fcntl. The new
218 file descriptor is returned on success, -1 on error. */
220 save_bash_input (fd, new_fd)
221 int fd, new_fd;
223 int nfd;
225 /* Sync the stream so we can re-read from the new file descriptor. We
226 might be able to avoid this by copying the buffered stream verbatim
227 to the new file descriptor. */
228 if (buffers[fd])
229 sync_buffered_stream (fd);
231 /* Now take care of duplicating the file descriptor that bash is
232 using for input, so we can reinitialize it later. */
233 nfd = (new_fd == -1) ? fcntl (fd, F_DUPFD, 10) : new_fd;
234 if (nfd == -1)
236 if (fcntl (fd, F_GETFD, 0) == 0)
237 sys_error (_("cannot allocate new file descriptor for bash input from fd %d"), fd);
238 return -1;
241 if (buffers[nfd])
243 /* What's this? A stray buffer without an associated open file
244 descriptor? Free up the buffer and report the error. */
245 internal_error (_("save_bash_input: buffer already exists for new fd %d"), nfd);
246 free_buffered_stream (buffers[nfd]);
249 /* Reinitialize bash_input.location. */
250 if (bash_input.type == st_bstream)
252 bash_input.location.buffered_fd = nfd;
253 fd_to_buffered_stream (nfd);
254 close_buffered_fd (fd); /* XXX */
256 else
257 /* If the current input type is not a buffered stream, but the shell
258 is not interactive and therefore using a buffered stream to read
259 input (e.g. with an `eval exec 3>output' inside a script), note
260 that the input fd has been changed. pop_stream() looks at this
261 value and adjusts the input fd to the new value of
262 default_buffered_input accordingly. */
263 bash_input_fd_changed++;
265 if (default_buffered_input == fd)
266 default_buffered_input = nfd;
268 SET_CLOSE_ON_EXEC (nfd);
269 return nfd;
272 /* Check that file descriptor FD is not the one that bash is currently
273 using to read input from a script. FD is about to be duplicated onto,
274 which means that the kernel will close it for us. If FD is the bash
275 input file descriptor, we need to seek backwards in the script (if
276 possible and necessary -- scripts read from stdin are still unbuffered),
277 allocate a new file descriptor to use for bash input, and re-initialize
278 the buffered stream. Make sure the file descriptor used to save bash
279 input is set close-on-exec. Returns 0 on success, -1 on failure. This
280 works only if fd is > 0 -- if fd == 0 and bash is reading input from
281 fd 0, save_bash_input is used instead, to cooperate with input
282 redirection (look at redir.c:add_undo_redirect()). */
284 check_bash_input (fd)
285 int fd;
287 if (fd_is_bash_input (fd))
289 if (fd > 0)
290 return ((save_bash_input (fd, -1) == -1) ? -1 : 0);
291 else if (fd == 0)
292 return ((sync_buffered_stream (fd) == -1) ? -1 : 0);
294 return 0;
297 /* This is the buffered stream analogue of dup2(fd1, fd2). The
298 BUFFERED_STREAM corresponding to fd2 is deallocated, if one exists.
299 BUFFERS[fd1] is copied to BUFFERS[fd2]. This is called by the
300 redirect code for constructs like 4<&0 and 3</etc/rc.local. */
302 duplicate_buffered_stream (fd1, fd2)
303 int fd1, fd2;
305 int is_bash_input, m;
307 if (fd1 == fd2)
308 return 0;
310 m = max (fd1, fd2);
311 ALLOCATE_BUFFERS (m);
313 /* If FD2 is the file descriptor bash is currently using for shell input,
314 we need to do some extra work to make sure that the buffered stream
315 actually exists (it might not if fd1 was not active, and the copy
316 didn't actually do anything). */
317 is_bash_input = (bash_input.type == st_bstream) &&
318 (bash_input.location.buffered_fd == fd2);
320 if (buffers[fd2])
322 /* If the two objects share the same b_buffer, don't free it. */
323 if (buffers[fd1] && buffers[fd1]->b_buffer && buffers[fd1]->b_buffer == buffers[fd2]->b_buffer)
324 buffers[fd2] = (BUFFERED_STREAM *)NULL;
325 else
326 free_buffered_stream (buffers[fd2]);
328 buffers[fd2] = copy_buffered_stream (buffers[fd1]);
329 if (buffers[fd2])
330 buffers[fd2]->b_fd = fd2;
332 if (is_bash_input)
334 if (!buffers[fd2])
335 fd_to_buffered_stream (fd2);
336 buffers[fd2]->b_flag |= B_WASBASHINPUT;
339 return (fd2);
342 /* Return 1 if a seek on FD will succeed. */
343 #ifndef __CYGWIN__
344 # define fd_is_seekable(fd) (lseek ((fd), 0L, SEEK_CUR) >= 0)
345 #else
346 # define fd_is_seekable(fd) 0
347 #endif /* __CYGWIN__ */
349 /* Take FD, a file descriptor, and create and return a buffered stream
350 corresponding to it. If something is wrong and the file descriptor
351 is invalid, return a NULL stream. */
352 BUFFERED_STREAM *
353 fd_to_buffered_stream (fd)
354 int fd;
356 char *buffer;
357 size_t size;
358 struct stat sb;
360 if (fstat (fd, &sb) < 0)
362 close (fd);
363 return ((BUFFERED_STREAM *)NULL);
366 size = (fd_is_seekable (fd)) ? min (sb.st_size, MAX_INPUT_BUFFER_SIZE) : 1;
367 if (size == 0)
368 size = 1;
369 buffer = (char *)xmalloc (size);
371 return (make_buffered_stream (fd, buffer, size));
374 /* Return a buffered stream corresponding to FILE, a file name. */
375 BUFFERED_STREAM *
376 open_buffered_stream (file)
377 char *file;
379 int fd;
381 fd = open (file, O_RDONLY);
382 return ((fd >= 0) ? fd_to_buffered_stream (fd) : (BUFFERED_STREAM *)NULL);
385 /* Deallocate a buffered stream and free up its resources. Make sure we
386 zero out the slot in BUFFERS that points to BP. */
387 void
388 free_buffered_stream (bp)
389 BUFFERED_STREAM *bp;
391 int n;
393 if (!bp)
394 return;
396 n = bp->b_fd;
397 if (bp->b_buffer)
398 free (bp->b_buffer);
399 free (bp);
400 buffers[n] = (BUFFERED_STREAM *)NULL;
403 /* Close the file descriptor associated with BP, a buffered stream, and free
404 up the stream. Return the status of closing BP's file descriptor. */
406 close_buffered_stream (bp)
407 BUFFERED_STREAM *bp;
409 int fd;
411 if (!bp)
412 return (0);
413 fd = bp->b_fd;
414 free_buffered_stream (bp);
415 return (close (fd));
418 /* Deallocate the buffered stream associated with file descriptor FD, and
419 close FD. Return the status of the close on FD. */
421 close_buffered_fd (fd)
422 int fd;
424 if (fd < 0)
426 errno = EBADF;
427 return -1;
429 if (fd >= nbuffers || !buffers || !buffers[fd])
430 return (close (fd));
431 return (close_buffered_stream (buffers[fd]));
434 /* Make the BUFFERED_STREAM associcated with buffers[FD] be BP, and return
435 the old BUFFERED_STREAM. */
436 BUFFERED_STREAM *
437 set_buffered_stream (fd, bp)
438 int fd;
439 BUFFERED_STREAM *bp;
441 BUFFERED_STREAM *ret;
443 ret = buffers[fd];
444 buffers[fd] = bp;
445 return ret;
448 /* Read a buffer full of characters from BP, a buffered stream. */
449 static int
450 b_fill_buffer (bp)
451 BUFFERED_STREAM *bp;
453 ssize_t nr;
455 CHECK_TERMSIG;
456 nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);
457 if (nr <= 0)
459 bp->b_used = 0;
460 bp->b_buffer[0] = 0;
461 if (nr == 0)
462 bp->b_flag |= B_EOF;
463 else
464 bp->b_flag |= B_ERROR;
465 return (EOF);
468 #if defined (__CYGWIN__)
469 /* If on cygwin, translate \r\n to \n. */
470 if (nr >= 2 && bp->b_buffer[nr - 2] == '\r' && bp->b_buffer[nr - 1] == '\n')
472 bp->b_buffer[nr - 2] = '\n';
473 nr--;
475 #endif
477 bp->b_used = nr;
478 bp->b_inputp = 0;
479 return (bp->b_buffer[bp->b_inputp++] & 0xFF);
482 /* Get a character from buffered stream BP. */
483 #define bufstream_getc(bp) \
484 (bp->b_inputp == bp->b_used || !bp->b_used) \
485 ? b_fill_buffer (bp) \
486 : bp->b_buffer[bp->b_inputp++] & 0xFF
488 /* Push C back onto buffered stream BP. */
489 static int
490 bufstream_ungetc(c, bp)
491 int c;
492 BUFFERED_STREAM *bp;
494 if (c == EOF || bp->b_inputp == 0)
495 return (EOF);
497 bp->b_buffer[--bp->b_inputp] = c;
498 return (c);
501 /* Seek backwards on file BFD to synchronize what we've read so far
502 with the underlying file pointer. */
504 sync_buffered_stream (bfd)
505 int bfd;
507 BUFFERED_STREAM *bp;
508 off_t chars_left;
510 if (buffers == 0 || (bp = buffers[bfd]) == 0)
511 return (-1);
513 chars_left = bp->b_used - bp->b_inputp;
514 if (chars_left)
515 lseek (bp->b_fd, -chars_left, SEEK_CUR);
516 bp->b_used = bp->b_inputp = 0;
517 return (0);
521 buffered_getchar ()
523 CHECK_TERMSIG;
525 #if !defined (DJGPP)
526 return (bufstream_getc (buffers[bash_input.location.buffered_fd]));
527 #else
528 /* On DJGPP, ignore \r. */
529 int ch;
530 while ((ch = bufstream_getc (buffers[bash_input.location.buffered_fd])) == '\r')
532 return ch;
533 #endif
537 buffered_ungetchar (c)
538 int c;
540 return (bufstream_ungetc (c, buffers[bash_input.location.buffered_fd]));
543 /* Make input come from file descriptor BFD through a buffered stream. */
544 void
545 with_input_from_buffered_stream (bfd, name)
546 int bfd;
547 char *name;
549 INPUT_STREAM location;
550 BUFFERED_STREAM *bp;
552 location.buffered_fd = bfd;
553 /* Make sure the buffered stream exists. */
554 bp = fd_to_buffered_stream (bfd);
555 init_yy_io (bp == 0 ? return_EOF : buffered_getchar,
556 buffered_ungetchar, st_bstream, name, location);
559 #if defined (TEST)
560 void *
561 xmalloc(s)
562 int s;
564 return (malloc (s));
567 void *
568 xrealloc(s, size)
569 char *s;
570 int size;
572 if (!s)
573 return(malloc (size));
574 else
575 return(realloc (s, size));
578 void
579 init_yy_io ()
583 process(bp)
584 BUFFERED_STREAM *bp;
586 int c;
588 while ((c = bufstream_getc(bp)) != EOF)
589 putchar(c);
592 BASH_INPUT bash_input;
594 struct stat dsb; /* can be used from gdb */
596 /* imitate /bin/cat */
597 main(argc, argv)
598 int argc;
599 char **argv;
601 register int i;
602 BUFFERED_STREAM *bp;
604 if (argc == 1) {
605 bp = fd_to_buffered_stream (0);
606 process(bp);
607 exit(0);
609 for (i = 1; i < argc; i++) {
610 if (argv[i][0] == '-' && argv[i][1] == '\0') {
611 bp = fd_to_buffered_stream (0);
612 if (!bp)
613 continue;
614 process(bp);
615 free_buffered_stream (bp);
616 } else {
617 bp = open_buffered_stream (argv[i]);
618 if (!bp)
619 continue;
620 process(bp);
621 close_buffered_stream (bp);
624 exit(0);
626 #endif /* TEST */
627 #endif /* BUFFERED_INPUT */