Imported from ../bash-3.0.tar.gz.
[platform/upstream/bash.git] / redir.c
1 /* redir.c -- Functions to perform input and output redirection. */
2
3 /* Copyright (C) 1997-2002 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)
41 extern 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
57 int expanding_redir;
58
59 extern int posixly_correct;
60 extern REDIRECT *redirection_undo_list;
61 extern REDIRECT *exec_redirection_undo_list;
62
63 /* Static functions defined and used in this file. */
64 static void add_undo_close_redirect __P((int));
65 static void add_exec_redirect __P((REDIRECT *));
66 static int add_undo_redirect __P((int));
67 static int expandable_redirection_filename __P((REDIRECT *));
68 static int stdin_redirection __P((enum r_instruction, int));
69 static int do_redirection_internal __P((REDIRECT *, int));
70
71 static int write_here_document __P((int, WORD_DESC *));
72 static int write_here_string __P((int, WORD_DESC *));
73 static int here_document_to_fd __P((WORD_DESC *, enum r_instruction));
74
75 static int redir_special_open __P((int, char *, int, int, enum r_instruction));
76 static int noclobber_open __P((char *, int, int, enum r_instruction));
77 static 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. */
81 static 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. */
85 static int heredoc_errno;
86
87 void
88 redirection_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. */
172 int
173 do_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. */
205 static int
206 expandable_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. */
231 char *
232 redirection_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
262 static int
263 write_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. */
293 static int
294 write_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. */
370 static int
371 here_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. */
448 static 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
464 static int
465 redir_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). */
522 static int
523 noclobber_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
574 static int
575 redir_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         fd = open (filename, flags & ~O_CREAT, mode);
600 #endif /* AFS */
601     }
602
603   return fd;
604 }
605
606 /* Do the specific redirection requested.  Returns errno or one of the
607    special redirection errors (*_REDIRECT) in case of error, 0 on success.
608    If flags & RX_ACTIVE is zero, then just do whatever is neccessary to
609    produce the appropriate side effects.   flags & RX_UNDOABLE, if non-zero,
610    says to remember how to undo each redirection.  If flags & RX_CLEXEC is
611    non-zero, then we set all file descriptors > 2 that we open to be
612    close-on-exec.  */
613 static int
614 do_redirection_internal (redirect, flags)
615      REDIRECT *redirect;
616      int flags;
617 {
618   WORD_DESC *redirectee;
619   int redir_fd, fd, redirector, r, oflags;
620   intmax_t lfd;
621   char *redirectee_word;
622   enum r_instruction ri;
623   REDIRECT *new_redirect;
624
625   redirectee = redirect->redirectee.filename;
626   redir_fd = redirect->redirectee.dest;
627   redirector = redirect->redirector;
628   ri = redirect->instruction;
629
630   if (TRANSLATE_REDIRECT (ri))
631     {
632       /* We have [N]>&WORD[-] or [N]<&WORD[-].  Expand WORD, then translate
633          the redirection into a new one and continue. */
634       redirectee_word = redirection_expand (redirectee);
635
636       /* XXX - what to do with [N]<&$w- where w is unset or null?  ksh93
637                closes N. */
638       if (redirectee_word == 0)
639         return (AMBIGUOUS_REDIRECT);
640       else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
641         {
642           rd.dest = 0;
643           new_redirect = make_redirection (redirector, r_close_this, rd);
644         }
645       else if (all_digits (redirectee_word))
646         {
647           if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
648             rd.dest = lfd;
649           else
650             rd.dest = -1;       /* XXX */
651           switch (ri)
652             {
653             case r_duplicating_input_word:
654               new_redirect = make_redirection (redirector, r_duplicating_input, rd);
655               break;
656             case r_duplicating_output_word:
657               new_redirect = make_redirection (redirector, r_duplicating_output, rd);
658               break;
659             case r_move_input_word:
660               new_redirect = make_redirection (redirector, r_move_input, rd);
661               break;
662             case r_move_output_word:
663               new_redirect = make_redirection (redirector, r_move_output, rd);
664               break;
665             }
666         }
667       else if (ri == r_duplicating_output_word && redirector == 1)
668         {
669           rd.filename = make_bare_word (redirectee_word);
670           new_redirect = make_redirection (1, r_err_and_out, rd);
671         }
672       else
673         {
674           free (redirectee_word);
675           return (AMBIGUOUS_REDIRECT);
676         }
677
678       free (redirectee_word);
679
680       /* Set up the variables needed by the rest of the function from the
681          new redirection. */
682       if (new_redirect->instruction == r_err_and_out)
683         {
684           char *alloca_hack;
685
686           /* Copy the word without allocating any memory that must be
687              explicitly freed. */
688           redirectee = (WORD_DESC *)alloca (sizeof (WORD_DESC));
689           xbcopy ((char *)new_redirect->redirectee.filename,
690                  (char *)redirectee, sizeof (WORD_DESC));
691
692           alloca_hack = (char *)
693             alloca (1 + strlen (new_redirect->redirectee.filename->word));
694           redirectee->word = alloca_hack;
695           strcpy (redirectee->word, new_redirect->redirectee.filename->word);
696         }
697       else
698         /* It's guaranteed to be an integer, and shouldn't be freed. */
699         redirectee = new_redirect->redirectee.filename;
700
701       redir_fd = new_redirect->redirectee.dest;
702       redirector = new_redirect->redirector;
703       ri = new_redirect->instruction;
704
705       /* Overwrite the flags element of the old redirect with the new value. */
706       redirect->flags = new_redirect->flags;
707       dispose_redirects (new_redirect);
708     }
709
710   switch (ri)
711     {
712     case r_output_direction:
713     case r_appending_to:
714     case r_input_direction:
715     case r_inputa_direction:
716     case r_err_and_out:         /* command &>filename */
717     case r_input_output:
718     case r_output_force:
719       if (posixly_correct && interactive_shell == 0)
720         {
721           oflags = redirectee->flags;
722           redirectee->flags |= W_NOGLOB;
723         }
724       redirectee_word = redirection_expand (redirectee);
725       if (posixly_correct && interactive_shell == 0)
726         redirectee->flags = oflags;
727
728       if (redirectee_word == 0)
729         return (AMBIGUOUS_REDIRECT);
730
731 #if defined (RESTRICTED_SHELL)
732       if (restricted && (WRITE_REDIRECT (ri)))
733         {
734           free (redirectee_word);
735           return (RESTRICTED_REDIRECT);
736         }
737 #endif /* RESTRICTED_SHELL */
738
739       fd = redir_open (redirectee_word, redirect->flags, 0666, ri);
740       free (redirectee_word);
741
742       if (fd == NOCLOBBER_REDIRECT)
743         return (fd);
744
745       if (fd < 0)
746         return (errno);
747
748       if (flags & RX_ACTIVE)
749         {
750           if (flags & RX_UNDOABLE)
751             {
752               /* Only setup to undo it if the thing to undo is active. */
753               if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
754                 add_undo_redirect (redirector);
755               else
756                 add_undo_close_redirect (redirector);
757             }
758
759 #if defined (BUFFERED_INPUT)
760           check_bash_input (redirector);
761 #endif
762
763           if ((fd != redirector) && (dup2 (fd, redirector) < 0))
764             return (errno);
765
766 #if defined (BUFFERED_INPUT)
767           /* Do not change the buffered stream for an implicit redirection
768              of /dev/null to fd 0 for asynchronous commands without job
769              control (r_inputa_direction). */
770           if (ri == r_input_direction || ri == r_input_output)
771             duplicate_buffered_stream (fd, redirector);
772 #endif /* BUFFERED_INPUT */
773
774           /*
775            * If we're remembering, then this is the result of a while, for
776            * or until loop with a loop redirection, or a function/builtin
777            * executing in the parent shell with a redirection.  In the
778            * function/builtin case, we want to set all file descriptors > 2
779            * to be close-on-exec to duplicate the effect of the old
780            * for i = 3 to NOFILE close(i) loop.  In the case of the loops,
781            * both sh and ksh leave the file descriptors open across execs.
782            * The Posix standard mentions only the exec builtin.
783            */
784           if ((flags & RX_CLEXEC) && (redirector > 2))
785             SET_CLOSE_ON_EXEC (redirector);
786         }
787
788       if (fd != redirector)
789         {
790 #if defined (BUFFERED_INPUT)
791           if (INPUT_REDIRECT (ri))
792             close_buffered_fd (fd);
793           else
794 #endif /* !BUFFERED_INPUT */
795             close (fd);         /* Don't close what we just opened! */
796         }
797
798       /* If we are hacking both stdout and stderr, do the stderr
799          redirection here. */
800       if (ri == r_err_and_out)
801         {
802           if (flags & RX_ACTIVE)
803             {
804               if (flags & RX_UNDOABLE)
805                 add_undo_redirect (2);
806               if (dup2 (1, 2) < 0)
807                 return (errno);
808             }
809         }
810       break;
811
812     case r_reading_until:
813     case r_deblank_reading_until:
814     case r_reading_string:
815       /* REDIRECTEE is a pointer to a WORD_DESC containing the text of
816          the new input.  Place it in a temporary file. */
817       if (redirectee)
818         {
819           fd = here_document_to_fd (redirectee, ri);
820
821           if (fd < 0)
822             {
823               heredoc_errno = errno;
824               return (HEREDOC_REDIRECT);
825             }
826
827           if (flags & RX_ACTIVE)
828             {
829               if (flags & RX_UNDOABLE)
830                 {
831                   /* Only setup to undo it if the thing to undo is active. */
832                   if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
833                     add_undo_redirect (redirector);
834                   else
835                     add_undo_close_redirect (redirector);
836                 }
837
838 #if defined (BUFFERED_INPUT)
839               check_bash_input (redirector);
840 #endif
841               if (fd != redirector && dup2 (fd, redirector) < 0)
842                 {
843                   r = errno;
844                   close (fd);
845                   return (r);
846                 }
847
848 #if defined (BUFFERED_INPUT)
849               duplicate_buffered_stream (fd, redirector);
850 #endif
851
852               if ((flags & RX_CLEXEC) && (redirector > 2))
853                 SET_CLOSE_ON_EXEC (redirector);
854             }
855
856           if (fd != redirector)
857 #if defined (BUFFERED_INPUT)
858             close_buffered_fd (fd);
859 #else
860             close (fd);
861 #endif
862         }
863       break;
864
865     case r_duplicating_input:
866     case r_duplicating_output:
867     case r_move_input:
868     case r_move_output:
869       if ((flags & RX_ACTIVE) && (redir_fd != redirector))
870         {
871           if (flags & RX_UNDOABLE)
872             {
873               /* Only setup to undo it if the thing to undo is active. */
874               if (fcntl (redirector, F_GETFD, 0) != -1)
875                 add_undo_redirect (redirector);
876               else
877                 add_undo_close_redirect (redirector);
878             }
879
880 #if defined (BUFFERED_INPUT)
881           check_bash_input (redirector);
882 #endif
883           /* This is correct.  2>&1 means dup2 (1, 2); */
884           if (dup2 (redir_fd, redirector) < 0)
885             return (errno);
886
887 #if defined (BUFFERED_INPUT)
888           if (ri == r_duplicating_input || ri == r_move_input)
889             duplicate_buffered_stream (redir_fd, redirector);
890 #endif /* BUFFERED_INPUT */
891
892           /* First duplicate the close-on-exec state of redirectee.  dup2
893              leaves the flag unset on the new descriptor, which means it
894              stays open.  Only set the close-on-exec bit for file descriptors
895              greater than 2 in any case, since 0-2 should always be open
896              unless closed by something like `exec 2<&-'. */
897           /* if ((already_set || set_unconditionally) && (ok_to_set))
898                 set_it () */
899           if (((fcntl (redir_fd, F_GETFD, 0) == 1) || (flags & RX_CLEXEC)) &&
900                (redirector > 2))
901             SET_CLOSE_ON_EXEC (redirector);
902
903           /* dup-and-close redirection */
904           if (ri == r_move_input || ri == r_move_output)
905             close (redir_fd);
906         }
907       break;
908
909     case r_close_this:
910       if (flags & RX_ACTIVE)
911         {
912           if ((flags & RX_UNDOABLE) && (fcntl (redirector, F_GETFD, 0) != -1))
913             add_undo_redirect (redirector);
914
915 #if defined (BUFFERED_INPUT)
916           check_bash_input (redirector);
917           close_buffered_fd (redirector);
918 #else /* !BUFFERED_INPUT */
919           close (redirector);
920 #endif /* !BUFFERED_INPUT */
921         }
922       break;
923
924     case r_duplicating_input_word:
925     case r_duplicating_output_word:
926       break;
927     }
928   return (0);
929 }
930
931 #define SHELL_FD_BASE   10
932
933 /* Remember the file descriptor associated with the slot FD,
934    on REDIRECTION_UNDO_LIST.  Note that the list will be reversed
935    before it is executed.  Any redirections that need to be undone
936    even if REDIRECTION_UNDO_LIST is discarded by the exec builtin
937    are also saved on EXEC_REDIRECTION_UNDO_LIST. */
938 static int
939 add_undo_redirect (fd)
940      int fd;
941 {
942   int new_fd, clexec_flag;
943   REDIRECT *new_redirect, *closer, *dummy_redirect;
944
945   new_fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
946
947   if (new_fd < 0)
948     {
949       sys_error (_("redirection error: cannot duplicate fd"));
950       return (-1);
951     }
952
953   clexec_flag = fcntl (fd, F_GETFD, 0);
954
955   rd.dest = 0;
956   closer = make_redirection (new_fd, r_close_this, rd);
957   dummy_redirect = copy_redirects (closer);
958
959   rd.dest = new_fd;
960   if (fd == 0)
961     new_redirect = make_redirection (fd, r_duplicating_input, rd);
962   else
963     new_redirect = make_redirection (fd, r_duplicating_output, rd);
964   new_redirect->next = closer;
965
966   closer->next = redirection_undo_list;
967   redirection_undo_list = new_redirect;
968
969   /* Save redirections that need to be undone even if the undo list
970      is thrown away by the `exec' builtin. */
971   add_exec_redirect (dummy_redirect);
972
973   /* File descriptors used only for saving others should always be
974      marked close-on-exec.  Unfortunately, we have to preserve the
975      close-on-exec state of the file descriptor we are saving, since
976      fcntl (F_DUPFD) sets the new file descriptor to remain open
977      across execs.  If, however, the file descriptor whose state we
978      are saving is <= 2, we can just set the close-on-exec flag,
979      because file descriptors 0-2 should always be open-on-exec,
980      and the restore above in do_redirection() will take care of it. */
981   if (clexec_flag || fd < 3)
982     SET_CLOSE_ON_EXEC (new_fd);
983
984   return (0);
985 }
986
987 /* Set up to close FD when we are finished with the current command
988    and its redirections. */
989 static void
990 add_undo_close_redirect (fd)
991      int fd;
992 {
993   REDIRECT *closer;
994
995   rd.dest = 0;
996   closer = make_redirection (fd, r_close_this, rd);
997   closer->next = redirection_undo_list;
998   redirection_undo_list = closer;
999 }
1000
1001 static void
1002 add_exec_redirect (dummy_redirect)
1003      REDIRECT *dummy_redirect;
1004 {
1005   dummy_redirect->next = exec_redirection_undo_list;
1006   exec_redirection_undo_list = dummy_redirect;
1007 }
1008
1009 /* Return 1 if the redirection specified by RI and REDIRECTOR alters the
1010    standard input. */
1011 static int
1012 stdin_redirection (ri, redirector)
1013      enum r_instruction ri;
1014      int redirector;
1015 {
1016   switch (ri)
1017     {
1018     case r_input_direction:
1019     case r_inputa_direction:
1020     case r_input_output:
1021     case r_reading_until:
1022     case r_deblank_reading_until:
1023     case r_reading_string:
1024       return (1);
1025     case r_duplicating_input:
1026     case r_duplicating_input_word:
1027     case r_close_this:
1028       return (redirector == 0);
1029     case r_output_direction:
1030     case r_appending_to:
1031     case r_duplicating_output:
1032     case r_err_and_out:
1033     case r_output_force:
1034     case r_duplicating_output_word:
1035       return (0);
1036     }
1037   return (0);
1038 }
1039
1040 /* Return non-zero if any of the redirections in REDIRS alter the standard
1041    input. */
1042 int
1043 stdin_redirects (redirs)
1044      REDIRECT *redirs;
1045 {
1046   REDIRECT *rp;
1047   int n;
1048
1049   for (n = 0, rp = redirs; rp; rp = rp->next)
1050     n += stdin_redirection (rp->instruction, rp->redirector);
1051   return n;
1052 }