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