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