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