1 /* redir.c -- Functions to perform input and output redirection. */
3 /* Copyright (C) 1997-2002 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
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)
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.
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. */
22 #if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
24 #endif /* _AIX && RISC6000 && !__GNUC__ */
27 #include "bashtypes.h"
29 # include <sys/file.h>
32 #include "posixstat.h"
34 #if defined (HAVE_UNISTD_H)
49 #include "execute_cmd.h"
52 #if defined (BUFFERED_INPUT)
56 extern int posixly_correct;
57 extern REDIRECT *redirection_undo_list;
58 extern REDIRECT *exec_redirection_undo_list;
60 /* Static functions defined and used in this file. */
61 static void add_undo_close_redirect __P((int));
62 static void add_exec_redirect __P((REDIRECT *));
63 static int add_undo_redirect __P((int));
64 static int expandable_redirection_filename __P((REDIRECT *));
65 static int stdin_redirection __P((enum r_instruction, int));
66 static int do_redirection_internal __P((REDIRECT *, int, int, int));
68 static int write_here_document __P((int, WORD_DESC *));
69 static int write_here_string __P((int, WORD_DESC *));
70 static int here_document_to_fd __P((WORD_DESC *, enum r_instruction));
72 static int redir_special_open __P((int, char *, int, int, enum r_instruction));
73 static int noclobber_open __P((char *, int, int, enum r_instruction));
74 static int redir_open __P((char *, int, int, enum r_instruction));
76 /* Spare redirector used when translating [N]>&WORD[-] or [N]<&WORD[-] to
77 a new redirection and when creating the redirection undo list. */
80 /* Set to errno when a here document cannot be created for some reason.
81 Used to print a reasonable error message. */
82 static int heredoc_errno;
85 redirection_error (temp, error)
89 char *filename, *allocname;
93 if (temp->redirector < 0)
94 /* This can happen when read_token_word encounters overflow, like in
96 filename = "file descriptor out of range";
98 else if (temp->redirector >= 0 && errno == EBADF)
100 /* If we're dealing with two file descriptors, we have to guess about
101 which one is invalid; in the cases of r_{duplicating,move}_input and
102 r_{duplicating,move}_output we're here because dup2() failed. */
103 switch (temp->instruction)
105 case r_duplicating_input:
106 case r_duplicating_output:
109 filename = allocname = itos (temp->redirectee.dest);
112 filename = allocname = itos (temp->redirector);
117 else if (expandable_redirection_filename (temp))
119 if (posixly_correct && interactive_shell == 0)
121 oflags = temp->redirectee.filename->flags;
122 temp->redirectee.filename->flags |= W_NOGLOB;
124 filename = allocname = redirection_expand (temp->redirectee.filename);
125 if (posixly_correct && interactive_shell == 0)
126 temp->redirectee.filename->flags = oflags;
128 filename = temp->redirectee.filename->word;
130 else if (temp->redirectee.dest < 0)
131 filename = "file descriptor out of range";
133 filename = allocname = itos (temp->redirectee.dest);
137 case AMBIGUOUS_REDIRECT:
138 internal_error ("%s: ambiguous redirect", filename);
141 case NOCLOBBER_REDIRECT:
142 internal_error ("%s: cannot overwrite existing file", filename);
145 #if defined (RESTRICTED_SHELL)
146 case RESTRICTED_REDIRECT:
147 internal_error ("%s: restricted: cannot redirect output", filename);
149 #endif /* RESTRICTED_SHELL */
151 case HEREDOC_REDIRECT:
152 internal_error ("cannot create temp file for here document: %s", strerror (heredoc_errno));
156 internal_error ("%s: %s", filename, strerror (error));
163 /* Perform the redirections on LIST. If FOR_REAL, then actually make
164 input and output file descriptors, otherwise just do whatever is
165 neccessary for side effecting. INTERNAL says to remember how to
166 undo the redirections later, if non-zero. If SET_CLEXEC is non-zero,
167 file descriptors opened in do_redirection () have their close-on-exec
170 do_redirections (list, for_real, internal, set_clexec)
172 int for_real, internal, set_clexec;
179 if (redirection_undo_list)
181 dispose_redirects (redirection_undo_list);
182 redirection_undo_list = (REDIRECT *)NULL;
184 if (exec_redirection_undo_list)
185 dispose_exec_redirects ();
188 for (temp = list; temp; temp = temp->next)
190 error = do_redirection_internal (temp, for_real, internal, set_clexec);
193 redirection_error (temp, error);
200 /* Return non-zero if the redirection pointed to by REDIRECT has a
201 redirectee.filename that can be expanded. */
203 expandable_redirection_filename (redirect)
206 switch (redirect->instruction)
208 case r_output_direction:
210 case r_input_direction:
211 case r_inputa_direction:
215 case r_duplicating_input_word:
216 case r_duplicating_output_word:
217 case r_move_input_word:
218 case r_move_output_word:
226 /* Expand the word in WORD returning a string. If WORD expands to
227 multiple words (or no words), then return NULL. */
229 redirection_expand (word)
233 WORD_LIST *tlist1, *tlist2;
236 w = copy_word (word);
238 w->flags |= W_NOSPLIT;
240 tlist1 = make_word_list (w, (WORD_LIST *)NULL);
241 tlist2 = expand_words_no_vars (tlist1);
242 dispose_words (tlist1);
244 if (!tlist2 || tlist2->next)
246 /* We expanded to no words, or to more than a single word.
247 Dispose of the word list and return NULL. */
249 dispose_words (tlist2);
250 return ((char *)NULL);
252 result = string_list (tlist2); /* XXX savestring (tlist2->word->word)? */
253 dispose_words (tlist2);
258 write_here_string (fd, redirectee)
260 WORD_DESC *redirectee;
265 herestr = expand_string_to_string (redirectee->word, 0);
266 herelen = strlen (herestr);
268 n = write (fd, herestr, herelen);
271 n = write (fd, "\n", 1);
285 /* Write the text of the here document pointed to by REDIRECTEE to the file
286 descriptor FD, which is already open to a temp file. Return 0 if the
287 write is successful, otherwise return errno. */
289 write_here_document (fd, redirectee)
291 WORD_DESC *redirectee;
294 int document_len, fd2;
296 register WORD_LIST *t, *tlist;
298 /* Expand the text if the word that was specified had
299 no quoting. The text that we expand is treated
300 exactly as if it were surrounded by double quotes. */
302 if (redirectee->flags & W_QUOTED)
304 document = redirectee->word;
305 document_len = strlen (document);
306 /* Set errno to something reasonable if the write fails. */
307 if (write (fd, document, document_len) < document_len)
317 tlist = expand_string (redirectee->word, Q_HERE_DOCUMENT);
320 /* Try using buffered I/O (stdio) and writing a word
321 at a time, letting stdio do the work of buffering
322 for us rather than managing our own strings. Most
323 stdios are not particularly fast, however -- this
324 may need to be reconsidered later. */
325 if ((fd2 = dup (fd)) < 0 || (fp = fdopen (fd2, "w")) == NULL)
332 for (t = tlist; t; t = t->next)
334 /* This is essentially the body of
335 string_list_internal expanded inline. */
336 document = t->word->word;
337 document_len = strlen (document);
339 putc (' ', fp); /* separator */
340 fwrite (document, document_len, 1, fp);
347 dispose_words (tlist);
351 dispose_words (tlist);
352 if (fclose (fp) != 0)
362 /* Create a temporary file holding the text of the here document pointed to
363 by REDIRECTEE, and return a file descriptor open for reading to the temp
364 file. Return -1 on any error, and make sure errno is set appropriately. */
366 here_document_to_fd (redirectee, ri)
367 WORD_DESC *redirectee;
368 enum r_instruction ri;
373 fd = sh_mktmpfd ("sh-thd", MT_USERANDOM, &filename);
375 /* If we failed for some reason other than the file existing, abort */
382 errno = r = 0; /* XXX */
383 /* write_here_document returns 0 on success, errno on failure. */
384 if (redirectee->word)
385 r = (ri != r_reading_string) ? write_here_document (fd, redirectee)
386 : write_here_string (fd, redirectee);
397 /* In an attempt to avoid races, we close the first fd only after opening
399 /* Make the document really temporary. Also make it the input. */
400 fd2 = open (filename, O_RDONLY, 0600);
413 if (unlink (filename) < 0)
416 #if defined (__CYGWIN__)
417 /* Under CygWin 1.1.0, the unlink will fail if the file is
418 open. This hack will allow the previous action of silently
419 ignoring the error, but will still leave the file there. This
420 needs some kind of magic. */
423 #endif /* __CYGWIN__ */
435 #define RF_DEVSTDERR 2
436 #define RF_DEVSTDIN 3
437 #define RF_DEVSTDOUT 4
441 /* A list of pattern/value pairs for filenames that the redirection
442 code handles specially. */
443 static STRING_INT_ALIST _redir_special_filenames[] = {
444 #if !defined (HAVE_DEV_FD)
445 { "/dev/fd/[0-9]*", RF_DEVFD },
447 #if !defined (HAVE_DEV_STDIN)
448 { "/dev/stderr", RF_DEVSTDERR },
449 { "/dev/stdin", RF_DEVSTDIN },
450 { "/dev/stdout", RF_DEVSTDOUT },
452 #if defined (NETWORK_REDIRECTIONS)
453 { "/dev/tcp/*/*", RF_DEVTCP },
454 { "/dev/udp/*/*", RF_DEVUDP },
460 redir_special_open (spec, filename, flags, mode, ri)
464 enum r_instruction ri;
467 #if !defined (HAVE_DEV_FD)
474 #if !defined (HAVE_DEV_FD)
476 if (all_digits (filename+8) && legal_number (filename+8, &lfd) && lfd == (int)lfd)
479 fd = fcntl (fd, F_DUPFD, 10);
482 fd = AMBIGUOUS_REDIRECT;
486 #if !defined (HAVE_DEV_STDIN)
488 fd = fcntl (0, F_DUPFD, 10);
491 fd = fcntl (1, F_DUPFD, 10);
494 fd = fcntl (2, F_DUPFD, 10);
498 #if defined (NETWORK_REDIRECTIONS)
501 #if defined (HAVE_NETWORK)
502 fd = netopen (filename);
504 internal_warning ("/dev/(tcp|udp)/host/port not supported without networking");
505 fd = open (filename, flags, mode);
508 #endif /* NETWORK_REDIRECTIONS */
514 /* Open FILENAME with FLAGS in noclobber mode, hopefully avoiding most
515 race conditions and avoiding the problem where the file is replaced
516 between the stat(2) and open(2). */
518 noclobber_open (filename, flags, mode, ri)
521 enum r_instruction ri;
524 struct stat finfo, finfo2;
526 /* If the file exists and is a regular file, return an error
528 r = stat (filename, &finfo);
529 if (r == 0 && (S_ISREG (finfo.st_mode)))
530 return (NOCLOBBER_REDIRECT);
532 /* If the file was not present (r != 0), make sure we open it
533 exclusively so that if it is created before we open it, our open
534 will fail. Make sure that we do not truncate an existing file.
535 Note that we don't turn on O_EXCL unless the stat failed -- if
536 the file was not a regular file, we leave O_EXCL off. */
540 fd = open (filename, flags|O_EXCL, mode);
541 return ((fd < 0 && errno == EEXIST) ? NOCLOBBER_REDIRECT : fd);
543 fd = open (filename, flags, mode);
545 /* If the open failed, return the file descriptor right away. */
547 return (errno == EEXIST ? NOCLOBBER_REDIRECT : fd);
549 /* OK, the open succeeded, but the file may have been changed from a
550 non-regular file to a regular file between the stat and the open.
551 We are assuming that the O_EXCL open handles the case where FILENAME
552 did not exist and is symlinked to an existing file between the stat
555 /* If we can open it and fstat the file descriptor, and neither check
556 revealed that it was a regular file, and the file has not been replaced,
557 return the file descriptor. */
558 if ((fstat (fd, &finfo2) == 0) && (S_ISREG (finfo2.st_mode) == 0) &&
559 r == 0 && (S_ISREG (finfo.st_mode) == 0) &&
560 same_file (filename, filename, &finfo, &finfo2))
563 /* The file has been replaced. badness. */
566 return (NOCLOBBER_REDIRECT);
570 redir_open (filename, flags, mode, ri)
573 enum r_instruction ri;
577 r = find_string_in_alist (filename, _redir_special_filenames, 1);
579 return (redir_special_open (r, filename, flags, mode, ri));
581 /* If we are in noclobber mode, you are not allowed to overwrite
582 existing files. Check before opening. */
583 if (noclobber && CLOBBERING_REDIRECT (ri))
585 fd = noclobber_open (filename, flags, mode, ri);
586 if (fd == NOCLOBBER_REDIRECT)
587 return (NOCLOBBER_REDIRECT);
591 fd = open (filename, flags, mode);
593 if ((fd < 0) && (errno == EACCES))
594 fd = open (filename, flags & ~O_CREAT, mode);
601 /* Do the specific redirection requested. Returns errno or one of the
602 special redirection errors (*_REDIRECT) in case of error, 0 on success.
603 If FOR_REAL is zero, then just do whatever is neccessary to produce the
604 appropriate side effects. REMEMBERING, if non-zero, says to remember
605 how to undo each redirection. If SET_CLEXEC is non-zero, then
606 we set all file descriptors > 2 that we open to be close-on-exec. */
608 do_redirection_internal (redirect, for_real, remembering, set_clexec)
610 int for_real, remembering, set_clexec;
612 WORD_DESC *redirectee;
613 int redir_fd, fd, redirector, r, oflags;
615 char *redirectee_word;
616 enum r_instruction ri;
617 REDIRECT *new_redirect;
619 redirectee = redirect->redirectee.filename;
620 redir_fd = redirect->redirectee.dest;
621 redirector = redirect->redirector;
622 ri = redirect->instruction;
624 if (TRANSLATE_REDIRECT (ri))
626 /* We have [N]>&WORD[-] or [N]<&WORD[-]. Expand WORD, then translate
627 the redirection into a new one and continue. */
628 redirectee_word = redirection_expand (redirectee);
630 /* XXX - what to do with [N]<&$w- where w is unset or null? ksh93
632 if (redirectee_word == 0)
633 return (AMBIGUOUS_REDIRECT);
634 else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
637 new_redirect = make_redirection (redirector, r_close_this, rd);
639 else if (all_digits (redirectee_word))
641 if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
644 rd.dest = -1; /* XXX */
647 case r_duplicating_input_word:
648 new_redirect = make_redirection (redirector, r_duplicating_input, rd);
650 case r_duplicating_output_word:
651 new_redirect = make_redirection (redirector, r_duplicating_output, rd);
653 case r_move_input_word:
654 new_redirect = make_redirection (redirector, r_move_input, rd);
656 case r_move_output_word:
657 new_redirect = make_redirection (redirector, r_move_output, rd);
661 else if (ri == r_duplicating_output_word && redirector == 1)
663 rd.filename = make_bare_word (redirectee_word);
664 new_redirect = make_redirection (1, r_err_and_out, rd);
668 free (redirectee_word);
669 return (AMBIGUOUS_REDIRECT);
672 free (redirectee_word);
674 /* Set up the variables needed by the rest of the function from the
676 if (new_redirect->instruction == r_err_and_out)
680 /* Copy the word without allocating any memory that must be
682 redirectee = (WORD_DESC *)alloca (sizeof (WORD_DESC));
683 xbcopy ((char *)new_redirect->redirectee.filename,
684 (char *)redirectee, sizeof (WORD_DESC));
686 alloca_hack = (char *)
687 alloca (1 + strlen (new_redirect->redirectee.filename->word));
688 redirectee->word = alloca_hack;
689 strcpy (redirectee->word, new_redirect->redirectee.filename->word);
692 /* It's guaranteed to be an integer, and shouldn't be freed. */
693 redirectee = new_redirect->redirectee.filename;
695 redir_fd = new_redirect->redirectee.dest;
696 redirector = new_redirect->redirector;
697 ri = new_redirect->instruction;
699 /* Overwrite the flags element of the old redirect with the new value. */
700 redirect->flags = new_redirect->flags;
701 dispose_redirects (new_redirect);
706 case r_output_direction:
708 case r_input_direction:
709 case r_inputa_direction:
710 case r_err_and_out: /* command &>filename */
713 if (posixly_correct && interactive_shell == 0)
715 oflags = redirectee->flags;
716 redirectee->flags |= W_NOGLOB;
718 redirectee_word = redirection_expand (redirectee);
719 if (posixly_correct && interactive_shell == 0)
720 redirectee->flags = oflags;
722 if (redirectee_word == 0)
723 return (AMBIGUOUS_REDIRECT);
725 #if defined (RESTRICTED_SHELL)
726 if (restricted && (WRITE_REDIRECT (ri)))
728 free (redirectee_word);
729 return (RESTRICTED_REDIRECT);
731 #endif /* RESTRICTED_SHELL */
733 fd = redir_open (redirectee_word, redirect->flags, 0666, ri);
734 free (redirectee_word);
736 if (fd == NOCLOBBER_REDIRECT)
746 /* Only setup to undo it if the thing to undo is active. */
747 if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
748 add_undo_redirect (redirector);
750 add_undo_close_redirect (redirector);
753 #if defined (BUFFERED_INPUT)
754 check_bash_input (redirector);
757 if ((fd != redirector) && (dup2 (fd, redirector) < 0))
760 #if defined (BUFFERED_INPUT)
761 /* Do not change the buffered stream for an implicit redirection
762 of /dev/null to fd 0 for asynchronous commands without job
763 control (r_inputa_direction). */
764 if (ri == r_input_direction || ri == r_input_output)
765 duplicate_buffered_stream (fd, redirector);
766 #endif /* BUFFERED_INPUT */
769 * If we're remembering, then this is the result of a while, for
770 * or until loop with a loop redirection, or a function/builtin
771 * executing in the parent shell with a redirection. In the
772 * function/builtin case, we want to set all file descriptors > 2
773 * to be close-on-exec to duplicate the effect of the old
774 * for i = 3 to NOFILE close(i) loop. In the case of the loops,
775 * both sh and ksh leave the file descriptors open across execs.
776 * The Posix standard mentions only the exec builtin.
778 if (set_clexec && (redirector > 2))
779 SET_CLOSE_ON_EXEC (redirector);
782 if (fd != redirector)
784 #if defined (BUFFERED_INPUT)
785 if (INPUT_REDIRECT (ri))
786 close_buffered_fd (fd);
788 #endif /* !BUFFERED_INPUT */
789 close (fd); /* Don't close what we just opened! */
792 /* If we are hacking both stdout and stderr, do the stderr
794 if (ri == r_err_and_out)
799 add_undo_redirect (2);
806 case r_reading_until:
807 case r_deblank_reading_until:
808 case r_reading_string:
809 /* REDIRECTEE is a pointer to a WORD_DESC containing the text of
810 the new input. Place it in a temporary file. */
813 fd = here_document_to_fd (redirectee, ri);
817 heredoc_errno = errno;
818 return (HEREDOC_REDIRECT);
825 /* Only setup to undo it if the thing to undo is active. */
826 if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
827 add_undo_redirect (redirector);
829 add_undo_close_redirect (redirector);
832 #if defined (BUFFERED_INPUT)
833 check_bash_input (redirector);
835 if (fd != redirector && dup2 (fd, redirector) < 0)
842 #if defined (BUFFERED_INPUT)
843 duplicate_buffered_stream (fd, redirector);
846 if (set_clexec && (redirector > 2))
847 SET_CLOSE_ON_EXEC (redirector);
850 if (fd != redirector)
851 #if defined (BUFFERED_INPUT)
852 close_buffered_fd (fd);
859 case r_duplicating_input:
860 case r_duplicating_output:
863 if (for_real && (redir_fd != redirector))
867 /* Only setup to undo it if the thing to undo is active. */
868 if (fcntl (redirector, F_GETFD, 0) != -1)
869 add_undo_redirect (redirector);
871 add_undo_close_redirect (redirector);
874 #if defined (BUFFERED_INPUT)
875 check_bash_input (redirector);
877 /* This is correct. 2>&1 means dup2 (1, 2); */
878 if (dup2 (redir_fd, redirector) < 0)
881 #if defined (BUFFERED_INPUT)
882 if (ri == r_duplicating_input || ri == r_move_input)
883 duplicate_buffered_stream (redir_fd, redirector);
884 #endif /* BUFFERED_INPUT */
886 /* First duplicate the close-on-exec state of redirectee. dup2
887 leaves the flag unset on the new descriptor, which means it
888 stays open. Only set the close-on-exec bit for file descriptors
889 greater than 2 in any case, since 0-2 should always be open
890 unless closed by something like `exec 2<&-'. */
891 /* if ((already_set || set_unconditionally) && (ok_to_set))
893 if (((fcntl (redir_fd, F_GETFD, 0) == 1) || set_clexec) &&
895 SET_CLOSE_ON_EXEC (redirector);
897 /* dup-and-close redirection */
898 if (ri == r_move_input || ri == r_move_output)
906 if (remembering && (fcntl (redirector, F_GETFD, 0) != -1))
907 add_undo_redirect (redirector);
909 #if defined (BUFFERED_INPUT)
910 check_bash_input (redirector);
911 close_buffered_fd (redirector);
912 #else /* !BUFFERED_INPUT */
914 #endif /* !BUFFERED_INPUT */
918 case r_duplicating_input_word:
919 case r_duplicating_output_word:
925 #define SHELL_FD_BASE 10
927 /* Remember the file descriptor associated with the slot FD,
928 on REDIRECTION_UNDO_LIST. Note that the list will be reversed
929 before it is executed. Any redirections that need to be undone
930 even if REDIRECTION_UNDO_LIST is discarded by the exec builtin
931 are also saved on EXEC_REDIRECTION_UNDO_LIST. */
933 add_undo_redirect (fd)
936 int new_fd, clexec_flag;
937 REDIRECT *new_redirect, *closer, *dummy_redirect;
939 new_fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
943 sys_error ("redirection error: cannot duplicate fd");
947 clexec_flag = fcntl (fd, F_GETFD, 0);
950 closer = make_redirection (new_fd, r_close_this, rd);
951 dummy_redirect = copy_redirects (closer);
955 new_redirect = make_redirection (fd, r_duplicating_input, rd);
957 new_redirect = make_redirection (fd, r_duplicating_output, rd);
958 new_redirect->next = closer;
960 closer->next = redirection_undo_list;
961 redirection_undo_list = new_redirect;
963 /* Save redirections that need to be undone even if the undo list
964 is thrown away by the `exec' builtin. */
965 add_exec_redirect (dummy_redirect);
967 /* File descriptors used only for saving others should always be
968 marked close-on-exec. Unfortunately, we have to preserve the
969 close-on-exec state of the file descriptor we are saving, since
970 fcntl (F_DUPFD) sets the new file descriptor to remain open
971 across execs. If, however, the file descriptor whose state we
972 are saving is <= 2, we can just set the close-on-exec flag,
973 because file descriptors 0-2 should always be open-on-exec,
974 and the restore above in do_redirection() will take care of it. */
975 if (clexec_flag || fd < 3)
976 SET_CLOSE_ON_EXEC (new_fd);
981 /* Set up to close FD when we are finished with the current command
982 and its redirections. */
984 add_undo_close_redirect (fd)
990 closer = make_redirection (fd, r_close_this, rd);
991 closer->next = redirection_undo_list;
992 redirection_undo_list = closer;
996 add_exec_redirect (dummy_redirect)
997 REDIRECT *dummy_redirect;
999 dummy_redirect->next = exec_redirection_undo_list;
1000 exec_redirection_undo_list = dummy_redirect;
1003 /* Return 1 if the redirection specified by RI and REDIRECTOR alters the
1006 stdin_redirection (ri, redirector)
1007 enum r_instruction ri;
1012 case r_input_direction:
1013 case r_inputa_direction:
1014 case r_input_output:
1015 case r_reading_until:
1016 case r_deblank_reading_until:
1017 case r_reading_string:
1019 case r_duplicating_input:
1020 case r_duplicating_input_word:
1022 return (redirector == 0);
1023 case r_output_direction:
1024 case r_appending_to:
1025 case r_duplicating_output:
1027 case r_output_force:
1028 case r_duplicating_output_word:
1034 /* Return non-zero if any of the redirections in REDIRS alter the standard
1037 stdin_redirects (redirs)
1043 for (n = 0, rp = redirs; rp; rp = rp->next)
1044 n += stdin_redirection (rp->instruction, rp->redirector);