02e477d77647b197669103b614fc024bd6e35d36
[platform/upstream/bash.git] / redir.c
1 /* redir.c -- Functions to perform input and output redirection. */
2
3 /* Copyright (C) 1997-2009 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
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    Bash is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
24   #pragma alloca
25 #endif /* _AIX && RISC6000 && !__GNUC__ */
26
27 #include <stdio.h>
28 #include "bashtypes.h"
29 #if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
30 #  include <sys/file.h>
31 #endif
32 #include "filecntl.h"
33 #include "posixstat.h"
34
35 #if defined (HAVE_UNISTD_H)
36 #  include <unistd.h>
37 #endif
38
39 #include <errno.h>
40
41 #if !defined (errno)
42 extern int errno;
43 #endif
44
45 #include "bashansi.h"
46 #include "bashintl.h"
47 #include "memalloc.h"
48
49 #define NEED_FPURGE_DECL
50
51 #include "shell.h"
52 #include "flags.h"
53 #include "execute_cmd.h"
54 #include "redir.h"
55
56 #if defined (BUFFERED_INPUT)
57 #  include "input.h"
58 #endif
59
60 #define SHELL_FD_BASE   10
61
62 int expanding_redir;
63
64 extern int posixly_correct;
65 extern int last_command_exit_value;
66 extern REDIRECT *redirection_undo_list;
67 extern REDIRECT *exec_redirection_undo_list;
68
69 /* Static functions defined and used in this file. */
70 static void add_exec_redirect __P((REDIRECT *));
71 static int add_undo_redirect __P((int, enum r_instruction, int));
72 static int add_undo_close_redirect __P((int));
73 static int expandable_redirection_filename __P((REDIRECT *));
74 static int stdin_redirection __P((enum r_instruction, int));
75 static int undoablefd __P((int));
76 static int do_redirection_internal __P((REDIRECT *, int));
77
78 static int write_here_document __P((int, WORD_DESC *));
79 static int write_here_string __P((int, WORD_DESC *));
80 static int here_document_to_fd __P((WORD_DESC *, enum r_instruction));
81
82 static int redir_special_open __P((int, char *, int, int, enum r_instruction));
83 static int noclobber_open __P((char *, int, int, enum r_instruction));
84 static int redir_open __P((char *, int, int, enum r_instruction));
85
86 static int redir_varassign __P((REDIRECT *, int));
87 static int redir_varvalue __P((REDIRECT *));
88
89 /* Spare redirector used when translating [N]>&WORD[-] or [N]<&WORD[-] to
90    a new redirection and when creating the redirection undo list. */
91 static REDIRECTEE rd;
92
93 /* Set to errno when a here document cannot be created for some reason.
94    Used to print a reasonable error message. */
95 static int heredoc_errno;
96
97 #define REDIRECTION_ERROR(r, e, fd) \
98 do { \
99   if ((r) < 0) \
100     { \
101       if (fd >= 0) \
102         close (fd); \
103       last_command_exit_value = EXECUTION_FAILURE;\
104       return ((e) == 0 ? EINVAL : (e));\
105     } \
106 } while (0)
107
108 void
109 redirection_error (temp, error)
110      REDIRECT *temp;
111      int error;
112 {
113   char *filename, *allocname;
114   int oflags;
115
116   allocname = 0;
117   if (temp->rflags & REDIR_VARASSIGN)
118     filename = savestring (temp->redirector.filename->word);
119   else if (temp->redirector.dest < 0)
120     /* This can happen when read_token_word encounters overflow, like in
121        exec 4294967297>x */
122     filename = _("file descriptor out of range");
123 #ifdef EBADF
124   /* This error can never involve NOCLOBBER */
125   else if (error != NOCLOBBER_REDIRECT && temp->redirector.dest >= 0 && error == EBADF)
126     {
127       /* If we're dealing with two file descriptors, we have to guess about
128          which one is invalid; in the cases of r_{duplicating,move}_input and
129          r_{duplicating,move}_output we're here because dup2() failed. */
130       switch (temp->instruction)
131         {
132         case r_duplicating_input:
133         case r_duplicating_output:
134         case r_move_input:
135         case r_move_output:
136           filename = allocname = itos (temp->redirectee.dest);
137           break;
138         case r_duplicating_input_word:
139           if (temp->redirector.dest == 0)       /* Guess */
140             filename = temp->redirectee.filename->word; /* XXX */
141           else
142             filename = allocname = itos (temp->redirector.dest);
143           break;
144         case r_duplicating_output_word:
145           if (temp->redirector.dest == 1)       /* Guess */
146             filename = temp->redirectee.filename->word; /* XXX */
147           else
148             filename = allocname = itos (temp->redirector.dest);
149           break;
150         default:
151           filename = allocname = itos (temp->redirector.dest);
152           break;
153         }
154     }
155 #endif
156   else if (expandable_redirection_filename (temp))
157     {
158 expandable_filename:
159       if (posixly_correct && interactive_shell == 0)
160         {
161           oflags = temp->redirectee.filename->flags;
162           temp->redirectee.filename->flags |= W_NOGLOB;
163         }
164       filename = allocname = redirection_expand (temp->redirectee.filename);
165       if (posixly_correct && interactive_shell == 0)
166         temp->redirectee.filename->flags = oflags;
167       if (filename == 0)
168         filename = temp->redirectee.filename->word;
169     }
170   else if (temp->redirectee.dest < 0)
171     filename = "file descriptor out of range";
172   else
173     filename = allocname = itos (temp->redirectee.dest);
174
175   switch (error)
176     {
177     case AMBIGUOUS_REDIRECT:
178       internal_error (_("%s: ambiguous redirect"), filename);
179       break;
180
181     case NOCLOBBER_REDIRECT:
182       internal_error (_("%s: cannot overwrite existing file"), filename);
183       break;
184
185 #if defined (RESTRICTED_SHELL)
186     case RESTRICTED_REDIRECT:
187       internal_error (_("%s: restricted: cannot redirect output"), filename);
188       break;
189 #endif /* RESTRICTED_SHELL */
190
191     case HEREDOC_REDIRECT:
192       internal_error (_("cannot create temp file for here-document: %s"), strerror (heredoc_errno));
193       break;
194
195     case BADVAR_REDIRECT:
196       internal_error (_("%s: cannot assign fd to variable"), filename);
197       break;
198
199     default:
200       internal_error ("%s: %s", filename, strerror (error));
201       break;
202     }
203
204   FREE (allocname);
205 }
206
207 /* Perform the redirections on LIST.  If flags & RX_ACTIVE, then actually
208    make input and output file descriptors, otherwise just do whatever is
209    neccessary for side effecting.  flags & RX_UNDOABLE says to remember
210    how to undo the redirections later, if non-zero.  If flags & RX_CLEXEC
211    is non-zero, file descriptors opened in do_redirection () have their
212    close-on-exec flag set. */
213 int
214 do_redirections (list, flags)
215      REDIRECT *list;
216      int flags;
217 {
218   int error;
219   REDIRECT *temp;
220
221   if (flags & RX_UNDOABLE)
222     {
223       if (redirection_undo_list)
224         {
225           dispose_redirects (redirection_undo_list);
226           redirection_undo_list = (REDIRECT *)NULL;
227         }
228       if (exec_redirection_undo_list)
229         dispose_exec_redirects ();
230     }
231
232   for (temp = list; temp; temp = temp->next)
233     {
234       error = do_redirection_internal (temp, flags);
235       if (error)
236         {
237           redirection_error (temp, error);
238           return (error);
239         }
240     }
241   return (0);
242 }
243
244 /* Return non-zero if the redirection pointed to by REDIRECT has a
245    redirectee.filename that can be expanded. */
246 static int
247 expandable_redirection_filename (redirect)
248      REDIRECT *redirect;
249 {
250   switch (redirect->instruction)
251     {
252     case r_output_direction:
253     case r_appending_to:
254     case r_input_direction:
255     case r_inputa_direction:
256     case r_err_and_out:
257     case r_append_err_and_out:
258     case r_input_output:
259     case r_output_force:
260     case r_duplicating_input_word:
261     case r_duplicating_output_word:
262     case r_move_input_word:
263     case r_move_output_word:
264       return 1;
265
266     default:
267       return 0;
268     }
269 }
270
271 /* Expand the word in WORD returning a string.  If WORD expands to
272    multiple words (or no words), then return NULL. */
273 char *
274 redirection_expand (word)
275      WORD_DESC *word;
276 {
277   char *result;
278   WORD_LIST *tlist1, *tlist2;
279   WORD_DESC *w;
280
281   w = copy_word (word);
282   if (posixly_correct)
283     w->flags |= W_NOSPLIT;
284
285   tlist1 = make_word_list (w, (WORD_LIST *)NULL);
286   expanding_redir = 1;
287   tlist2 = expand_words_no_vars (tlist1);
288   expanding_redir = 0;
289   dispose_words (tlist1);
290
291   if (!tlist2 || tlist2->next)
292     {
293       /* We expanded to no words, or to more than a single word.
294          Dispose of the word list and return NULL. */
295       if (tlist2)
296         dispose_words (tlist2);
297       return ((char *)NULL);
298     }
299   result = string_list (tlist2);  /* XXX savestring (tlist2->word->word)? */
300   dispose_words (tlist2);
301   return (result);
302 }
303
304 static int
305 write_here_string (fd, redirectee)
306      int fd;
307      WORD_DESC *redirectee;
308 {
309   char *herestr;
310   int herelen, n, e;
311
312   expanding_redir = 1;
313   herestr = expand_string_to_string (redirectee->word, 0);
314   expanding_redir = 0;
315   herelen = STRLEN (herestr);
316
317   n = write (fd, herestr, herelen);
318   if (n == herelen)
319     {
320       n = write (fd, "\n", 1);
321       herelen = 1;
322     }
323   e = errno;
324   FREE (herestr);
325   if (n != herelen)
326     {
327       if (e == 0)
328         e = ENOSPC;
329       return e;
330     }
331   return 0;
332 }  
333
334 /* Write the text of the here document pointed to by REDIRECTEE to the file
335    descriptor FD, which is already open to a temp file.  Return 0 if the
336    write is successful, otherwise return errno. */
337 static int
338 write_here_document (fd, redirectee)
339      int fd;
340      WORD_DESC *redirectee;
341 {
342   char *document;
343   int document_len, fd2;
344   FILE *fp;
345   register WORD_LIST *t, *tlist;
346
347   /* Expand the text if the word that was specified had
348      no quoting.  The text that we expand is treated
349      exactly as if it were surrounded by double quotes. */
350
351   if (redirectee->flags & W_QUOTED)
352     {
353       document = redirectee->word;
354       document_len = strlen (document);
355       /* Set errno to something reasonable if the write fails. */
356       if (write (fd, document, document_len) < document_len)
357         {
358           if (errno == 0)
359             errno = ENOSPC;
360           return (errno);
361         }
362       else
363         return 0;
364     }
365
366   expanding_redir = 1;
367   tlist = expand_string (redirectee->word, Q_HERE_DOCUMENT);
368   expanding_redir = 0;
369
370   if (tlist)
371     {
372       /* Try using buffered I/O (stdio) and writing a word
373          at a time, letting stdio do the work of buffering
374          for us rather than managing our own strings.  Most
375          stdios are not particularly fast, however -- this
376          may need to be reconsidered later. */
377       if ((fd2 = dup (fd)) < 0 || (fp = fdopen (fd2, "w")) == NULL)
378         {
379           if (fd2 >= 0)
380             close (fd2);
381           return (errno);
382         }
383       errno = 0;
384       for (t = tlist; t; t = t->next)
385         {
386           /* This is essentially the body of
387              string_list_internal expanded inline. */
388           document = t->word->word;
389           document_len = strlen (document);
390           if (t != tlist)
391             putc (' ', fp);     /* separator */
392           fwrite (document, document_len, 1, fp);
393           if (ferror (fp))
394             {
395               if (errno == 0)
396                 errno = ENOSPC;
397               fd2 = errno;
398               fclose(fp);
399               dispose_words (tlist);
400               return (fd2);
401             }
402         }
403       dispose_words (tlist);
404       if (fclose (fp) != 0)
405         {
406           if (errno == 0)
407             errno = ENOSPC;
408           return (errno);
409         }
410     }
411   return 0;
412 }
413
414 /* Create a temporary file holding the text of the here document pointed to
415    by REDIRECTEE, and return a file descriptor open for reading to the temp
416    file.  Return -1 on any error, and make sure errno is set appropriately. */
417 static int
418 here_document_to_fd (redirectee, ri)
419      WORD_DESC *redirectee;
420      enum r_instruction ri;
421 {
422   char *filename;
423   int r, fd, fd2;
424
425   fd = sh_mktmpfd ("sh-thd", MT_USERANDOM|MT_USETMPDIR, &filename);
426
427   /* If we failed for some reason other than the file existing, abort */
428   if (fd < 0)
429     {
430       FREE (filename);
431       return (fd);
432     }
433
434   errno = r = 0;                /* XXX */
435   /* write_here_document returns 0 on success, errno on failure. */
436   if (redirectee->word)
437     r = (ri != r_reading_string) ? write_here_document (fd, redirectee)
438                                  : write_here_string (fd, redirectee);
439
440   if (r)
441     {
442       close (fd);
443       unlink (filename);
444       free (filename);
445       errno = r;
446       return (-1);
447     }
448
449   /* In an attempt to avoid races, we close the first fd only after opening
450      the second. */
451   /* Make the document really temporary.  Also make it the input. */
452   fd2 = open (filename, O_RDONLY|O_BINARY, 0600);
453
454   if (fd2 < 0)
455     {
456       r = errno;
457       unlink (filename);
458       free (filename);
459       close (fd);
460       errno = r;
461       return -1;
462     }
463
464   close (fd);
465   if (unlink (filename) < 0)
466     {
467       r = errno;
468       close (fd2);
469       free (filename);
470       errno = r;
471       return (-1);
472     }
473
474   free (filename);
475   return (fd2);
476 }
477
478 #define RF_DEVFD        1
479 #define RF_DEVSTDERR    2
480 #define RF_DEVSTDIN     3
481 #define RF_DEVSTDOUT    4
482 #define RF_DEVTCP       5
483 #define RF_DEVUDP       6
484
485 /* A list of pattern/value pairs for filenames that the redirection
486    code handles specially. */
487 static STRING_INT_ALIST _redir_special_filenames[] = {
488 #if !defined (HAVE_DEV_FD)
489   { "/dev/fd/[0-9]*", RF_DEVFD },
490 #endif
491 #if !defined (HAVE_DEV_STDIN)
492   { "/dev/stderr", RF_DEVSTDERR },
493   { "/dev/stdin", RF_DEVSTDIN },
494   { "/dev/stdout", RF_DEVSTDOUT },
495 #endif
496 #if defined (NETWORK_REDIRECTIONS)
497   { "/dev/tcp/*/*", RF_DEVTCP },
498   { "/dev/udp/*/*", RF_DEVUDP },
499 #endif
500   { (char *)NULL, -1 }
501 };
502
503 static int
504 redir_special_open (spec, filename, flags, mode, ri)
505      int spec;
506      char *filename;
507      int flags, mode;
508      enum r_instruction ri;
509 {
510   int fd;
511 #if !defined (HAVE_DEV_FD)
512   intmax_t lfd;
513 #endif
514
515   fd = -1;
516   switch (spec)
517     {
518 #if !defined (HAVE_DEV_FD)
519     case RF_DEVFD:
520       if (all_digits (filename+8) && legal_number (filename+8, &lfd) && lfd == (int)lfd)
521         {
522           fd = lfd;
523           fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
524         }
525       else
526         fd = AMBIGUOUS_REDIRECT;
527       break;
528 #endif
529
530 #if !defined (HAVE_DEV_STDIN)
531     case RF_DEVSTDIN:
532       fd = fcntl (0, F_DUPFD, SHELL_FD_BASE);
533       break;
534     case RF_DEVSTDOUT:
535       fd = fcntl (1, F_DUPFD, SHELL_FD_BASE);
536       break;
537     case RF_DEVSTDERR:
538       fd = fcntl (2, F_DUPFD, SHELL_FD_BASE);
539       break;
540 #endif
541
542 #if defined (NETWORK_REDIRECTIONS)
543     case RF_DEVTCP:
544     case RF_DEVUDP:
545 #if defined (HAVE_NETWORK)
546       fd = netopen (filename);
547 #else
548       internal_warning (_("/dev/(tcp|udp)/host/port not supported without networking"));
549       fd = open (filename, flags, mode);
550 #endif
551       break;
552 #endif /* NETWORK_REDIRECTIONS */
553     }
554
555   return fd;
556 }
557       
558 /* Open FILENAME with FLAGS in noclobber mode, hopefully avoiding most
559    race conditions and avoiding the problem where the file is replaced
560    between the stat(2) and open(2). */
561 static int
562 noclobber_open (filename, flags, mode, ri)
563      char *filename;
564      int flags, mode;
565      enum r_instruction ri;
566 {
567   int r, fd;
568   struct stat finfo, finfo2;
569
570   /* If the file exists and is a regular file, return an error
571      immediately. */
572   r = stat (filename, &finfo);
573   if (r == 0 && (S_ISREG (finfo.st_mode)))
574     return (NOCLOBBER_REDIRECT);
575
576   /* If the file was not present (r != 0), make sure we open it
577      exclusively so that if it is created before we open it, our open
578      will fail.  Make sure that we do not truncate an existing file.
579      Note that we don't turn on O_EXCL unless the stat failed -- if
580      the file was not a regular file, we leave O_EXCL off. */
581   flags &= ~O_TRUNC;
582   if (r != 0)
583     {
584       fd = open (filename, flags|O_EXCL, mode);
585       return ((fd < 0 && errno == EEXIST) ? NOCLOBBER_REDIRECT : fd);
586     }
587   fd = open (filename, flags, mode);
588
589   /* If the open failed, return the file descriptor right away. */
590   if (fd < 0)
591     return (errno == EEXIST ? NOCLOBBER_REDIRECT : fd);
592
593   /* OK, the open succeeded, but the file may have been changed from a
594      non-regular file to a regular file between the stat and the open.
595      We are assuming that the O_EXCL open handles the case where FILENAME
596      did not exist and is symlinked to an existing file between the stat
597      and open. */
598
599   /* If we can open it and fstat the file descriptor, and neither check
600      revealed that it was a regular file, and the file has not been replaced,
601      return the file descriptor. */
602   if ((fstat (fd, &finfo2) == 0) && (S_ISREG (finfo2.st_mode) == 0) &&
603       r == 0 && (S_ISREG (finfo.st_mode) == 0) &&
604       same_file (filename, filename, &finfo, &finfo2))
605     return fd;
606
607   /* The file has been replaced.  badness. */
608   close (fd);  
609   errno = EEXIST;
610   return (NOCLOBBER_REDIRECT);
611 }
612
613 static int
614 redir_open (filename, flags, mode, ri)
615      char *filename;
616      int flags, mode;
617      enum r_instruction ri;
618 {
619   int fd, r;
620
621   r = find_string_in_alist (filename, _redir_special_filenames, 1);
622   if (r >= 0)
623     return (redir_special_open (r, filename, flags, mode, ri));
624
625   /* If we are in noclobber mode, you are not allowed to overwrite
626      existing files.  Check before opening. */
627   if (noclobber && CLOBBERING_REDIRECT (ri))
628     {
629       fd = noclobber_open (filename, flags, mode, ri);
630       if (fd == NOCLOBBER_REDIRECT)
631         return (NOCLOBBER_REDIRECT);
632     }
633   else
634     {
635       fd = open (filename, flags, mode);
636 #if defined (AFS)
637       if ((fd < 0) && (errno == EACCES))
638         {
639           fd = open (filename, flags & ~O_CREAT, mode);
640           errno = EACCES;       /* restore errno */
641         }
642 #endif /* AFS */
643     }
644
645   return fd;
646 }
647
648 static int
649 undoablefd (fd)
650      int fd;
651 {
652   int clexec;
653
654   clexec = fcntl (fd, F_GETFD, 0);
655   if (clexec == -1 || (fd >= SHELL_FD_BASE && clexec == 1))
656     return 0;
657   return 1;
658 }
659
660 /* Do the specific redirection requested.  Returns errno or one of the
661    special redirection errors (*_REDIRECT) in case of error, 0 on success.
662    If flags & RX_ACTIVE is zero, then just do whatever is neccessary to
663    produce the appropriate side effects.   flags & RX_UNDOABLE, if non-zero,
664    says to remember how to undo each redirection.  If flags & RX_CLEXEC is
665    non-zero, then we set all file descriptors > 2 that we open to be
666    close-on-exec.  */
667 static int
668 do_redirection_internal (redirect, flags)
669      REDIRECT *redirect;
670      int flags;
671 {
672   WORD_DESC *redirectee;
673   int redir_fd, fd, redirector, r, oflags;
674   intmax_t lfd;
675   char *redirectee_word;
676   enum r_instruction ri;
677   REDIRECT *new_redirect;
678   REDIRECTEE sd;
679
680   redirectee = redirect->redirectee.filename;
681   redir_fd = redirect->redirectee.dest;
682   redirector = redirect->redirector.dest;
683   ri = redirect->instruction;
684
685   if (redirect->flags & RX_INTERNAL)
686     flags |= RX_INTERNAL;
687
688   if (TRANSLATE_REDIRECT (ri))
689     {
690       /* We have [N]>&WORD[-] or [N]<&WORD[-] (or {V}>&WORD[-] or {V}<&WORD-).
691          and WORD, then translate the redirection into a new one and 
692          continue. */
693       redirectee_word = redirection_expand (redirectee);
694
695       /* XXX - what to do with [N]<&$w- where w is unset or null?  ksh93
696                closes N. */
697       if (redirectee_word == 0)
698         return (AMBIGUOUS_REDIRECT);
699       else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
700         {
701           sd = redirect->redirector;
702           rd.dest = 0;
703           new_redirect = make_redirection (sd, r_close_this, rd, 0);
704         }
705       else if (all_digits (redirectee_word))
706         {
707           sd = redirect->redirector;
708           if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
709             rd.dest = lfd;
710           else
711             rd.dest = -1;       /* XXX */
712           switch (ri)
713             {
714             case r_duplicating_input_word:
715               new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
716               break;
717             case r_duplicating_output_word:
718               new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
719               break;
720             case r_move_input_word:
721               new_redirect = make_redirection (sd, r_move_input, rd, 0);
722               break;
723             case r_move_output_word:
724               new_redirect = make_redirection (sd, r_move_output, rd, 0);
725               break;
726             }
727         }
728       else if (ri == r_duplicating_output_word && (redirect->rflags & REDIR_VARASSIGN) == 0 && redirector == 1)
729         {
730           sd = redirect->redirector;
731           rd.filename = make_bare_word (redirectee_word);
732           new_redirect = make_redirection (sd, r_err_and_out, rd, 0);
733         }
734       else
735         {
736           free (redirectee_word);
737           return (AMBIGUOUS_REDIRECT);
738         }
739
740       free (redirectee_word);
741
742       /* Set up the variables needed by the rest of the function from the
743          new redirection. */
744       if (new_redirect->instruction == r_err_and_out)
745         {
746           char *alloca_hack;
747
748           /* Copy the word without allocating any memory that must be
749              explicitly freed. */
750           redirectee = (WORD_DESC *)alloca (sizeof (WORD_DESC));
751           xbcopy ((char *)new_redirect->redirectee.filename,
752                  (char *)redirectee, sizeof (WORD_DESC));
753
754           alloca_hack = (char *)
755             alloca (1 + strlen (new_redirect->redirectee.filename->word));
756           redirectee->word = alloca_hack;
757           strcpy (redirectee->word, new_redirect->redirectee.filename->word);
758         }
759       else
760         /* It's guaranteed to be an integer, and shouldn't be freed. */
761         redirectee = new_redirect->redirectee.filename;
762
763       redir_fd = new_redirect->redirectee.dest;
764       redirector = new_redirect->redirector.dest;
765       ri = new_redirect->instruction;
766
767       /* Overwrite the flags element of the old redirect with the new value. */
768       redirect->flags = new_redirect->flags;
769       dispose_redirects (new_redirect);
770     }
771
772   switch (ri)
773     {
774     case r_output_direction:
775     case r_appending_to:
776     case r_input_direction:
777     case r_inputa_direction:
778     case r_err_and_out:         /* command &>filename */
779     case r_append_err_and_out:  /* command &>> filename */
780     case r_input_output:
781     case r_output_force:
782       if (posixly_correct && interactive_shell == 0)
783         {
784           oflags = redirectee->flags;
785           redirectee->flags |= W_NOGLOB;
786         }
787       redirectee_word = redirection_expand (redirectee);
788       if (posixly_correct && interactive_shell == 0)
789         redirectee->flags = oflags;
790
791       if (redirectee_word == 0)
792         return (AMBIGUOUS_REDIRECT);
793
794 #if defined (RESTRICTED_SHELL)
795       if (restricted && (WRITE_REDIRECT (ri)))
796         {
797           free (redirectee_word);
798           return (RESTRICTED_REDIRECT);
799         }
800 #endif /* RESTRICTED_SHELL */
801
802       fd = redir_open (redirectee_word, redirect->flags, 0666, ri);
803       free (redirectee_word);
804
805       if (fd == NOCLOBBER_REDIRECT)
806         return (fd);
807
808       if (fd < 0)
809         return (errno);
810
811       if (flags & RX_ACTIVE)
812         {
813           if (redirect->rflags & REDIR_VARASSIGN)
814             {
815               redirector = fcntl (fd, F_DUPFD, SHELL_FD_BASE);          /* XXX try this for now */
816               r = errno;
817               if (redirector < 0)
818                 sys_error (_("redirection error: cannot duplicate fd"));
819               REDIRECTION_ERROR (redirector, r, fd);
820             }
821
822           if (flags & RX_UNDOABLE)
823             {
824               /* Only setup to undo it if the thing to undo is active. */
825               if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
826                 r = add_undo_redirect (redirector, ri, -1);
827               else
828                 r = add_undo_close_redirect (redirector);
829               if (r < 0 && (redirect->rflags & REDIR_VARASSIGN))
830                 close (redirector);
831               REDIRECTION_ERROR (r, errno, fd);
832             }
833
834 #if defined (BUFFERED_INPUT)
835           check_bash_input (redirector);
836 #endif
837
838           /* Make sure there is no pending output before we change the state
839              of the underlying file descriptor, since the builtins use stdio
840              for output. */
841           if (redirector == 1 && fileno (stdout) == redirector)
842             {
843               fflush (stdout);
844               fpurge (stdout);
845             }
846           else if (redirector == 2 && fileno (stderr) == redirector)
847             {
848               fflush (stderr);
849               fpurge (stderr);
850             }
851
852           if (redirect->rflags & REDIR_VARASSIGN)
853             {
854               if ((r = redir_varassign (redirect, redirector)) < 0)
855                 {
856                   close (redirector);
857                   close (fd);
858                   return (r);   /* XXX */
859                 }
860             }
861           else if ((fd != redirector) && (dup2 (fd, redirector) < 0))
862             return (errno);
863
864 #if defined (BUFFERED_INPUT)
865           /* Do not change the buffered stream for an implicit redirection
866              of /dev/null to fd 0 for asynchronous commands without job
867              control (r_inputa_direction). */
868           if (ri == r_input_direction || ri == r_input_output)
869             duplicate_buffered_stream (fd, redirector);
870 #endif /* BUFFERED_INPUT */
871
872           /*
873            * If we're remembering, then this is the result of a while, for
874            * or until loop with a loop redirection, or a function/builtin
875            * executing in the parent shell with a redirection.  In the
876            * function/builtin case, we want to set all file descriptors > 2
877            * to be close-on-exec to duplicate the effect of the old
878            * for i = 3 to NOFILE close(i) loop.  In the case of the loops,
879            * both sh and ksh leave the file descriptors open across execs.
880            * The Posix standard mentions only the exec builtin.
881            */
882           if ((flags & RX_CLEXEC) && (redirector > 2))
883             SET_CLOSE_ON_EXEC (redirector);
884         }
885
886       if (fd != redirector)
887         {
888 #if defined (BUFFERED_INPUT)
889           if (INPUT_REDIRECT (ri))
890             close_buffered_fd (fd);
891           else
892 #endif /* !BUFFERED_INPUT */
893             close (fd);         /* Don't close what we just opened! */
894         }
895
896       /* If we are hacking both stdout and stderr, do the stderr
897          redirection here.  XXX - handle {var} here? */
898       if (ri == r_err_and_out || ri == r_append_err_and_out)
899         {
900           if (flags & RX_ACTIVE)
901             {
902               if (flags & RX_UNDOABLE)
903                 add_undo_redirect (2, ri, -1);
904               if (dup2 (1, 2) < 0)
905                 return (errno);
906             }
907         }
908       break;
909
910     case r_reading_until:
911     case r_deblank_reading_until:
912     case r_reading_string:
913       /* REDIRECTEE is a pointer to a WORD_DESC containing the text of
914          the new input.  Place it in a temporary file. */
915       if (redirectee)
916         {
917           fd = here_document_to_fd (redirectee, ri);
918
919           if (fd < 0)
920             {
921               heredoc_errno = errno;
922               return (HEREDOC_REDIRECT);
923             }
924
925           if (redirect->rflags & REDIR_VARASSIGN)
926             {
927               redirector = fcntl (fd, F_DUPFD, SHELL_FD_BASE);          /* XXX try this for now */
928               r = errno;
929               if (redirector < 0)
930                 sys_error (_("redirection error: cannot duplicate fd"));
931               REDIRECTION_ERROR (redirector, r, fd);
932             }
933
934           if (flags & RX_ACTIVE)
935             {
936               if (flags & RX_UNDOABLE)
937                 {
938                   /* Only setup to undo it if the thing to undo is active. */
939                   if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
940                     r = add_undo_redirect (redirector, ri, -1);
941                   else
942                     r = add_undo_close_redirect (redirector);
943                   if (r < 0 && (redirect->rflags & REDIR_VARASSIGN))
944                     close (redirector);
945                   REDIRECTION_ERROR (r, errno, fd);
946                 }
947
948 #if defined (BUFFERED_INPUT)
949               check_bash_input (redirector);
950 #endif
951               if (redirect->rflags & REDIR_VARASSIGN)
952                 {
953                   if ((r = redir_varassign (redirect, redirector)) < 0)
954                     {
955                       close (redirector);
956                       close (fd);
957                       return (r);       /* XXX */
958                     }
959                 }
960               else if (fd != redirector && dup2 (fd, redirector) < 0)
961                 {
962                   r = errno;
963                   close (fd);
964                   return (r);
965                 }
966
967 #if defined (BUFFERED_INPUT)
968               duplicate_buffered_stream (fd, redirector);
969 #endif
970
971               if ((flags & RX_CLEXEC) && (redirector > 2))
972                 SET_CLOSE_ON_EXEC (redirector);
973             }
974
975           if (fd != redirector)
976 #if defined (BUFFERED_INPUT)
977             close_buffered_fd (fd);
978 #else
979             close (fd);
980 #endif
981         }
982       break;
983
984     case r_duplicating_input:
985     case r_duplicating_output:
986     case r_move_input:
987     case r_move_output:
988       if ((flags & RX_ACTIVE) && (redirect->rflags & REDIR_VARASSIGN))
989         {
990           redirector = fcntl (redir_fd, F_DUPFD, SHELL_FD_BASE);                /* XXX try this for now */
991           r = errno;
992           if (redirector < 0)
993             sys_error (_("redirection error: cannot duplicate fd"));
994           REDIRECTION_ERROR (redirector, r, -1);
995         }
996
997       if ((flags & RX_ACTIVE) && (redir_fd != redirector))
998         {
999           if (flags & RX_UNDOABLE)
1000             {
1001               /* Only setup to undo it if the thing to undo is active. */
1002               if (fcntl (redirector, F_GETFD, 0) != -1)
1003                 r = add_undo_redirect (redirector, ri, redir_fd);
1004               else
1005                 r = add_undo_close_redirect (redirector);
1006               if (r < 0 && (redirect->rflags & REDIR_VARASSIGN))
1007                 close (redirector);
1008               REDIRECTION_ERROR (r, errno, -1);
1009             }
1010           if ((flags & RX_UNDOABLE) && (ri == r_move_input || ri == r_move_output))
1011             {
1012               /* r_move_input and r_move_output add an additional close()
1013                  that needs to be undone */
1014               if (fcntl (redirector, F_GETFD, 0) != -1)
1015                 {
1016                   r = add_undo_redirect (redir_fd, r_close_this, -1);
1017                   REDIRECTION_ERROR (r, errno, -1);
1018                 }
1019             }
1020 #if defined (BUFFERED_INPUT)
1021           check_bash_input (redirector);
1022 #endif
1023           if (redirect->rflags & REDIR_VARASSIGN)
1024             {
1025               if ((r = redir_varassign (redirect, redirector)) < 0)
1026                 {
1027                   close (redirector);
1028                   return (r);   /* XXX */
1029                 }
1030             }
1031           /* This is correct.  2>&1 means dup2 (1, 2); */
1032           else if (dup2 (redir_fd, redirector) < 0)
1033             return (errno);
1034
1035 #if defined (BUFFERED_INPUT)
1036           if (ri == r_duplicating_input || ri == r_move_input)
1037             duplicate_buffered_stream (redir_fd, redirector);
1038 #endif /* BUFFERED_INPUT */
1039
1040           /* First duplicate the close-on-exec state of redirectee.  dup2
1041              leaves the flag unset on the new descriptor, which means it
1042              stays open.  Only set the close-on-exec bit for file descriptors
1043              greater than 2 in any case, since 0-2 should always be open
1044              unless closed by something like `exec 2<&-'.  It should always
1045              be safe to set fds > 2 to close-on-exec if they're being used to
1046              save file descriptors < 2, since we don't need to preserve the
1047              state of the close-on-exec flag for those fds -- they should
1048              always be open. */
1049           /* if ((already_set || set_unconditionally) && (ok_to_set))
1050                 set_it () */
1051 #if 0
1052           if (((fcntl (redir_fd, F_GETFD, 0) == 1) || redir_fd < 2 || (flags & RX_CLEXEC)) &&
1053                (redirector > 2))
1054 #else
1055           if (((fcntl (redir_fd, F_GETFD, 0) == 1) || (redir_fd < 2 && (flags & RX_INTERNAL)) || (flags & RX_CLEXEC)) &&
1056                (redirector > 2))
1057 #endif
1058             SET_CLOSE_ON_EXEC (redirector);
1059
1060           /* When undoing saving of non-standard file descriptors (>=3) using
1061              file descriptors >= SHELL_FD_BASE, we set the saving fd to be
1062              close-on-exec and use a flag to decide how to set close-on-exec
1063              when the fd is restored. */
1064           if ((redirect->flags & RX_INTERNAL) && (redirect->flags & RX_SAVCLEXEC) && redirector >= 3 && redir_fd >= SHELL_FD_BASE)
1065             SET_OPEN_ON_EXEC (redirector);
1066             
1067           /* dup-and-close redirection */
1068           if (ri == r_move_input || ri == r_move_output)
1069             {
1070               xtrace_fdchk (redir_fd);
1071
1072               close (redir_fd);
1073 #if defined (COPROCESS_SUPPORT)
1074               coproc_fdchk (redir_fd);  /* XXX - loses coproc fds */
1075 #endif
1076             }
1077         }
1078       break;
1079
1080     case r_close_this:
1081       if (flags & RX_ACTIVE)
1082         {
1083           if (redirect->rflags & REDIR_VARASSIGN)
1084             {
1085               redirector = redir_varvalue (redirect);
1086               if (redirector < 0)
1087                 return AMBIGUOUS_REDIRECT;
1088             }
1089
1090           r = 0;
1091           if ((flags & RX_UNDOABLE) && (fcntl (redirector, F_GETFD, 0) != -1))
1092             {
1093               r = add_undo_redirect (redirector, ri, -1);
1094               REDIRECTION_ERROR (r, errno, redirector);
1095             }
1096
1097 #if defined (COPROCESS_SUPPORT)
1098           coproc_fdchk (redirector);
1099 #endif
1100           xtrace_fdchk (redirector);
1101
1102 #if defined (BUFFERED_INPUT)
1103           check_bash_input (redirector);
1104           r = close_buffered_fd (redirector);
1105 #else /* !BUFFERED_INPUT */
1106           r = close (redirector);
1107 #endif /* !BUFFERED_INPUT */
1108           if (r < 0 && (flags & RX_INTERNAL) && (errno == EIO || errno == ENOSPC))
1109             REDIRECTION_ERROR (r, errno, -1);
1110         }
1111       break;
1112
1113     case r_duplicating_input_word:
1114     case r_duplicating_output_word:
1115       break;
1116     }
1117   return (0);
1118 }
1119
1120 /* Remember the file descriptor associated with the slot FD,
1121    on REDIRECTION_UNDO_LIST.  Note that the list will be reversed
1122    before it is executed.  Any redirections that need to be undone
1123    even if REDIRECTION_UNDO_LIST is discarded by the exec builtin
1124    are also saved on EXEC_REDIRECTION_UNDO_LIST.  FDBASE says where to
1125    start the duplicating.  If it's less than SHELL_FD_BASE, we're ok,
1126    and can use SHELL_FD_BASE (-1 == don't care).  If it's >= SHELL_FD_BASE,
1127    we have to make sure we don't use fdbase to save a file descriptor,
1128    since we're going to use it later (e.g., make sure we don't save fd 0
1129    to fd 10 if we have a redirection like 0<&10).  If the value of fdbase
1130    puts the process over its fd limit, causing fcntl to fail, we try
1131    again with SHELL_FD_BASE.  Return 0 on success, -1 on error. */
1132 static int
1133 add_undo_redirect (fd, ri, fdbase)
1134      int fd;
1135      enum r_instruction ri;
1136      int fdbase;
1137 {
1138   int new_fd, clexec_flag;
1139   REDIRECT *new_redirect, *closer, *dummy_redirect;
1140   REDIRECTEE sd;
1141
1142   new_fd = fcntl (fd, F_DUPFD, (fdbase < SHELL_FD_BASE) ? SHELL_FD_BASE : fdbase+1);
1143   if (new_fd < 0)
1144     new_fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
1145
1146   if (new_fd < 0)
1147     {
1148       sys_error (_("redirection error: cannot duplicate fd"));
1149       return (-1);
1150     }
1151
1152   clexec_flag = fcntl (fd, F_GETFD, 0);
1153
1154   sd.dest = new_fd;
1155   rd.dest = 0;
1156   closer = make_redirection (sd, r_close_this, rd, 0);
1157   closer->flags |= RX_INTERNAL;
1158   dummy_redirect = copy_redirects (closer);
1159
1160   sd.dest = fd;
1161   rd.dest = new_fd;
1162   if (fd == 0)
1163     new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
1164   else
1165     new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
1166   new_redirect->flags |= RX_INTERNAL;
1167   if (clexec_flag == 0 && fd >= 3 && new_fd >= SHELL_FD_BASE)
1168     new_redirect->flags |= RX_SAVCLEXEC;
1169   new_redirect->next = closer;
1170
1171   closer->next = redirection_undo_list;
1172   redirection_undo_list = new_redirect;
1173
1174   /* Save redirections that need to be undone even if the undo list
1175      is thrown away by the `exec' builtin. */
1176   add_exec_redirect (dummy_redirect);
1177
1178   /* experimental:  if we're saving a redirection to undo for a file descriptor
1179      above SHELL_FD_BASE, add a redirection to be undone if the exec builtin
1180      causes redirections to be discarded.  There needs to be a difference
1181      between fds that are used to save other fds and then are the target of
1182      user redirections and fds that are just the target of user redirections.
1183      We use the close-on-exec flag to tell the difference; fds > SHELL_FD_BASE
1184      that have the close-on-exec flag set are assumed to be fds used internally
1185      to save others. */
1186   if (fd >= SHELL_FD_BASE && ri != r_close_this && clexec_flag)
1187     {
1188       sd.dest = fd;
1189       rd.dest = new_fd;
1190       new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
1191       new_redirect->flags |= RX_INTERNAL;
1192
1193       add_exec_redirect (new_redirect);
1194     }
1195
1196   /* File descriptors used only for saving others should always be
1197      marked close-on-exec.  Unfortunately, we have to preserve the
1198      close-on-exec state of the file descriptor we are saving, since
1199      fcntl (F_DUPFD) sets the new file descriptor to remain open
1200      across execs.  If, however, the file descriptor whose state we
1201      are saving is <= 2, we can just set the close-on-exec flag,
1202      because file descriptors 0-2 should always be open-on-exec,
1203      and the restore above in do_redirection() will take care of it. */
1204   if (clexec_flag || fd < 3)
1205     SET_CLOSE_ON_EXEC (new_fd);
1206   else if (redirection_undo_list->flags & RX_SAVCLEXEC)
1207     SET_CLOSE_ON_EXEC (new_fd);
1208
1209   return (0);
1210 }
1211
1212 /* Set up to close FD when we are finished with the current command
1213    and its redirections.  Return 0 on success, -1 on error. */
1214 static int
1215 add_undo_close_redirect (fd)
1216      int fd;
1217 {
1218   REDIRECT *closer;
1219   REDIRECTEE sd;
1220
1221   sd.dest = fd;
1222   rd.dest = 0;
1223   closer = make_redirection (sd, r_close_this, rd, 0);
1224   closer->flags |= RX_INTERNAL;
1225   closer->next = redirection_undo_list;
1226   redirection_undo_list = closer;
1227
1228   return 0;
1229 }
1230
1231 static void
1232 add_exec_redirect (dummy_redirect)
1233      REDIRECT *dummy_redirect;
1234 {
1235   dummy_redirect->next = exec_redirection_undo_list;
1236   exec_redirection_undo_list = dummy_redirect;
1237 }
1238
1239 /* Return 1 if the redirection specified by RI and REDIRECTOR alters the
1240    standard input. */
1241 static int
1242 stdin_redirection (ri, redirector)
1243      enum r_instruction ri;
1244      int redirector;
1245 {
1246   switch (ri)
1247     {
1248     case r_input_direction:
1249     case r_inputa_direction:
1250     case r_input_output:
1251     case r_reading_until:
1252     case r_deblank_reading_until:
1253     case r_reading_string:
1254       return (1);
1255     case r_duplicating_input:
1256     case r_duplicating_input_word:
1257     case r_close_this:
1258       return (redirector == 0);
1259     case r_output_direction:
1260     case r_appending_to:
1261     case r_duplicating_output:
1262     case r_err_and_out:
1263     case r_append_err_and_out:
1264     case r_output_force:
1265     case r_duplicating_output_word:
1266       return (0);
1267     }
1268   return (0);
1269 }
1270
1271 /* Return non-zero if any of the redirections in REDIRS alter the standard
1272    input. */
1273 int
1274 stdin_redirects (redirs)
1275      REDIRECT *redirs;
1276 {
1277   REDIRECT *rp;
1278   int n;
1279
1280   for (n = 0, rp = redirs; rp; rp = rp->next)
1281     if ((rp->rflags & REDIR_VARASSIGN) == 0)
1282       n += stdin_redirection (rp->instruction, rp->redirector.dest);
1283   return n;
1284 }
1285
1286 /* These don't yet handle array references */
1287 static int
1288 redir_varassign (redir, fd)
1289      REDIRECT *redir;
1290      int fd;
1291 {
1292   WORD_DESC *w;
1293   SHELL_VAR *v;
1294
1295   w = redir->redirector.filename;
1296   v = bind_var_to_int (w->word, fd);
1297   if (v == 0 || readonly_p (v) || noassign_p (v))
1298     return BADVAR_REDIRECT;
1299
1300   return 0;
1301 }
1302
1303 static int
1304 redir_varvalue (redir)
1305      REDIRECT *redir;
1306 {
1307   SHELL_VAR *v;
1308   char *val;
1309   intmax_t vmax;
1310   int i;
1311
1312   /* XXX - handle set -u here? */
1313   v = find_variable (redir->redirector.filename->word);
1314   if (v == 0 || invisible_p (v))
1315     return -1;
1316
1317   val = get_variable_value (v);
1318   if (val == 0 || *val == 0)
1319     return -1;
1320
1321   if (legal_number (val, &vmax) < 0)
1322     return -1;
1323
1324   i = vmax;     /* integer truncation */
1325   return i;
1326 }