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