]> git.ipfire.org Git - thirdparty/bash.git/blob - input.c
Bash-4.2 patch 16
[thirdparty/bash.git] / input.c
1 /* input.c -- functions to perform buffered input with synchronization. */
2
3 /* Copyright (C) 1992-2009 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
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.
11
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.
16
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 */
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 #include "quit.h"
45
46 #if !defined (errno)
47 extern int errno;
48 #endif /* !errno */
49
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
62 extern void termsig_handler __P((int));
63
64 /* Functions to handle reading input on systems that don't restart read(2)
65 if a signal is received. */
66
67 static char localbuf[128];
68 static int local_index = 0, local_bufused = 0;
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. */
73 int
74 getc_with_restart (stream)
75 FILE *stream;
76 {
77 unsigned char uc;
78
79 CHECK_TERMSIG;
80
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 {
86 CHECK_TERMSIG;
87 local_bufused = read (fileno (stream), localbuf, sizeof(localbuf));
88 if (local_bufused > 0)
89 break;
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 }
99 else if (local_bufused == 0 || errno != EINTR)
100 {
101 local_index = 0;
102 return EOF;
103 }
104 }
105 local_index = 0;
106 }
107 uc = localbuf[local_index++];
108 return uc;
109 }
110
111 int
112 ungetc_with_restart (c, stream)
113 int c;
114 FILE *stream;
115 {
116 if (local_index == 0 || c == EOF)
117 return EOF;
118 localbuf[--local_index] = c;
119 return c;
120 }
121
122 #if defined (BUFFERED_INPUT)
123
124 /* A facility similar to stdio, but input-only. */
125
126 #if defined (USING_BASH_MALLOC)
127 # define MAX_INPUT_BUFFER_SIZE 8176
128 #else
129 # define MAX_INPUT_BUFFER_SIZE 8192
130 #endif
131
132 #if !defined (SEEK_CUR)
133 # define SEEK_CUR 1
134 #endif /* !SEEK_CUR */
135
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
145 extern int interactive_shell;
146
147 int bash_input_fd_changed;
148
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. */
154 static BUFFERED_STREAM **buffers = (BUFFERED_STREAM **)NULL;
155 static int nbuffers;
156
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. */
161 static void
162 allocate_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. */
179 static BUFFERED_STREAM *
180 make_buffered_stream (fd, buffer, bufsize)
181 int fd;
182 char *buffer;
183 size_t bufsize;
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;
193 bp->b_used = bp->b_inputp = bp->b_flag = 0;
194 if (bufsize == 1)
195 bp->b_flag |= B_UNBUFF;
196 if (O_TEXT && (fcntl (fd, F_GETFL) & O_TEXT) != 0)
197 bp->b_flag |= O_TEXT;
198 return (bp);
199 }
200
201 /* Allocate a new BUFFERED_STREAM, copy BP to it, and return the new copy. */
202 static BUFFERED_STREAM *
203 copy_buffered_stream (bp)
204 BUFFERED_STREAM *bp;
205 {
206 BUFFERED_STREAM *nbp;
207
208 if (!bp)
209 return ((BUFFERED_STREAM *)NULL);
210
211 nbp = (BUFFERED_STREAM *)xmalloc (sizeof (BUFFERED_STREAM));
212 xbcopy ((char *)bp, (char *)nbp, sizeof (BUFFERED_STREAM));
213 return (nbp);
214 }
215
216 int
217 set_bash_input_fd (fd)
218 int fd;
219 {
220 if (bash_input.type == st_bstream)
221 bash_input.location.buffered_fd = fd;
222 else if (interactive_shell == 0)
223 default_buffered_input = fd;
224 return 0;
225 }
226
227 int
228 fd_is_bash_input (fd)
229 int fd;
230 {
231 if (bash_input.type == st_bstream && bash_input.location.buffered_fd == fd)
232 return 1;
233 else if (interactive_shell == 0 && default_buffered_input == fd)
234 return 1;
235 return 0;
236 }
237
238 /* Save the buffered stream corresponding to file descriptor FD (which bash
239 is using to read input) to a buffered stream associated with NEW_FD. If
240 NEW_FD is -1, a new file descriptor is allocated with fcntl. The new
241 file descriptor is returned on success, -1 on error. */
242 int
243 save_bash_input (fd, new_fd)
244 int fd, new_fd;
245 {
246 int nfd;
247
248 /* Sync the stream so we can re-read from the new file descriptor. We
249 might be able to avoid this by copying the buffered stream verbatim
250 to the new file descriptor. */
251 if (buffers[fd])
252 sync_buffered_stream (fd);
253
254 /* Now take care of duplicating the file descriptor that bash is
255 using for input, so we can reinitialize it later. */
256 nfd = (new_fd == -1) ? fcntl (fd, F_DUPFD, 10) : new_fd;
257 if (nfd == -1)
258 {
259 if (fcntl (fd, F_GETFD, 0) == 0)
260 sys_error (_("cannot allocate new file descriptor for bash input from fd %d"), fd);
261 return -1;
262 }
263
264 if (buffers[nfd])
265 {
266 /* What's this? A stray buffer without an associated open file
267 descriptor? Free up the buffer and report the error. */
268 internal_error (_("save_bash_input: buffer already exists for new fd %d"), nfd);
269 free_buffered_stream (buffers[nfd]);
270 }
271
272 /* Reinitialize bash_input.location. */
273 if (bash_input.type == st_bstream)
274 {
275 bash_input.location.buffered_fd = nfd;
276 fd_to_buffered_stream (nfd);
277 close_buffered_fd (fd); /* XXX */
278 }
279 else
280 /* If the current input type is not a buffered stream, but the shell
281 is not interactive and therefore using a buffered stream to read
282 input (e.g. with an `eval exec 3>output' inside a script), note
283 that the input fd has been changed. pop_stream() looks at this
284 value and adjusts the input fd to the new value of
285 default_buffered_input accordingly. */
286 bash_input_fd_changed++;
287
288 if (default_buffered_input == fd)
289 default_buffered_input = nfd;
290
291 SET_CLOSE_ON_EXEC (nfd);
292 return nfd;
293 }
294
295 /* Check that file descriptor FD is not the one that bash is currently
296 using to read input from a script. FD is about to be duplicated onto,
297 which means that the kernel will close it for us. If FD is the bash
298 input file descriptor, we need to seek backwards in the script (if
299 possible and necessary -- scripts read from stdin are still unbuffered),
300 allocate a new file descriptor to use for bash input, and re-initialize
301 the buffered stream. Make sure the file descriptor used to save bash
302 input is set close-on-exec. Returns 0 on success, -1 on failure. This
303 works only if fd is > 0 -- if fd == 0 and bash is reading input from
304 fd 0, save_bash_input is used instead, to cooperate with input
305 redirection (look at redir.c:add_undo_redirect()). */
306 int
307 check_bash_input (fd)
308 int fd;
309 {
310 if (fd_is_bash_input (fd))
311 {
312 if (fd > 0)
313 return ((save_bash_input (fd, -1) == -1) ? -1 : 0);
314 else if (fd == 0)
315 return ((sync_buffered_stream (fd) == -1) ? -1 : 0);
316 }
317 return 0;
318 }
319
320 /* This is the buffered stream analogue of dup2(fd1, fd2). The
321 BUFFERED_STREAM corresponding to fd2 is deallocated, if one exists.
322 BUFFERS[fd1] is copied to BUFFERS[fd2]. This is called by the
323 redirect code for constructs like 4<&0 and 3</etc/rc.local. */
324 int
325 duplicate_buffered_stream (fd1, fd2)
326 int fd1, fd2;
327 {
328 int is_bash_input, m;
329
330 if (fd1 == fd2)
331 return 0;
332
333 m = max (fd1, fd2);
334 ALLOCATE_BUFFERS (m);
335
336 /* If FD2 is the file descriptor bash is currently using for shell input,
337 we need to do some extra work to make sure that the buffered stream
338 actually exists (it might not if fd1 was not active, and the copy
339 didn't actually do anything). */
340 is_bash_input = (bash_input.type == st_bstream) &&
341 (bash_input.location.buffered_fd == fd2);
342
343 if (buffers[fd2])
344 {
345 /* If the two objects share the same b_buffer, don't free it. */
346 if (buffers[fd1] && buffers[fd1]->b_buffer && buffers[fd1]->b_buffer == buffers[fd2]->b_buffer)
347 buffers[fd2] = (BUFFERED_STREAM *)NULL;
348 else
349 free_buffered_stream (buffers[fd2]);
350 }
351 buffers[fd2] = copy_buffered_stream (buffers[fd1]);
352 if (buffers[fd2])
353 buffers[fd2]->b_fd = fd2;
354
355 if (is_bash_input)
356 {
357 if (!buffers[fd2])
358 fd_to_buffered_stream (fd2);
359 buffers[fd2]->b_flag |= B_WASBASHINPUT;
360 }
361
362 return (fd2);
363 }
364
365 /* Return 1 if a seek on FD will succeed. */
366 #define fd_is_seekable(fd) (lseek ((fd), 0L, SEEK_CUR) >= 0)
367
368 /* Take FD, a file descriptor, and create and return a buffered stream
369 corresponding to it. If something is wrong and the file descriptor
370 is invalid, return a NULL stream. */
371 BUFFERED_STREAM *
372 fd_to_buffered_stream (fd)
373 int fd;
374 {
375 char *buffer;
376 size_t size;
377 struct stat sb;
378
379 if (fstat (fd, &sb) < 0)
380 {
381 close (fd);
382 return ((BUFFERED_STREAM *)NULL);
383 }
384
385 size = (fd_is_seekable (fd)) ? min (sb.st_size, MAX_INPUT_BUFFER_SIZE) : 1;
386 if (size == 0)
387 size = 1;
388 buffer = (char *)xmalloc (size);
389
390 return (make_buffered_stream (fd, buffer, size));
391 }
392
393 /* Return a buffered stream corresponding to FILE, a file name. */
394 BUFFERED_STREAM *
395 open_buffered_stream (file)
396 char *file;
397 {
398 int fd;
399
400 fd = open (file, O_RDONLY);
401 return ((fd >= 0) ? fd_to_buffered_stream (fd) : (BUFFERED_STREAM *)NULL);
402 }
403
404 /* Deallocate a buffered stream and free up its resources. Make sure we
405 zero out the slot in BUFFERS that points to BP. */
406 void
407 free_buffered_stream (bp)
408 BUFFERED_STREAM *bp;
409 {
410 int n;
411
412 if (!bp)
413 return;
414
415 n = bp->b_fd;
416 if (bp->b_buffer)
417 free (bp->b_buffer);
418 free (bp);
419 buffers[n] = (BUFFERED_STREAM *)NULL;
420 }
421
422 /* Close the file descriptor associated with BP, a buffered stream, and free
423 up the stream. Return the status of closing BP's file descriptor. */
424 int
425 close_buffered_stream (bp)
426 BUFFERED_STREAM *bp;
427 {
428 int fd;
429
430 if (!bp)
431 return (0);
432 fd = bp->b_fd;
433 free_buffered_stream (bp);
434 return (close (fd));
435 }
436
437 /* Deallocate the buffered stream associated with file descriptor FD, and
438 close FD. Return the status of the close on FD. */
439 int
440 close_buffered_fd (fd)
441 int fd;
442 {
443 if (fd < 0)
444 {
445 errno = EBADF;
446 return -1;
447 }
448 if (fd >= nbuffers || !buffers || !buffers[fd])
449 return (close (fd));
450 return (close_buffered_stream (buffers[fd]));
451 }
452
453 /* Make the BUFFERED_STREAM associcated with buffers[FD] be BP, and return
454 the old BUFFERED_STREAM. */
455 BUFFERED_STREAM *
456 set_buffered_stream (fd, bp)
457 int fd;
458 BUFFERED_STREAM *bp;
459 {
460 BUFFERED_STREAM *ret;
461
462 ret = buffers[fd];
463 buffers[fd] = bp;
464 return ret;
465 }
466
467 /* Read a buffer full of characters from BP, a buffered stream. */
468 static int
469 b_fill_buffer (bp)
470 BUFFERED_STREAM *bp;
471 {
472 ssize_t nr;
473 off_t o;
474
475 CHECK_TERMSIG;
476 /* In an environment where text and binary files are treated differently,
477 compensate for lseek() on text files returning an offset different from
478 the count of characters read() returns. Text-mode streams have to be
479 treated as unbuffered. */
480 if ((bp->b_flag & (B_TEXT | B_UNBUFF)) == B_TEXT)
481 {
482 o = lseek (bp->b_fd, 0, SEEK_CUR);
483 nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);
484 if (nr > 0 && nr < lseek (bp->b_fd, 0, SEEK_CUR) - o)
485 {
486 lseek (bp->b_fd, o, SEEK_SET);
487 bp->b_flag |= B_UNBUFF;
488 bp->b_size = 1;
489 nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);
490 }
491 }
492 else
493 nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);
494 if (nr <= 0)
495 {
496 bp->b_used = 0;
497 bp->b_buffer[0] = 0;
498 if (nr == 0)
499 bp->b_flag |= B_EOF;
500 else
501 bp->b_flag |= B_ERROR;
502 return (EOF);
503 }
504
505 bp->b_used = nr;
506 bp->b_inputp = 0;
507 return (bp->b_buffer[bp->b_inputp++] & 0xFF);
508 }
509
510 /* Get a character from buffered stream BP. */
511 #define bufstream_getc(bp) \
512 (bp->b_inputp == bp->b_used || !bp->b_used) \
513 ? b_fill_buffer (bp) \
514 : bp->b_buffer[bp->b_inputp++] & 0xFF
515
516 /* Push C back onto buffered stream BP. */
517 static int
518 bufstream_ungetc(c, bp)
519 int c;
520 BUFFERED_STREAM *bp;
521 {
522 if (c == EOF || bp->b_inputp == 0)
523 return (EOF);
524
525 bp->b_buffer[--bp->b_inputp] = c;
526 return (c);
527 }
528
529 /* Seek backwards on file BFD to synchronize what we've read so far
530 with the underlying file pointer. */
531 int
532 sync_buffered_stream (bfd)
533 int bfd;
534 {
535 BUFFERED_STREAM *bp;
536 off_t chars_left;
537
538 if (buffers == 0 || (bp = buffers[bfd]) == 0)
539 return (-1);
540
541 chars_left = bp->b_used - bp->b_inputp;
542 if (chars_left)
543 lseek (bp->b_fd, -chars_left, SEEK_CUR);
544 bp->b_used = bp->b_inputp = 0;
545 return (0);
546 }
547
548 int
549 buffered_getchar ()
550 {
551 CHECK_TERMSIG;
552
553 #if !defined (DJGPP)
554 return (bufstream_getc (buffers[bash_input.location.buffered_fd]));
555 #else
556 /* On DJGPP, ignore \r. */
557 int ch;
558 while ((ch = bufstream_getc (buffers[bash_input.location.buffered_fd])) == '\r')
559 ;
560 return ch;
561 #endif
562 }
563
564 int
565 buffered_ungetchar (c)
566 int c;
567 {
568 return (bufstream_ungetc (c, buffers[bash_input.location.buffered_fd]));
569 }
570
571 /* Make input come from file descriptor BFD through a buffered stream. */
572 void
573 with_input_from_buffered_stream (bfd, name)
574 int bfd;
575 char *name;
576 {
577 INPUT_STREAM location;
578 BUFFERED_STREAM *bp;
579
580 location.buffered_fd = bfd;
581 /* Make sure the buffered stream exists. */
582 bp = fd_to_buffered_stream (bfd);
583 init_yy_io (bp == 0 ? return_EOF : buffered_getchar,
584 buffered_ungetchar, st_bstream, name, location);
585 }
586
587 #if defined (TEST)
588 void *
589 xmalloc(s)
590 int s;
591 {
592 return (malloc (s));
593 }
594
595 void *
596 xrealloc(s, size)
597 char *s;
598 int size;
599 {
600 if (!s)
601 return(malloc (size));
602 else
603 return(realloc (s, size));
604 }
605
606 void
607 init_yy_io ()
608 {
609 }
610
611 process(bp)
612 BUFFERED_STREAM *bp;
613 {
614 int c;
615
616 while ((c = bufstream_getc(bp)) != EOF)
617 putchar(c);
618 }
619
620 BASH_INPUT bash_input;
621
622 struct stat dsb; /* can be used from gdb */
623
624 /* imitate /bin/cat */
625 main(argc, argv)
626 int argc;
627 char **argv;
628 {
629 register int i;
630 BUFFERED_STREAM *bp;
631
632 if (argc == 1) {
633 bp = fd_to_buffered_stream (0);
634 process(bp);
635 exit(0);
636 }
637 for (i = 1; i < argc; i++) {
638 if (argv[i][0] == '-' && argv[i][1] == '\0') {
639 bp = fd_to_buffered_stream (0);
640 if (!bp)
641 continue;
642 process(bp);
643 free_buffered_stream (bp);
644 } else {
645 bp = open_buffered_stream (argv[i]);
646 if (!bp)
647 continue;
648 process(bp);
649 close_buffered_stream (bp);
650 }
651 }
652 exit(0);
653 }
654 #endif /* TEST */
655 #endif /* BUFFERED_INPUT */