source: trunk/essentials/app-shells/bash/redir.c

Last change on this file was 3260, checked in by bird, 18 years ago

Ignore unlink failure like cygwin does. Fixes the array testcase.

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