Imported from ../bash-2.05b.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 #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 write_here_string __P((int, WORD_DESC *));
70 static int here_document_to_fd __P((WORD_DESC *, enum r_instruction));
71
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));
75
76 /* Spare redirector used when translating [N]>&WORD[-] or [N]<&WORD[-] to
77    a new redirection and when creating the redirection undo list. */
78 static REDIRECTEE rd;
79
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;
83
84 void
85 redirection_error (temp, error)
86      REDIRECT *temp;
87      int error;
88 {
89   char *filename, *allocname;
90   int oflags;
91
92   allocname = 0;
93   if (temp->redirector < 0)
94     /* This can happen when read_token_word encounters overflow, like in
95        exec 4294967297>x */
96     filename = "file descriptor out of range";
97 #ifdef EBADF
98   else if (temp->redirector >= 0 && errno == EBADF)
99     {
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)
104         {
105         case r_duplicating_input:
106         case r_duplicating_output:
107         case r_move_input:
108         case r_move_output:
109           filename = allocname = itos (temp->redirectee.dest);
110           break;
111         default:
112           filename = allocname = itos (temp->redirector);
113           break;
114         }
115     }
116 #endif
117   else if (expandable_redirection_filename (temp))
118     {
119       if (posixly_correct && interactive_shell == 0)
120         {
121           oflags = temp->redirectee.filename->flags;
122           temp->redirectee.filename->flags |= W_NOGLOB;
123         }
124       filename = allocname = redirection_expand (temp->redirectee.filename);
125       if (posixly_correct && interactive_shell == 0)
126         temp->redirectee.filename->flags = oflags;
127       if (filename == 0)
128         filename = temp->redirectee.filename->word;
129     }
130   else if (temp->redirectee.dest < 0)
131     filename = "file descriptor out of range";
132   else
133     filename = allocname = itos (temp->redirectee.dest);
134
135   switch (error)
136     {
137     case AMBIGUOUS_REDIRECT:
138       internal_error ("%s: ambiguous redirect", filename);
139       break;
140
141     case NOCLOBBER_REDIRECT:
142       internal_error ("%s: cannot overwrite existing file", filename);
143       break;
144
145 #if defined (RESTRICTED_SHELL)
146     case RESTRICTED_REDIRECT:
147       internal_error ("%s: restricted: cannot redirect output", filename);
148       break;
149 #endif /* RESTRICTED_SHELL */
150
151     case HEREDOC_REDIRECT:
152       internal_error ("cannot create temp file for here document: %s", strerror (heredoc_errno));
153       break;
154
155     default:
156       internal_error ("%s: %s", filename, strerror (error));
157       break;
158     }
159
160   FREE (allocname);
161 }
162
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
168    flag set. */
169 int
170 do_redirections (list, for_real, internal, set_clexec)
171      REDIRECT *list;
172      int for_real, internal, set_clexec;
173 {
174   int error;
175   REDIRECT *temp;
176
177   if (internal)
178     {
179       if (redirection_undo_list)
180         {
181           dispose_redirects (redirection_undo_list);
182           redirection_undo_list = (REDIRECT *)NULL;
183         }
184       if (exec_redirection_undo_list)
185         dispose_exec_redirects ();
186     }
187
188   for (temp = list; temp; temp = temp->next)
189     {
190       error = do_redirection_internal (temp, for_real, internal, set_clexec);
191       if (error)
192         {
193           redirection_error (temp, error);
194           return (error);
195         }
196     }
197   return (0);
198 }
199
200 /* Return non-zero if the redirection pointed to by REDIRECT has a
201    redirectee.filename that can be expanded. */
202 static int
203 expandable_redirection_filename (redirect)
204      REDIRECT *redirect;
205 {
206   switch (redirect->instruction)
207     {
208     case r_output_direction:
209     case r_appending_to:
210     case r_input_direction:
211     case r_inputa_direction:
212     case r_err_and_out:
213     case r_input_output:
214     case r_output_force:
215     case r_duplicating_input_word:
216     case r_duplicating_output_word:
217     case r_move_input_word:
218     case r_move_output_word:
219       return 1;
220
221     default:
222       return 0;
223     }
224 }
225
226 /* Expand the word in WORD returning a string.  If WORD expands to
227    multiple words (or no words), then return NULL. */
228 char *
229 redirection_expand (word)
230      WORD_DESC *word;
231 {
232   char *result;
233   WORD_LIST *tlist1, *tlist2;
234   WORD_DESC *w;
235
236   w = copy_word (word);
237   if (posixly_correct)
238     w->flags |= W_NOSPLIT;
239
240   tlist1 = make_word_list (w, (WORD_LIST *)NULL);
241   tlist2 = expand_words_no_vars (tlist1);
242   dispose_words (tlist1);
243
244   if (!tlist2 || tlist2->next)
245     {
246       /* We expanded to no words, or to more than a single word.
247          Dispose of the word list and return NULL. */
248       if (tlist2)
249         dispose_words (tlist2);
250       return ((char *)NULL);
251     }
252   result = string_list (tlist2);  /* XXX savestring (tlist2->word->word)? */
253   dispose_words (tlist2);
254   return (result);
255 }
256
257 static int
258 write_here_string (fd, redirectee)
259      int fd;
260      WORD_DESC *redirectee;
261 {
262   char *herestr;
263   int herelen, n, e;
264
265   herestr = expand_string_to_string (redirectee->word, 0);
266   herelen = strlen (herestr);
267
268   n = write (fd, herestr, herelen);
269   if (n == herelen)
270     {
271       n = write (fd, "\n", 1);
272       herelen = 1;
273     }
274   e = errno;
275   free (herestr);
276   if (n != herelen)
277     {
278       if (e == 0)
279         e = ENOSPC;
280       return e;
281     }
282   return 0;
283 }  
284
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. */
288 static int
289 write_here_document (fd, redirectee)
290      int fd;
291      WORD_DESC *redirectee;
292 {
293   char *document;
294   int document_len, fd2;
295   FILE *fp;
296   register WORD_LIST *t, *tlist;
297
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. */
301
302   if (redirectee->flags & W_QUOTED)
303     {
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)
308         {
309           if (errno == 0)
310             errno = ENOSPC;
311           return (errno);
312         }
313       else
314         return 0;
315     }
316
317   tlist = expand_string (redirectee->word, Q_HERE_DOCUMENT);
318   if (tlist)
319     {
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)
326         {
327           if (fd2 >= 0)
328             close (fd2);
329           return (errno);
330         }
331       errno = 0;
332       for (t = tlist; t; t = t->next)
333         {
334           /* This is essentially the body of
335              string_list_internal expanded inline. */
336           document = t->word->word;
337           document_len = strlen (document);
338           if (t != tlist)
339             putc (' ', fp);     /* separator */
340           fwrite (document, document_len, 1, fp);
341           if (ferror (fp))
342             {
343               if (errno == 0)
344                 errno = ENOSPC;
345               fd2 = errno;
346               fclose(fp);
347               dispose_words (tlist);
348               return (fd2);
349             }
350         }
351       dispose_words (tlist);
352       if (fclose (fp) != 0)
353         {
354           if (errno == 0)
355             errno = ENOSPC;
356           return (errno);
357         }
358     }
359   return 0;
360 }
361
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. */
365 static int
366 here_document_to_fd (redirectee, ri)
367      WORD_DESC *redirectee;
368      enum r_instruction ri;
369 {
370   char *filename;
371   int r, fd, fd2;
372
373   fd = sh_mktmpfd ("sh-thd", MT_USERANDOM, &filename);
374
375   /* If we failed for some reason other than the file existing, abort */
376   if (fd < 0)
377     {
378       FREE (filename);
379       return (fd);
380     }
381
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);
387
388   if (r)
389     {
390       close (fd);
391       unlink (filename);
392       free (filename);
393       errno = r;
394       return (-1);
395     }
396
397   /* In an attempt to avoid races, we close the first fd only after opening
398      the second. */
399   /* Make the document really temporary.  Also make it the input. */
400   fd2 = open (filename, O_RDONLY, 0600);
401
402   if (fd2 < 0)
403     {
404       r = errno;
405       unlink (filename);
406       free (filename);
407       close (fd);
408       errno = r;
409       return -1;
410     }
411
412   close (fd);
413   if (unlink (filename) < 0)
414     {
415       r = errno;
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. */
421       if (r == EACCES)
422         return (fd2);
423 #endif /* __CYGWIN__ */
424       close (fd2);
425       free (filename);
426       errno = r;
427       return (-1);
428     }
429
430   free (filename);
431   return (fd2);
432 }
433
434 #define RF_DEVFD        1
435 #define RF_DEVSTDERR    2
436 #define RF_DEVSTDIN     3
437 #define RF_DEVSTDOUT    4
438 #define RF_DEVTCP       5
439 #define RF_DEVUDP       6
440
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 },
446 #endif
447 #if !defined (HAVE_DEV_STDIN)
448   { "/dev/stderr", RF_DEVSTDERR },
449   { "/dev/stdin", RF_DEVSTDIN },
450   { "/dev/stdout", RF_DEVSTDOUT },
451 #endif
452 #if defined (NETWORK_REDIRECTIONS)
453   { "/dev/tcp/*/*", RF_DEVTCP },
454   { "/dev/udp/*/*", RF_DEVUDP },
455 #endif
456   { (char *)NULL, -1 }
457 };
458
459 static int
460 redir_special_open (spec, filename, flags, mode, ri)
461      int spec;
462      char *filename;
463      int flags, mode;
464      enum r_instruction ri;
465 {
466   int fd;
467 #if !defined (HAVE_DEV_FD)
468   intmax_t lfd;
469 #endif
470
471   fd = -1;
472   switch (spec)
473     {
474 #if !defined (HAVE_DEV_FD)
475     case RF_DEVFD:
476       if (all_digits (filename+8) && legal_number (filename+8, &lfd) && lfd == (int)lfd)
477         {
478           fd = lfd;
479           fd = fcntl (fd, F_DUPFD, 10);
480         }
481       else
482         fd = AMBIGUOUS_REDIRECT;
483       break;
484 #endif
485
486 #if !defined (HAVE_DEV_STDIN)
487     case RF_DEVSTDIN:
488       fd = fcntl (0, F_DUPFD, 10);
489       break;
490     case RF_DEVSTDOUT:
491       fd = fcntl (1, F_DUPFD, 10);
492       break;
493     case RF_DEVSTDERR:
494       fd = fcntl (2, F_DUPFD, 10);
495       break;
496 #endif
497
498 #if defined (NETWORK_REDIRECTIONS)
499     case RF_DEVTCP:
500     case RF_DEVUDP:
501 #if defined (HAVE_NETWORK)
502       fd = netopen (filename);
503 #else
504       internal_warning ("/dev/(tcp|udp)/host/port not supported without networking");
505       fd = open (filename, flags, mode);
506 #endif
507       break;
508 #endif /* NETWORK_REDIRECTIONS */
509     }
510
511   return fd;
512 }
513       
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). */
517 static int
518 noclobber_open (filename, flags, mode, ri)
519      char *filename;
520      int flags, mode;
521      enum r_instruction ri;
522 {
523   int r, fd;
524   struct stat finfo, finfo2;
525
526   /* If the file exists and is a regular file, return an error
527      immediately. */
528   r = stat (filename, &finfo);
529   if (r == 0 && (S_ISREG (finfo.st_mode)))
530     return (NOCLOBBER_REDIRECT);
531
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. */
537   flags &= ~O_TRUNC;
538   if (r != 0)
539     {
540       fd = open (filename, flags|O_EXCL, mode);
541       return ((fd < 0 && errno == EEXIST) ? NOCLOBBER_REDIRECT : fd);
542     }
543   fd = open (filename, flags, mode);
544
545   /* If the open failed, return the file descriptor right away. */
546   if (fd < 0)
547     return (errno == EEXIST ? NOCLOBBER_REDIRECT : fd);
548
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
553      and open. */
554
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))
561     return fd;
562
563   /* The file has been replaced.  badness. */
564   close (fd);  
565   errno = EEXIST;
566   return (NOCLOBBER_REDIRECT);
567 }
568
569 static int
570 redir_open (filename, flags, mode, ri)
571      char *filename;
572      int flags, mode;
573      enum r_instruction ri;
574 {
575   int fd, r;
576
577   r = find_string_in_alist (filename, _redir_special_filenames, 1);
578   if (r >= 0)
579     return (redir_special_open (r, filename, flags, mode, ri));
580
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))
584     {
585       fd = noclobber_open (filename, flags, mode, ri);
586       if (fd == NOCLOBBER_REDIRECT)
587         return (NOCLOBBER_REDIRECT);
588     }
589   else
590     {
591       fd = open (filename, flags, mode);
592 #if defined (AFS)
593       if ((fd < 0) && (errno == EACCES))
594         fd = open (filename, flags & ~O_CREAT, mode);
595 #endif /* AFS */
596     }
597
598   return fd;
599 }
600
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.  */
607 static int
608 do_redirection_internal (redirect, for_real, remembering, set_clexec)
609      REDIRECT *redirect;
610      int for_real, remembering, set_clexec;
611 {
612   WORD_DESC *redirectee;
613   int redir_fd, fd, redirector, r, oflags;
614   intmax_t lfd;
615   char *redirectee_word;
616   enum r_instruction ri;
617   REDIRECT *new_redirect;
618
619   redirectee = redirect->redirectee.filename;
620   redir_fd = redirect->redirectee.dest;
621   redirector = redirect->redirector;
622   ri = redirect->instruction;
623
624   if (TRANSLATE_REDIRECT (ri))
625     {
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);
629
630       /* XXX - what to do with [N]<&$w- where w is unset or null?  ksh93
631                closes N. */
632       if (redirectee_word == 0)
633         return (AMBIGUOUS_REDIRECT);
634       else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
635         {
636           rd.dest = 0;
637           new_redirect = make_redirection (redirector, r_close_this, rd);
638         }
639       else if (all_digits (redirectee_word))
640         {
641           if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
642             rd.dest = lfd;
643           else
644             rd.dest = -1;       /* XXX */
645           switch (ri)
646             {
647             case r_duplicating_input_word:
648               new_redirect = make_redirection (redirector, r_duplicating_input, rd);
649               break;
650             case r_duplicating_output_word:
651               new_redirect = make_redirection (redirector, r_duplicating_output, rd);
652               break;
653             case r_move_input_word:
654               new_redirect = make_redirection (redirector, r_move_input, rd);
655               break;
656             case r_move_output_word:
657               new_redirect = make_redirection (redirector, r_move_output, rd);
658               break;
659             }
660         }
661       else if (ri == r_duplicating_output_word && redirector == 1)
662         {
663           rd.filename = make_bare_word (redirectee_word);
664           new_redirect = make_redirection (1, r_err_and_out, rd);
665         }
666       else
667         {
668           free (redirectee_word);
669           return (AMBIGUOUS_REDIRECT);
670         }
671
672       free (redirectee_word);
673
674       /* Set up the variables needed by the rest of the function from the
675          new redirection. */
676       if (new_redirect->instruction == r_err_and_out)
677         {
678           char *alloca_hack;
679
680           /* Copy the word without allocating any memory that must be
681              explicitly freed. */
682           redirectee = (WORD_DESC *)alloca (sizeof (WORD_DESC));
683           xbcopy ((char *)new_redirect->redirectee.filename,
684                  (char *)redirectee, sizeof (WORD_DESC));
685
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);
690         }
691       else
692         /* It's guaranteed to be an integer, and shouldn't be freed. */
693         redirectee = new_redirect->redirectee.filename;
694
695       redir_fd = new_redirect->redirectee.dest;
696       redirector = new_redirect->redirector;
697       ri = new_redirect->instruction;
698
699       /* Overwrite the flags element of the old redirect with the new value. */
700       redirect->flags = new_redirect->flags;
701       dispose_redirects (new_redirect);
702     }
703
704   switch (ri)
705     {
706     case r_output_direction:
707     case r_appending_to:
708     case r_input_direction:
709     case r_inputa_direction:
710     case r_err_and_out:         /* command &>filename */
711     case r_input_output:
712     case r_output_force:
713       if (posixly_correct && interactive_shell == 0)
714         {
715           oflags = redirectee->flags;
716           redirectee->flags |= W_NOGLOB;
717         }
718       redirectee_word = redirection_expand (redirectee);
719       if (posixly_correct && interactive_shell == 0)
720         redirectee->flags = oflags;
721
722       if (redirectee_word == 0)
723         return (AMBIGUOUS_REDIRECT);
724
725 #if defined (RESTRICTED_SHELL)
726       if (restricted && (WRITE_REDIRECT (ri)))
727         {
728           free (redirectee_word);
729           return (RESTRICTED_REDIRECT);
730         }
731 #endif /* RESTRICTED_SHELL */
732
733       fd = redir_open (redirectee_word, redirect->flags, 0666, ri);
734       free (redirectee_word);
735
736       if (fd == NOCLOBBER_REDIRECT)
737         return (fd);
738
739       if (fd < 0)
740         return (errno);
741
742       if (for_real)
743         {
744           if (remembering)
745             {
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);
749               else
750                 add_undo_close_redirect (redirector);
751             }
752
753 #if defined (BUFFERED_INPUT)
754           check_bash_input (redirector);
755 #endif
756
757           if ((fd != redirector) && (dup2 (fd, redirector) < 0))
758             return (errno);
759
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 */
767
768           /*
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.
777            */
778           if (set_clexec && (redirector > 2))
779             SET_CLOSE_ON_EXEC (redirector);
780         }
781
782       if (fd != redirector)
783         {
784 #if defined (BUFFERED_INPUT)
785           if (INPUT_REDIRECT (ri))
786             close_buffered_fd (fd);
787           else
788 #endif /* !BUFFERED_INPUT */
789             close (fd);         /* Don't close what we just opened! */
790         }
791
792       /* If we are hacking both stdout and stderr, do the stderr
793          redirection here. */
794       if (ri == r_err_and_out)
795         {
796           if (for_real)
797             {
798               if (remembering)
799                 add_undo_redirect (2);
800               if (dup2 (1, 2) < 0)
801                 return (errno);
802             }
803         }
804       break;
805
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. */
811       if (redirectee)
812         {
813           fd = here_document_to_fd (redirectee, ri);
814
815           if (fd < 0)
816             {
817               heredoc_errno = errno;
818               return (HEREDOC_REDIRECT);
819             }
820
821           if (for_real)
822             {
823               if (remembering)
824                 {
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);
828                   else
829                     add_undo_close_redirect (redirector);
830                 }
831
832 #if defined (BUFFERED_INPUT)
833               check_bash_input (redirector);
834 #endif
835               if (fd != redirector && dup2 (fd, redirector) < 0)
836                 {
837                   r = errno;
838                   close (fd);
839                   return (r);
840                 }
841
842 #if defined (BUFFERED_INPUT)
843               duplicate_buffered_stream (fd, redirector);
844 #endif
845
846               if (set_clexec && (redirector > 2))
847                 SET_CLOSE_ON_EXEC (redirector);
848             }
849
850           if (fd != redirector)
851 #if defined (BUFFERED_INPUT)
852             close_buffered_fd (fd);
853 #else
854             close (fd);
855 #endif
856         }
857       break;
858
859     case r_duplicating_input:
860     case r_duplicating_output:
861     case r_move_input:
862     case r_move_output:
863       if (for_real && (redir_fd != redirector))
864         {
865           if (remembering)
866             {
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);
870               else
871                 add_undo_close_redirect (redirector);
872             }
873
874 #if defined (BUFFERED_INPUT)
875           check_bash_input (redirector);
876 #endif
877           /* This is correct.  2>&1 means dup2 (1, 2); */
878           if (dup2 (redir_fd, redirector) < 0)
879             return (errno);
880
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 */
885
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))
892                 set_it () */
893           if (((fcntl (redir_fd, F_GETFD, 0) == 1) || set_clexec) &&
894                (redirector > 2))
895             SET_CLOSE_ON_EXEC (redirector);
896
897           /* dup-and-close redirection */
898           if (ri == r_move_input || ri == r_move_output)
899             close (redir_fd);
900         }
901       break;
902
903     case r_close_this:
904       if (for_real)
905         {
906           if (remembering && (fcntl (redirector, F_GETFD, 0) != -1))
907             add_undo_redirect (redirector);
908
909 #if defined (BUFFERED_INPUT)
910           check_bash_input (redirector);
911           close_buffered_fd (redirector);
912 #else /* !BUFFERED_INPUT */
913           close (redirector);
914 #endif /* !BUFFERED_INPUT */
915         }
916       break;
917
918     case r_duplicating_input_word:
919     case r_duplicating_output_word:
920       break;
921     }
922   return (0);
923 }
924
925 #define SHELL_FD_BASE   10
926
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. */
932 static int
933 add_undo_redirect (fd)
934      int fd;
935 {
936   int new_fd, clexec_flag;
937   REDIRECT *new_redirect, *closer, *dummy_redirect;
938
939   new_fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
940
941   if (new_fd < 0)
942     {
943       sys_error ("redirection error: cannot duplicate fd");
944       return (-1);
945     }
946
947   clexec_flag = fcntl (fd, F_GETFD, 0);
948
949   rd.dest = 0;
950   closer = make_redirection (new_fd, r_close_this, rd);
951   dummy_redirect = copy_redirects (closer);
952
953   rd.dest = new_fd;
954   if (fd == 0)
955     new_redirect = make_redirection (fd, r_duplicating_input, rd);
956   else
957     new_redirect = make_redirection (fd, r_duplicating_output, rd);
958   new_redirect->next = closer;
959
960   closer->next = redirection_undo_list;
961   redirection_undo_list = new_redirect;
962
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);
966
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);
977
978   return (0);
979 }
980
981 /* Set up to close FD when we are finished with the current command
982    and its redirections. */
983 static void
984 add_undo_close_redirect (fd)
985      int fd;
986 {
987   REDIRECT *closer;
988
989   rd.dest = 0;
990   closer = make_redirection (fd, r_close_this, rd);
991   closer->next = redirection_undo_list;
992   redirection_undo_list = closer;
993 }
994
995 static void
996 add_exec_redirect (dummy_redirect)
997      REDIRECT *dummy_redirect;
998 {
999   dummy_redirect->next = exec_redirection_undo_list;
1000   exec_redirection_undo_list = dummy_redirect;
1001 }
1002
1003 /* Return 1 if the redirection specified by RI and REDIRECTOR alters the
1004    standard input. */
1005 static int
1006 stdin_redirection (ri, redirector)
1007      enum r_instruction ri;
1008      int redirector;
1009 {
1010   switch (ri)
1011     {
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:
1018       return (1);
1019     case r_duplicating_input:
1020     case r_duplicating_input_word:
1021     case r_close_this:
1022       return (redirector == 0);
1023     case r_output_direction:
1024     case r_appending_to:
1025     case r_duplicating_output:
1026     case r_err_and_out:
1027     case r_output_force:
1028     case r_duplicating_output_word:
1029       return (0);
1030     }
1031   return (0);
1032 }
1033
1034 /* Return non-zero if any of the redirections in REDIRS alter the standard
1035    input. */
1036 int
1037 stdin_redirects (redirs)
1038      REDIRECT *redirs;
1039 {
1040   REDIRECT *rp;
1041   int n;
1042
1043   for (n = 0, rp = redirs; rp; rp = rp->next)
1044     n += stdin_redirection (rp->instruction, rp->redirector);
1045   return n;
1046 }