source: vendor/bash/3.1/redir.c@ 3494

Last change on this file since 3494 was 3228, checked in by bird, 18 years ago

bash 3.1

File size: 29.2 KB
Line 
1/* redir.c -- Functions to perform input and output redirection. */
2
3/* Copyright (C) 1997-2005 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
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 Bash is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bash; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
20#include "config.h"
21
22#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
23 #pragma alloca
24#endif /* _AIX && RISC6000 && !__GNUC__ */
25
26#include <stdio.h>
27#include "bashtypes.h"
28#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
29# include <sys/file.h>
30#endif
31#include "filecntl.h"
32#include "posixstat.h"
33
34#if defined (HAVE_UNISTD_H)
35# include <unistd.h>
36#endif
37
38#include <errno.h>
39
40#if !defined (errno)
41extern int errno;
42#endif
43
44#include "bashansi.h"
45#include "bashintl.h"
46
47#include "memalloc.h"
48#include "shell.h"
49#include "flags.h"
50#include "execute_cmd.h"
51#include "redir.h"
52
53#if defined (BUFFERED_INPUT)
54# include "input.h"
55#endif
56
57int expanding_redir;
58
59extern int posixly_correct;
60extern REDIRECT *redirection_undo_list;
61extern REDIRECT *exec_redirection_undo_list;
62
63/* Static functions defined and used in this file. */
64static void add_undo_close_redirect __P((int));
65static void add_exec_redirect __P((REDIRECT *));
66static int add_undo_redirect __P((int));
67static int expandable_redirection_filename __P((REDIRECT *));
68static int stdin_redirection __P((enum r_instruction, int));
69static int do_redirection_internal __P((REDIRECT *, int));
70
71static int write_here_document __P((int, WORD_DESC *));
72static int write_here_string __P((int, WORD_DESC *));
73static int here_document_to_fd __P((WORD_DESC *, enum r_instruction));
74
75static int redir_special_open __P((int, char *, int, int, enum r_instruction));
76static int noclobber_open __P((char *, int, int, enum r_instruction));
77static int redir_open __P((char *, int, int, enum r_instruction));
78
79/* Spare redirector used when translating [N]>&WORD[-] or [N]<&WORD[-] to
80 a new redirection and when creating the redirection undo list. */
81static REDIRECTEE rd;
82
83/* Set to errno when a here document cannot be created for some reason.
84 Used to print a reasonable error message. */
85static int heredoc_errno;
86
87void
88redirection_error (temp, error)
89 REDIRECT *temp;
90 int error;
91{
92 char *filename, *allocname;
93 int oflags;
94
95 allocname = 0;
96 if (temp->redirector < 0)
97 /* This can happen when read_token_word encounters overflow, like in
98 exec 4294967297>x */
99 filename = _("file descriptor out of range");
100#ifdef EBADF
101 else if (temp->redirector >= 0 && errno == EBADF)
102 {
103 /* If we're dealing with two file descriptors, we have to guess about
104 which one is invalid; in the cases of r_{duplicating,move}_input and
105 r_{duplicating,move}_output we're here because dup2() failed. */
106 switch (temp->instruction)
107 {
108 case r_duplicating_input:
109 case r_duplicating_output:
110 case r_move_input:
111 case r_move_output:
112 filename = allocname = itos (temp->redirectee.dest);
113 break;
114 default:
115 filename = allocname = itos (temp->redirector);
116 break;
117 }
118 }
119#endif
120 else if (expandable_redirection_filename (temp))
121 {
122 if (posixly_correct && interactive_shell == 0)
123 {
124 oflags = temp->redirectee.filename->flags;
125 temp->redirectee.filename->flags |= W_NOGLOB;
126 }
127 filename = allocname = redirection_expand (temp->redirectee.filename);
128 if (posixly_correct && interactive_shell == 0)
129 temp->redirectee.filename->flags = oflags;
130 if (filename == 0)
131 filename = temp->redirectee.filename->word;
132 }
133 else if (temp->redirectee.dest < 0)
134 filename = "file descriptor out of range";
135 else
136 filename = allocname = itos (temp->redirectee.dest);
137
138 switch (error)
139 {
140 case AMBIGUOUS_REDIRECT:
141 internal_error (_("%s: ambiguous redirect"), filename);
142 break;
143
144 case NOCLOBBER_REDIRECT:
145 internal_error (_("%s: cannot overwrite existing file"), filename);
146 break;
147
148#if defined (RESTRICTED_SHELL)
149 case RESTRICTED_REDIRECT:
150 internal_error (_("%s: restricted: cannot redirect output"), filename);
151 break;
152#endif /* RESTRICTED_SHELL */
153
154 case HEREDOC_REDIRECT:
155 internal_error (_("cannot create temp file for here document: %s"), strerror (heredoc_errno));
156 break;
157
158 default:
159 internal_error ("%s: %s", filename, strerror (error));
160 break;
161 }
162
163 FREE (allocname);
164}
165
166/* Perform the redirections on LIST. If flags & RX_ACTIVE, then actually
167 make input and output file descriptors, otherwise just do whatever is
168 neccessary for side effecting. flags & RX_UNDOABLE says to remember
169 how to undo the redirections later, if non-zero. If flags & RX_CLEXEC
170 is non-zero, file descriptors opened in do_redirection () have their
171 close-on-exec flag set. */
172int
173do_redirections (list, flags)
174 REDIRECT *list;
175 int flags;
176{
177 int error;
178 REDIRECT *temp;
179
180 if (flags & RX_UNDOABLE)
181 {
182 if (redirection_undo_list)
183 {
184 dispose_redirects (redirection_undo_list);
185 redirection_undo_list = (REDIRECT *)NULL;
186 }
187 if (exec_redirection_undo_list)
188 dispose_exec_redirects ();
189 }
190
191 for (temp = list; temp; temp = temp->next)
192 {
193 error = do_redirection_internal (temp, flags);
194 if (error)
195 {
196 redirection_error (temp, error);
197 return (error);
198 }
199 }
200 return (0);
201}
202
203/* Return non-zero if the redirection pointed to by REDIRECT has a
204 redirectee.filename that can be expanded. */
205static int
206expandable_redirection_filename (redirect)
207 REDIRECT *redirect;
208{
209 switch (redirect->instruction)
210 {
211 case r_output_direction:
212 case r_appending_to:
213 case r_input_direction:
214 case r_inputa_direction:
215 case r_err_and_out:
216 case r_input_output:
217 case r_output_force:
218 case r_duplicating_input_word:
219 case r_duplicating_output_word:
220 case r_move_input_word:
221 case r_move_output_word:
222 return 1;
223
224 default:
225 return 0;
226 }
227}
228
229/* Expand the word in WORD returning a string. If WORD expands to
230 multiple words (or no words), then return NULL. */
231char *
232redirection_expand (word)
233 WORD_DESC *word;
234{
235 char *result;
236 WORD_LIST *tlist1, *tlist2;
237 WORD_DESC *w;
238
239 w = copy_word (word);
240 if (posixly_correct)
241 w->flags |= W_NOSPLIT;
242
243 tlist1 = make_word_list (w, (WORD_LIST *)NULL);
244 expanding_redir = 1;
245 tlist2 = expand_words_no_vars (tlist1);
246 expanding_redir = 0;
247 dispose_words (tlist1);
248
249 if (!tlist2 || tlist2->next)
250 {
251 /* We expanded to no words, or to more than a single word.
252 Dispose of the word list and return NULL. */
253 if (tlist2)
254 dispose_words (tlist2);
255 return ((char *)NULL);
256 }
257 result = string_list (tlist2); /* XXX savestring (tlist2->word->word)? */
258 dispose_words (tlist2);
259 return (result);
260}
261
262static int
263write_here_string (fd, redirectee)
264 int fd;
265 WORD_DESC *redirectee;
266{
267 char *herestr;
268 int herelen, n, e;
269
270 herestr = expand_string_to_string (redirectee->word, 0);
271 herelen = STRLEN (herestr);
272
273 n = write (fd, herestr, herelen);
274 if (n == herelen)
275 {
276 n = write (fd, "\n", 1);
277 herelen = 1;
278 }
279 e = errno;
280 FREE (herestr);
281 if (n != herelen)
282 {
283 if (e == 0)
284 e = ENOSPC;
285 return e;
286 }
287 return 0;
288}
289
290/* Write the text of the here document pointed to by REDIRECTEE to the file
291 descriptor FD, which is already open to a temp file. Return 0 if the
292 write is successful, otherwise return errno. */
293static int
294write_here_document (fd, redirectee)
295 int fd;
296 WORD_DESC *redirectee;
297{
298 char *document;
299 int document_len, fd2;
300 FILE *fp;
301 register WORD_LIST *t, *tlist;
302
303 /* Expand the text if the word that was specified had
304 no quoting. The text that we expand is treated
305 exactly as if it were surrounded by double quotes. */
306
307 if (redirectee->flags & W_QUOTED)
308 {
309 document = redirectee->word;
310 document_len = strlen (document);
311 /* Set errno to something reasonable if the write fails. */
312 if (write (fd, document, document_len) < document_len)
313 {
314 if (errno == 0)
315 errno = ENOSPC;
316 return (errno);
317 }
318 else
319 return 0;
320 }
321
322 tlist = expand_string (redirectee->word, Q_HERE_DOCUMENT);
323 if (tlist)
324 {
325 /* Try using buffered I/O (stdio) and writing a word
326 at a time, letting stdio do the work of buffering
327 for us rather than managing our own strings. Most
328 stdios are not particularly fast, however -- this
329 may need to be reconsidered later. */
330 if ((fd2 = dup (fd)) < 0 || (fp = fdopen (fd2, "w")) == NULL)
331 {
332 if (fd2 >= 0)
333 close (fd2);
334 return (errno);
335 }
336 errno = 0;
337 for (t = tlist; t; t = t->next)
338 {
339 /* This is essentially the body of
340 string_list_internal expanded inline. */
341 document = t->word->word;
342 document_len = strlen (document);
343 if (t != tlist)
344 putc (' ', fp); /* separator */
345 fwrite (document, document_len, 1, fp);
346 if (ferror (fp))
347 {
348 if (errno == 0)
349 errno = ENOSPC;
350 fd2 = errno;
351 fclose(fp);
352 dispose_words (tlist);
353 return (fd2);
354 }
355 }
356 dispose_words (tlist);
357 if (fclose (fp) != 0)
358 {
359 if (errno == 0)
360 errno = ENOSPC;
361 return (errno);
362 }
363 }
364 return 0;
365}
366
367/* Create a temporary file holding the text of the here document pointed to
368 by REDIRECTEE, and return a file descriptor open for reading to the temp
369 file. Return -1 on any error, and make sure errno is set appropriately. */
370static int
371here_document_to_fd (redirectee, ri)
372 WORD_DESC *redirectee;
373 enum r_instruction ri;
374{
375 char *filename;
376 int r, fd, fd2;
377
378 fd = sh_mktmpfd ("sh-thd", MT_USERANDOM, &filename);
379
380 /* If we failed for some reason other than the file existing, abort */
381 if (fd < 0)
382 {
383 FREE (filename);
384 return (fd);
385 }
386
387 errno = r = 0; /* XXX */
388 /* write_here_document returns 0 on success, errno on failure. */
389 if (redirectee->word)
390 r = (ri != r_reading_string) ? write_here_document (fd, redirectee)
391 : write_here_string (fd, redirectee);
392
393 if (r)
394 {
395 close (fd);
396 unlink (filename);
397 free (filename);
398 errno = r;
399 return (-1);
400 }
401
402 /* In an attempt to avoid races, we close the first fd only after opening
403 the second. */
404 /* Make the document really temporary. Also make it the input. */
405 fd2 = open (filename, O_RDONLY, 0600);
406
407 if (fd2 < 0)
408 {
409 r = errno;
410 unlink (filename);
411 free (filename);
412 close (fd);
413 errno = r;
414 return -1;
415 }
416
417 close (fd);
418 if (unlink (filename) < 0)
419 {
420 r = errno;
421#if defined (__CYGWIN__)
422 /* Under CygWin 1.1.0, the unlink will fail if the file is
423 open. This hack will allow the previous action of silently
424 ignoring the error, but will still leave the file there. This
425 needs some kind of magic. */
426 if (r == EACCES)
427 return (fd2);
428#endif /* __CYGWIN__ */
429 close (fd2);
430 free (filename);
431 errno = r;
432 return (-1);
433 }
434
435 free (filename);
436 return (fd2);
437}
438
439#define RF_DEVFD 1
440#define RF_DEVSTDERR 2
441#define RF_DEVSTDIN 3
442#define RF_DEVSTDOUT 4
443#define RF_DEVTCP 5
444#define RF_DEVUDP 6
445
446/* A list of pattern/value pairs for filenames that the redirection
447 code handles specially. */
448static STRING_INT_ALIST _redir_special_filenames[] = {
449#if !defined (HAVE_DEV_FD)
450 { "/dev/fd/[0-9]*", RF_DEVFD },
451#endif
452#if !defined (HAVE_DEV_STDIN)
453 { "/dev/stderr", RF_DEVSTDERR },
454 { "/dev/stdin", RF_DEVSTDIN },
455 { "/dev/stdout", RF_DEVSTDOUT },
456#endif
457#if defined (NETWORK_REDIRECTIONS)
458 { "/dev/tcp/*/*", RF_DEVTCP },
459 { "/dev/udp/*/*", RF_DEVUDP },
460#endif
461 { (char *)NULL, -1 }
462};
463
464static int
465redir_special_open (spec, filename, flags, mode, ri)
466 int spec;
467 char *filename;
468 int flags, mode;
469 enum r_instruction ri;
470{
471 int fd;
472#if !defined (HAVE_DEV_FD)
473 intmax_t lfd;
474#endif
475
476 fd = -1;
477 switch (spec)
478 {
479#if !defined (HAVE_DEV_FD)
480 case RF_DEVFD:
481 if (all_digits (filename+8) && legal_number (filename+8, &lfd) && lfd == (int)lfd)
482 {
483 fd = lfd;
484 fd = fcntl (fd, F_DUPFD, 10);
485 }
486 else
487 fd = AMBIGUOUS_REDIRECT;
488 break;
489#endif
490
491#if !defined (HAVE_DEV_STDIN)
492 case RF_DEVSTDIN:
493 fd = fcntl (0, F_DUPFD, 10);
494 break;
495 case RF_DEVSTDOUT:
496 fd = fcntl (1, F_DUPFD, 10);
497 break;
498 case RF_DEVSTDERR:
499 fd = fcntl (2, F_DUPFD, 10);
500 break;
501#endif
502
503#if defined (NETWORK_REDIRECTIONS)
504 case RF_DEVTCP:
505 case RF_DEVUDP:
506#if defined (HAVE_NETWORK)
507 fd = netopen (filename);
508#else
509 internal_warning (_("/dev/(tcp|udp)/host/port not supported without networking"));
510 fd = open (filename, flags, mode);
511#endif
512 break;
513#endif /* NETWORK_REDIRECTIONS */
514 }
515
516 return fd;
517}
518
519/* Open FILENAME with FLAGS in noclobber mode, hopefully avoiding most
520 race conditions and avoiding the problem where the file is replaced
521 between the stat(2) and open(2). */
522static int
523noclobber_open (filename, flags, mode, ri)
524 char *filename;
525 int flags, mode;
526 enum r_instruction ri;
527{
528 int r, fd;
529 struct stat finfo, finfo2;
530
531 /* If the file exists and is a regular file, return an error
532 immediately. */
533 r = stat (filename, &finfo);
534 if (r == 0 && (S_ISREG (finfo.st_mode)))
535 return (NOCLOBBER_REDIRECT);
536
537 /* If the file was not present (r != 0), make sure we open it
538 exclusively so that if it is created before we open it, our open
539 will fail. Make sure that we do not truncate an existing file.
540 Note that we don't turn on O_EXCL unless the stat failed -- if
541 the file was not a regular file, we leave O_EXCL off. */
542 flags &= ~O_TRUNC;
543 if (r != 0)
544 {
545 fd = open (filename, flags|O_EXCL, mode);
546 return ((fd < 0 && errno == EEXIST) ? NOCLOBBER_REDIRECT : fd);
547 }
548 fd = open (filename, flags, mode);
549
550 /* If the open failed, return the file descriptor right away. */
551 if (fd < 0)
552 return (errno == EEXIST ? NOCLOBBER_REDIRECT : fd);
553
554 /* OK, the open succeeded, but the file may have been changed from a
555 non-regular file to a regular file between the stat and the open.
556 We are assuming that the O_EXCL open handles the case where FILENAME
557 did not exist and is symlinked to an existing file between the stat
558 and open. */
559
560 /* If we can open it and fstat the file descriptor, and neither check
561 revealed that it was a regular file, and the file has not been replaced,
562 return the file descriptor. */
563 if ((fstat (fd, &finfo2) == 0) && (S_ISREG (finfo2.st_mode) == 0) &&
564 r == 0 && (S_ISREG (finfo.st_mode) == 0) &&
565 same_file (filename, filename, &finfo, &finfo2))
566 return fd;
567
568 /* The file has been replaced. badness. */
569 close (fd);
570 errno = EEXIST;
571 return (NOCLOBBER_REDIRECT);
572}
573
574static int
575redir_open (filename, flags, mode, ri)
576 char *filename;
577 int flags, mode;
578 enum r_instruction ri;
579{
580 int fd, r;
581
582 r = find_string_in_alist (filename, _redir_special_filenames, 1);
583 if (r >= 0)
584 return (redir_special_open (r, filename, flags, mode, ri));
585
586 /* If we are in noclobber mode, you are not allowed to overwrite
587 existing files. Check before opening. */
588 if (noclobber && CLOBBERING_REDIRECT (ri))
589 {
590 fd = noclobber_open (filename, flags, mode, ri);
591 if (fd == NOCLOBBER_REDIRECT)
592 return (NOCLOBBER_REDIRECT);
593 }
594 else
595 {
596 fd = open (filename, flags, mode);
597#if defined (AFS)
598 if ((fd < 0) && (errno == EACCES))
599 {
600 fd = open (filename, flags & ~O_CREAT, mode);
601 errno = EACCES; /* restore errno */
602 }
603#endif /* AFS */
604 }
605
606 return fd;
607}
608
609/* Do the specific redirection requested. Returns errno or one of the
610 special redirection errors (*_REDIRECT) in case of error, 0 on success.
611 If flags & RX_ACTIVE is zero, then just do whatever is neccessary to
612 produce the appropriate side effects. flags & RX_UNDOABLE, if non-zero,
613 says to remember how to undo each redirection. If flags & RX_CLEXEC is
614 non-zero, then we set all file descriptors > 2 that we open to be
615 close-on-exec. */
616static int
617do_redirection_internal (redirect, flags)
618 REDIRECT *redirect;
619 int flags;
620{
621 WORD_DESC *redirectee;
622 int redir_fd, fd, redirector, r, oflags;
623 intmax_t lfd;
624 char *redirectee_word;
625 enum r_instruction ri;
626 REDIRECT *new_redirect;
627
628 redirectee = redirect->redirectee.filename;
629 redir_fd = redirect->redirectee.dest;
630 redirector = redirect->redirector;
631 ri = redirect->instruction;
632
633if (redirect->flags & RX_INTERNAL)
634 flags |= RX_INTERNAL;
635
636 if (TRANSLATE_REDIRECT (ri))
637 {
638 /* We have [N]>&WORD[-] or [N]<&WORD[-]. Expand WORD, then translate
639 the redirection into a new one and continue. */
640 redirectee_word = redirection_expand (redirectee);
641
642 /* XXX - what to do with [N]<&$w- where w is unset or null? ksh93
643 closes N. */
644 if (redirectee_word == 0)
645 return (AMBIGUOUS_REDIRECT);
646 else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
647 {
648 rd.dest = 0;
649 new_redirect = make_redirection (redirector, r_close_this, rd);
650 }
651 else if (all_digits (redirectee_word))
652 {
653 if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
654 rd.dest = lfd;
655 else
656 rd.dest = -1; /* XXX */
657 switch (ri)
658 {
659 case r_duplicating_input_word:
660 new_redirect = make_redirection (redirector, r_duplicating_input, rd);
661 break;
662 case r_duplicating_output_word:
663 new_redirect = make_redirection (redirector, r_duplicating_output, rd);
664 break;
665 case r_move_input_word:
666 new_redirect = make_redirection (redirector, r_move_input, rd);
667 break;
668 case r_move_output_word:
669 new_redirect = make_redirection (redirector, r_move_output, rd);
670 break;
671 }
672 }
673 else if (ri == r_duplicating_output_word && redirector == 1)
674 {
675 rd.filename = make_bare_word (redirectee_word);
676 new_redirect = make_redirection (1, r_err_and_out, rd);
677 }
678 else
679 {
680 free (redirectee_word);
681 return (AMBIGUOUS_REDIRECT);
682 }
683
684 free (redirectee_word);
685
686 /* Set up the variables needed by the rest of the function from the
687 new redirection. */
688 if (new_redirect->instruction == r_err_and_out)
689 {
690 char *alloca_hack;
691
692 /* Copy the word without allocating any memory that must be
693 explicitly freed. */
694 redirectee = (WORD_DESC *)alloca (sizeof (WORD_DESC));
695 xbcopy ((char *)new_redirect->redirectee.filename,
696 (char *)redirectee, sizeof (WORD_DESC));
697
698 alloca_hack = (char *)
699 alloca (1 + strlen (new_redirect->redirectee.filename->word));
700 redirectee->word = alloca_hack;
701 strcpy (redirectee->word, new_redirect->redirectee.filename->word);
702 }
703 else
704 /* It's guaranteed to be an integer, and shouldn't be freed. */
705 redirectee = new_redirect->redirectee.filename;
706
707 redir_fd = new_redirect->redirectee.dest;
708 redirector = new_redirect->redirector;
709 ri = new_redirect->instruction;
710
711 /* Overwrite the flags element of the old redirect with the new value. */
712 redirect->flags = new_redirect->flags;
713 dispose_redirects (new_redirect);
714 }
715
716 switch (ri)
717 {
718 case r_output_direction:
719 case r_appending_to:
720 case r_input_direction:
721 case r_inputa_direction:
722 case r_err_and_out: /* command &>filename */
723 case r_input_output:
724 case r_output_force:
725 if (posixly_correct && interactive_shell == 0)
726 {
727 oflags = redirectee->flags;
728 redirectee->flags |= W_NOGLOB;
729 }
730 redirectee_word = redirection_expand (redirectee);
731 if (posixly_correct && interactive_shell == 0)
732 redirectee->flags = oflags;
733
734 if (redirectee_word == 0)
735 return (AMBIGUOUS_REDIRECT);
736
737#if defined (RESTRICTED_SHELL)
738 if (restricted && (WRITE_REDIRECT (ri)))
739 {
740 free (redirectee_word);
741 return (RESTRICTED_REDIRECT);
742 }
743#endif /* RESTRICTED_SHELL */
744
745 fd = redir_open (redirectee_word, redirect->flags, 0666, ri);
746 free (redirectee_word);
747
748 if (fd == NOCLOBBER_REDIRECT)
749 return (fd);
750
751 if (fd < 0)
752 return (errno);
753
754 if (flags & RX_ACTIVE)
755 {
756 if (flags & RX_UNDOABLE)
757 {
758 /* Only setup to undo it if the thing to undo is active. */
759 if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
760 add_undo_redirect (redirector);
761 else
762 add_undo_close_redirect (redirector);
763 }
764
765#if defined (BUFFERED_INPUT)
766 check_bash_input (redirector);
767#endif
768
769 if ((fd != redirector) && (dup2 (fd, redirector) < 0))
770 return (errno);
771
772#if defined (BUFFERED_INPUT)
773 /* Do not change the buffered stream for an implicit redirection
774 of /dev/null to fd 0 for asynchronous commands without job
775 control (r_inputa_direction). */
776 if (ri == r_input_direction || ri == r_input_output)
777 duplicate_buffered_stream (fd, redirector);
778#endif /* BUFFERED_INPUT */
779
780 /*
781 * If we're remembering, then this is the result of a while, for
782 * or until loop with a loop redirection, or a function/builtin
783 * executing in the parent shell with a redirection. In the
784 * function/builtin case, we want to set all file descriptors > 2
785 * to be close-on-exec to duplicate the effect of the old
786 * for i = 3 to NOFILE close(i) loop. In the case of the loops,
787 * both sh and ksh leave the file descriptors open across execs.
788 * The Posix standard mentions only the exec builtin.
789 */
790 if ((flags & RX_CLEXEC) && (redirector > 2))
791 SET_CLOSE_ON_EXEC (redirector);
792 }
793
794 if (fd != redirector)
795 {
796#if defined (BUFFERED_INPUT)
797 if (INPUT_REDIRECT (ri))
798 close_buffered_fd (fd);
799 else
800#endif /* !BUFFERED_INPUT */
801 close (fd); /* Don't close what we just opened! */
802 }
803
804 /* If we are hacking both stdout and stderr, do the stderr
805 redirection here. */
806 if (ri == r_err_and_out)
807 {
808 if (flags & RX_ACTIVE)
809 {
810 if (flags & RX_UNDOABLE)
811 add_undo_redirect (2);
812 if (dup2 (1, 2) < 0)
813 return (errno);
814 }
815 }
816 break;
817
818 case r_reading_until:
819 case r_deblank_reading_until:
820 case r_reading_string:
821 /* REDIRECTEE is a pointer to a WORD_DESC containing the text of
822 the new input. Place it in a temporary file. */
823 if (redirectee)
824 {
825 fd = here_document_to_fd (redirectee, ri);
826
827 if (fd < 0)
828 {
829 heredoc_errno = errno;
830 return (HEREDOC_REDIRECT);
831 }
832
833 if (flags & RX_ACTIVE)
834 {
835 if (flags & RX_UNDOABLE)
836 {
837 /* Only setup to undo it if the thing to undo is active. */
838 if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
839 add_undo_redirect (redirector);
840 else
841 add_undo_close_redirect (redirector);
842 }
843
844#if defined (BUFFERED_INPUT)
845 check_bash_input (redirector);
846#endif
847 if (fd != redirector && dup2 (fd, redirector) < 0)
848 {
849 r = errno;
850 close (fd);
851 return (r);
852 }
853
854#if defined (BUFFERED_INPUT)
855 duplicate_buffered_stream (fd, redirector);
856#endif
857
858 if ((flags & RX_CLEXEC) && (redirector > 2))
859 SET_CLOSE_ON_EXEC (redirector);
860 }
861
862 if (fd != redirector)
863#if defined (BUFFERED_INPUT)
864 close_buffered_fd (fd);
865#else
866 close (fd);
867#endif
868 }
869 break;
870
871 case r_duplicating_input:
872 case r_duplicating_output:
873 case r_move_input:
874 case r_move_output:
875 if ((flags & RX_ACTIVE) && (redir_fd != redirector))
876 {
877 if (flags & RX_UNDOABLE)
878 {
879 /* Only setup to undo it if the thing to undo is active. */
880 if (fcntl (redirector, F_GETFD, 0) != -1)
881 add_undo_redirect (redirector);
882 else
883 add_undo_close_redirect (redirector);
884 }
885
886#if defined (BUFFERED_INPUT)
887 check_bash_input (redirector);
888#endif
889 /* This is correct. 2>&1 means dup2 (1, 2); */
890 if (dup2 (redir_fd, redirector) < 0)
891 return (errno);
892
893#if defined (BUFFERED_INPUT)
894 if (ri == r_duplicating_input || ri == r_move_input)
895 duplicate_buffered_stream (redir_fd, redirector);
896#endif /* BUFFERED_INPUT */
897
898 /* First duplicate the close-on-exec state of redirectee. dup2
899 leaves the flag unset on the new descriptor, which means it
900 stays open. Only set the close-on-exec bit for file descriptors
901 greater than 2 in any case, since 0-2 should always be open
902 unless closed by something like `exec 2<&-'. It should always
903 be safe to set fds > 2 to close-on-exec if they're being used to
904 save file descriptors < 2, since we don't need to preserve the
905 state of the close-on-exec flag for those fds -- they should
906 always be open. */
907 /* if ((already_set || set_unconditionally) && (ok_to_set))
908 set_it () */
909#if 0
910 if (((fcntl (redir_fd, F_GETFD, 0) == 1) || redir_fd < 2 || (flags & RX_CLEXEC)) &&
911 (redirector > 2))
912#else
913 if (((fcntl (redir_fd, F_GETFD, 0) == 1) || (redir_fd < 2 && (flags & RX_INTERNAL)) || (flags & RX_CLEXEC)) &&
914 (redirector > 2))
915#endif
916 SET_CLOSE_ON_EXEC (redirector);
917
918 /* dup-and-close redirection */
919 if (ri == r_move_input || ri == r_move_output)
920 close (redir_fd);
921 }
922 break;
923
924 case r_close_this:
925 if (flags & RX_ACTIVE)
926 {
927 if ((flags & RX_UNDOABLE) && (fcntl (redirector, F_GETFD, 0) != -1))
928 add_undo_redirect (redirector);
929
930#if defined (BUFFERED_INPUT)
931 check_bash_input (redirector);
932 close_buffered_fd (redirector);
933#else /* !BUFFERED_INPUT */
934 close (redirector);
935#endif /* !BUFFERED_INPUT */
936 }
937 break;
938
939 case r_duplicating_input_word:
940 case r_duplicating_output_word:
941 break;
942 }
943 return (0);
944}
945
946#define SHELL_FD_BASE 10
947
948/* Remember the file descriptor associated with the slot FD,
949 on REDIRECTION_UNDO_LIST. Note that the list will be reversed
950 before it is executed. Any redirections that need to be undone
951 even if REDIRECTION_UNDO_LIST is discarded by the exec builtin
952 are also saved on EXEC_REDIRECTION_UNDO_LIST. */
953static int
954add_undo_redirect (fd)
955 int fd;
956{
957 int new_fd, clexec_flag;
958 REDIRECT *new_redirect, *closer, *dummy_redirect;
959
960 new_fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
961
962 if (new_fd < 0)
963 {
964 sys_error (_("redirection error: cannot duplicate fd"));
965 return (-1);
966 }
967
968 clexec_flag = fcntl (fd, F_GETFD, 0);
969
970 rd.dest = 0;
971 closer = make_redirection (new_fd, r_close_this, rd);
972 closer->flags |= RX_INTERNAL;
973 dummy_redirect = copy_redirects (closer);
974
975 rd.dest = new_fd;
976 if (fd == 0)
977 new_redirect = make_redirection (fd, r_duplicating_input, rd);
978 else
979 new_redirect = make_redirection (fd, r_duplicating_output, rd);
980 new_redirect->flags |= RX_INTERNAL;
981 new_redirect->next = closer;
982
983 closer->next = redirection_undo_list;
984 redirection_undo_list = new_redirect;
985
986 /* Save redirections that need to be undone even if the undo list
987 is thrown away by the `exec' builtin. */
988 add_exec_redirect (dummy_redirect);
989
990 /* experimental: if we're saving a redirection to undo for a file descriptor
991 above SHELL_FD_BASE, add a redirection to be undone if the exec builtin
992 causes redirections to be discarded. */
993 if (fd >= SHELL_FD_BASE)
994 {
995 rd.dest = new_fd;
996 new_redirect = make_redirection (fd, r_duplicating_output, rd);
997#if 0
998 closer = copy_redirects (new_redirect);
999 add_exec_redirect (closer);
1000#else
1001 add_exec_redirect (new_redirect);
1002#endif
1003 }
1004
1005 /* File descriptors used only for saving others should always be
1006 marked close-on-exec. Unfortunately, we have to preserve the
1007 close-on-exec state of the file descriptor we are saving, since
1008 fcntl (F_DUPFD) sets the new file descriptor to remain open
1009 across execs. If, however, the file descriptor whose state we
1010 are saving is <= 2, we can just set the close-on-exec flag,
1011 because file descriptors 0-2 should always be open-on-exec,
1012 and the restore above in do_redirection() will take care of it. */
1013 if (clexec_flag || fd < 3)
1014 SET_CLOSE_ON_EXEC (new_fd);
1015
1016 return (0);
1017}
1018
1019/* Set up to close FD when we are finished with the current command
1020 and its redirections. */
1021static void
1022add_undo_close_redirect (fd)
1023 int fd;
1024{
1025 REDIRECT *closer;
1026
1027 rd.dest = 0;
1028 closer = make_redirection (fd, r_close_this, rd);
1029 closer->flags |= RX_INTERNAL;
1030 closer->next = redirection_undo_list;
1031 redirection_undo_list = closer;
1032}
1033
1034static void
1035add_exec_redirect (dummy_redirect)
1036 REDIRECT *dummy_redirect;
1037{
1038 dummy_redirect->next = exec_redirection_undo_list;
1039 exec_redirection_undo_list = dummy_redirect;
1040}
1041
1042/* Return 1 if the redirection specified by RI and REDIRECTOR alters the
1043 standard input. */
1044static int
1045stdin_redirection (ri, redirector)
1046 enum r_instruction ri;
1047 int redirector;
1048{
1049 switch (ri)
1050 {
1051 case r_input_direction:
1052 case r_inputa_direction:
1053 case r_input_output:
1054 case r_reading_until:
1055 case r_deblank_reading_until:
1056 case r_reading_string:
1057 return (1);
1058 case r_duplicating_input:
1059 case r_duplicating_input_word:
1060 case r_close_this:
1061 return (redirector == 0);
1062 case r_output_direction:
1063 case r_appending_to:
1064 case r_duplicating_output:
1065 case r_err_and_out:
1066 case r_output_force:
1067 case r_duplicating_output_word:
1068 return (0);
1069 }
1070 return (0);
1071}
1072
1073/* Return non-zero if any of the redirections in REDIRS alter the standard
1074 input. */
1075int
1076stdin_redirects (redirs)
1077 REDIRECT *redirs;
1078{
1079 REDIRECT *rp;
1080 int n;
1081
1082 for (n = 0, rp = redirs; rp; rp = rp->next)
1083 n += stdin_redirection (rp->instruction, rp->redirector);
1084 return n;
1085}
Note: See TracBrowser for help on using the repository browser.