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