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