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