]> git.ipfire.org Git - thirdparty/bash.git/blame - redir.c
Bash-4.4 patch 4
[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
JA
471
472 errno = r = 0; /* XXX */
473 /* write_here_document returns 0 on success, errno on failure. */
474 if (redirectee->word)
7117c2d2
JA
475 r = (ri != r_reading_string) ? write_here_document (fd, redirectee)
476 : write_here_string (fd, redirectee);
cce855bc 477
cce855bc
JA
478 if (r)
479 {
bb70624e 480 close (fd);
cce855bc 481 unlink (filename);
28ef6c31 482 free (filename);
cce855bc
JA
483 errno = r;
484 return (-1);
485 }
486
bb70624e
JA
487 /* In an attempt to avoid races, we close the first fd only after opening
488 the second. */
cce855bc 489 /* Make the document really temporary. Also make it the input. */
495aee44 490 fd2 = open (filename, O_RDONLY|O_BINARY, 0600);
cce855bc 491
bb70624e 492 if (fd2 < 0)
cce855bc
JA
493 {
494 r = errno;
495 unlink (filename);
28ef6c31 496 free (filename);
bb70624e 497 close (fd);
cce855bc
JA
498 errno = r;
499 return -1;
500 }
501
bb70624e 502 close (fd);
cce855bc
JA
503 if (unlink (filename) < 0)
504 {
505 r = errno;
bb70624e 506 close (fd2);
28ef6c31 507 free (filename);
cce855bc
JA
508 errno = r;
509 return (-1);
510 }
511
28ef6c31 512 free (filename);
bb70624e 513 return (fd2);
cce855bc
JA
514}
515
bb70624e
JA
516#define RF_DEVFD 1
517#define RF_DEVSTDERR 2
518#define RF_DEVSTDIN 3
519#define RF_DEVSTDOUT 4
520#define RF_DEVTCP 5
521#define RF_DEVUDP 6
522
523/* A list of pattern/value pairs for filenames that the redirection
524 code handles specially. */
525static STRING_INT_ALIST _redir_special_filenames[] = {
526#if !defined (HAVE_DEV_FD)
527 { "/dev/fd/[0-9]*", RF_DEVFD },
528#endif
529#if !defined (HAVE_DEV_STDIN)
530 { "/dev/stderr", RF_DEVSTDERR },
531 { "/dev/stdin", RF_DEVSTDIN },
532 { "/dev/stdout", RF_DEVSTDOUT },
533#endif
534#if defined (NETWORK_REDIRECTIONS)
535 { "/dev/tcp/*/*", RF_DEVTCP },
536 { "/dev/udp/*/*", RF_DEVUDP },
537#endif
538 { (char *)NULL, -1 }
539};
540
541static int
542redir_special_open (spec, filename, flags, mode, ri)
543 int spec;
544 char *filename;
545 int flags, mode;
546 enum r_instruction ri;
547{
548 int fd;
f73dda09 549#if !defined (HAVE_DEV_FD)
7117c2d2 550 intmax_t lfd;
f73dda09 551#endif
bb70624e
JA
552
553 fd = -1;
554 switch (spec)
555 {
556#if !defined (HAVE_DEV_FD)
557 case RF_DEVFD:
f73dda09
JA
558 if (all_digits (filename+8) && legal_number (filename+8, &lfd) && lfd == (int)lfd)
559 {
560 fd = lfd;
3185942a 561 fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
f73dda09 562 }
bb70624e
JA
563 else
564 fd = AMBIGUOUS_REDIRECT;
565 break;
566#endif
567
568#if !defined (HAVE_DEV_STDIN)
569 case RF_DEVSTDIN:
3185942a 570 fd = fcntl (0, F_DUPFD, SHELL_FD_BASE);
bb70624e
JA
571 break;
572 case RF_DEVSTDOUT:
3185942a 573 fd = fcntl (1, F_DUPFD, SHELL_FD_BASE);
bb70624e
JA
574 break;
575 case RF_DEVSTDERR:
3185942a 576 fd = fcntl (2, F_DUPFD, SHELL_FD_BASE);
bb70624e
JA
577 break;
578#endif
579
580#if defined (NETWORK_REDIRECTIONS)
581 case RF_DEVTCP:
582 case RF_DEVUDP:
583#if defined (HAVE_NETWORK)
584 fd = netopen (filename);
585#else
b80f6443 586 internal_warning (_("/dev/(tcp|udp)/host/port not supported without networking"));
bb70624e
JA
587 fd = open (filename, flags, mode);
588#endif
589 break;
590#endif /* NETWORK_REDIRECTIONS */
591 }
592
593 return fd;
594}
595
cce855bc
JA
596/* Open FILENAME with FLAGS in noclobber mode, hopefully avoiding most
597 race conditions and avoiding the problem where the file is replaced
598 between the stat(2) and open(2). */
599static int
bb70624e 600noclobber_open (filename, flags, mode, ri)
cce855bc 601 char *filename;
bb70624e 602 int flags, mode;
cce855bc
JA
603 enum r_instruction ri;
604{
605 int r, fd;
606 struct stat finfo, finfo2;
607
608 /* If the file exists and is a regular file, return an error
609 immediately. */
610 r = stat (filename, &finfo);
611 if (r == 0 && (S_ISREG (finfo.st_mode)))
612 return (NOCLOBBER_REDIRECT);
613
614 /* If the file was not present (r != 0), make sure we open it
615 exclusively so that if it is created before we open it, our open
616 will fail. Make sure that we do not truncate an existing file.
617 Note that we don't turn on O_EXCL unless the stat failed -- if
618 the file was not a regular file, we leave O_EXCL off. */
619 flags &= ~O_TRUNC;
620 if (r != 0)
621 {
bb70624e 622 fd = open (filename, flags|O_EXCL, mode);
cce855bc
JA
623 return ((fd < 0 && errno == EEXIST) ? NOCLOBBER_REDIRECT : fd);
624 }
bb70624e 625 fd = open (filename, flags, mode);
cce855bc
JA
626
627 /* If the open failed, return the file descriptor right away. */
628 if (fd < 0)
629 return (errno == EEXIST ? NOCLOBBER_REDIRECT : fd);
630
631 /* OK, the open succeeded, but the file may have been changed from a
632 non-regular file to a regular file between the stat and the open.
633 We are assuming that the O_EXCL open handles the case where FILENAME
634 did not exist and is symlinked to an existing file between the stat
635 and open. */
636
637 /* If we can open it and fstat the file descriptor, and neither check
638 revealed that it was a regular file, and the file has not been replaced,
639 return the file descriptor. */
640 if ((fstat (fd, &finfo2) == 0) && (S_ISREG (finfo2.st_mode) == 0) &&
641 r == 0 && (S_ISREG (finfo.st_mode) == 0) &&
642 same_file (filename, filename, &finfo, &finfo2))
643 return fd;
644
645 /* The file has been replaced. badness. */
646 close (fd);
647 errno = EEXIST;
648 return (NOCLOBBER_REDIRECT);
649}
650
bb70624e
JA
651static int
652redir_open (filename, flags, mode, ri)
653 char *filename;
654 int flags, mode;
655 enum r_instruction ri;
656{
ac50fbac 657 int fd, r, e;
bb70624e
JA
658
659 r = find_string_in_alist (filename, _redir_special_filenames, 1);
660 if (r >= 0)
661 return (redir_special_open (r, filename, flags, mode, ri));
662
663 /* If we are in noclobber mode, you are not allowed to overwrite
664 existing files. Check before opening. */
28ef6c31 665 if (noclobber && CLOBBERING_REDIRECT (ri))
bb70624e
JA
666 {
667 fd = noclobber_open (filename, flags, mode, ri);
668 if (fd == NOCLOBBER_REDIRECT)
669 return (NOCLOBBER_REDIRECT);
670 }
671 else
672 {
ac50fbac
CR
673 do
674 {
675 fd = open (filename, flags, mode);
676 e = errno;
677 if (fd < 0 && e == EINTR)
591b09c4
CR
678 {
679 QUIT;
680 run_pending_traps ();
681 }
ac50fbac
CR
682 errno = e;
683 }
684 while (fd < 0 && errno == EINTR);
685
bb70624e
JA
686#if defined (AFS)
687 if ((fd < 0) && (errno == EACCES))
95732b49
JA
688 {
689 fd = open (filename, flags & ~O_CREAT, mode);
690 errno = EACCES; /* restore errno */
691 }
bb70624e
JA
692#endif /* AFS */
693 }
694
695 return fd;
696}
697
3185942a
JA
698static int
699undoablefd (fd)
700 int fd;
701{
702 int clexec;
703
704 clexec = fcntl (fd, F_GETFD, 0);
705 if (clexec == -1 || (fd >= SHELL_FD_BASE && clexec == 1))
706 return 0;
707 return 1;
708}
709
cce855bc
JA
710/* Do the specific redirection requested. Returns errno or one of the
711 special redirection errors (*_REDIRECT) in case of error, 0 on success.
ac50fbac 712 If flags & RX_ACTIVE is zero, then just do whatever is necessary to
b80f6443
JA
713 produce the appropriate side effects. flags & RX_UNDOABLE, if non-zero,
714 says to remember how to undo each redirection. If flags & RX_CLEXEC is
715 non-zero, then we set all file descriptors > 2 that we open to be
716 close-on-exec. */
cce855bc 717static int
b80f6443 718do_redirection_internal (redirect, flags)
cce855bc 719 REDIRECT *redirect;
b80f6443 720 int flags;
cce855bc
JA
721{
722 WORD_DESC *redirectee;
bb70624e 723 int redir_fd, fd, redirector, r, oflags;
7117c2d2 724 intmax_t lfd;
cce855bc
JA
725 char *redirectee_word;
726 enum r_instruction ri;
727 REDIRECT *new_redirect;
0001803f 728 REDIRECTEE sd;
cce855bc
JA
729
730 redirectee = redirect->redirectee.filename;
731 redir_fd = redirect->redirectee.dest;
0001803f 732 redirector = redirect->redirector.dest;
cce855bc
JA
733 ri = redirect->instruction;
734
0628567a
JA
735 if (redirect->flags & RX_INTERNAL)
736 flags |= RX_INTERNAL;
95732b49 737
7117c2d2 738 if (TRANSLATE_REDIRECT (ri))
cce855bc 739 {
0001803f
CR
740 /* We have [N]>&WORD[-] or [N]<&WORD[-] (or {V}>&WORD[-] or {V}<&WORD-).
741 and WORD, then translate the redirection into a new one and
742 continue. */
cce855bc
JA
743 redirectee_word = redirection_expand (redirectee);
744
7117c2d2
JA
745 /* XXX - what to do with [N]<&$w- where w is unset or null? ksh93
746 closes N. */
cce855bc
JA
747 if (redirectee_word == 0)
748 return (AMBIGUOUS_REDIRECT);
749 else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
750 {
0001803f 751 sd = redirect->redirector;
f73dda09 752 rd.dest = 0;
0001803f 753 new_redirect = make_redirection (sd, r_close_this, rd, 0);
cce855bc
JA
754 }
755 else if (all_digits (redirectee_word))
756 {
0001803f 757 sd = redirect->redirector;
f73dda09
JA
758 if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
759 rd.dest = lfd;
cce855bc 760 else
f73dda09 761 rd.dest = -1; /* XXX */
7117c2d2
JA
762 switch (ri)
763 {
764 case r_duplicating_input_word:
0001803f 765 new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
7117c2d2
JA
766 break;
767 case r_duplicating_output_word:
0001803f 768 new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
7117c2d2
JA
769 break;
770 case r_move_input_word:
0001803f 771 new_redirect = make_redirection (sd, r_move_input, rd, 0);
7117c2d2
JA
772 break;
773 case r_move_output_word:
0001803f 774 new_redirect = make_redirection (sd, r_move_output, rd, 0);
7117c2d2
JA
775 break;
776 }
cce855bc 777 }
0001803f 778 else if (ri == r_duplicating_output_word && (redirect->rflags & REDIR_VARASSIGN) == 0 && redirector == 1)
cce855bc 779 {
0001803f 780 sd = redirect->redirector;
28ef6c31 781 rd.filename = make_bare_word (redirectee_word);
0001803f 782 new_redirect = make_redirection (sd, r_err_and_out, rd, 0);
cce855bc
JA
783 }
784 else
785 {
786 free (redirectee_word);
787 return (AMBIGUOUS_REDIRECT);
788 }
789
790 free (redirectee_word);
791
792 /* Set up the variables needed by the rest of the function from the
793 new redirection. */
794 if (new_redirect->instruction == r_err_and_out)
795 {
796 char *alloca_hack;
797
798 /* Copy the word without allocating any memory that must be
799 explicitly freed. */
800 redirectee = (WORD_DESC *)alloca (sizeof (WORD_DESC));
801 xbcopy ((char *)new_redirect->redirectee.filename,
802 (char *)redirectee, sizeof (WORD_DESC));
803
804 alloca_hack = (char *)
805 alloca (1 + strlen (new_redirect->redirectee.filename->word));
806 redirectee->word = alloca_hack;
807 strcpy (redirectee->word, new_redirect->redirectee.filename->word);
808 }
809 else
810 /* It's guaranteed to be an integer, and shouldn't be freed. */
811 redirectee = new_redirect->redirectee.filename;
812
813 redir_fd = new_redirect->redirectee.dest;
0001803f 814 redirector = new_redirect->redirector.dest;
cce855bc
JA
815 ri = new_redirect->instruction;
816
817 /* Overwrite the flags element of the old redirect with the new value. */
818 redirect->flags = new_redirect->flags;
819 dispose_redirects (new_redirect);
820 }
821
822 switch (ri)
823 {
824 case r_output_direction:
825 case r_appending_to:
826 case r_input_direction:
827 case r_inputa_direction:
828 case r_err_and_out: /* command &>filename */
3185942a 829 case r_append_err_and_out: /* command &>> filename */
cce855bc
JA
830 case r_input_output:
831 case r_output_force:
bb70624e 832 if (posixly_correct && interactive_shell == 0)
28ef6c31
JA
833 {
834 oflags = redirectee->flags;
835 redirectee->flags |= W_NOGLOB;
836 }
cce855bc 837 redirectee_word = redirection_expand (redirectee);
bb70624e
JA
838 if (posixly_correct && interactive_shell == 0)
839 redirectee->flags = oflags;
cce855bc
JA
840
841 if (redirectee_word == 0)
842 return (AMBIGUOUS_REDIRECT);
843
844#if defined (RESTRICTED_SHELL)
845 if (restricted && (WRITE_REDIRECT (ri)))
846 {
847 free (redirectee_word);
848 return (RESTRICTED_REDIRECT);
849 }
850#endif /* RESTRICTED_SHELL */
851
bb70624e 852 fd = redir_open (redirectee_word, redirect->flags, 0666, ri);
cce855bc
JA
853 free (redirectee_word);
854
bb70624e 855 if (fd == NOCLOBBER_REDIRECT)
28ef6c31 856 return (fd);
bb70624e 857
cce855bc
JA
858 if (fd < 0)
859 return (errno);
860
b80f6443 861 if (flags & RX_ACTIVE)
cce855bc 862 {
0001803f 863 if (redirect->rflags & REDIR_VARASSIGN)
495aee44
CR
864 {
865 redirector = fcntl (fd, F_DUPFD, SHELL_FD_BASE); /* XXX try this for now */
866 r = errno;
867 if (redirector < 0)
868 sys_error (_("redirection error: cannot duplicate fd"));
869 REDIRECTION_ERROR (redirector, r, fd);
870 }
0001803f 871
ac50fbac 872 if ((flags & RX_UNDOABLE) && (redirect->rflags & REDIR_VARASSIGN) == 0)
f73dda09
JA
873 {
874 /* Only setup to undo it if the thing to undo is active. */
875 if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
495aee44 876 r = add_undo_redirect (redirector, ri, -1);
f73dda09 877 else
495aee44 878 r = add_undo_close_redirect (redirector);
495aee44 879 REDIRECTION_ERROR (r, errno, fd);
f73dda09 880 }
cce855bc
JA
881
882#if defined (BUFFERED_INPUT)
ac50fbac
CR
883 /* inhibit call to sync_buffered_stream() for async processes */
884 if (redirector != 0 || (subshell_environment & SUBSHELL_ASYNC) == 0)
885 check_bash_input (redirector);
cce855bc
JA
886#endif
887
3185942a
JA
888 /* Make sure there is no pending output before we change the state
889 of the underlying file descriptor, since the builtins use stdio
890 for output. */
891 if (redirector == 1 && fileno (stdout) == redirector)
892 {
893 fflush (stdout);
894 fpurge (stdout);
895 }
896 else if (redirector == 2 && fileno (stderr) == redirector)
897 {
898 fflush (stderr);
899 fpurge (stderr);
900 }
901
0001803f
CR
902 if (redirect->rflags & REDIR_VARASSIGN)
903 {
904 if ((r = redir_varassign (redirect, redirector)) < 0)
905 {
906 close (redirector);
907 close (fd);
908 return (r); /* XXX */
909 }
910 }
911 else if ((fd != redirector) && (dup2 (fd, redirector) < 0))
a0c0a00f
CR
912 {
913 close (fd); /* dup2 failed? must be fd limit issue */
914 return (errno);
915 }
cce855bc
JA
916
917#if defined (BUFFERED_INPUT)
918 /* Do not change the buffered stream for an implicit redirection
919 of /dev/null to fd 0 for asynchronous commands without job
920 control (r_inputa_direction). */
921 if (ri == r_input_direction || ri == r_input_output)
922 duplicate_buffered_stream (fd, redirector);
923#endif /* BUFFERED_INPUT */
924
925 /*
926 * If we're remembering, then this is the result of a while, for
927 * or until loop with a loop redirection, or a function/builtin
928 * executing in the parent shell with a redirection. In the
929 * function/builtin case, we want to set all file descriptors > 2
930 * to be close-on-exec to duplicate the effect of the old
931 * for i = 3 to NOFILE close(i) loop. In the case of the loops,
932 * both sh and ksh leave the file descriptors open across execs.
933 * The Posix standard mentions only the exec builtin.
934 */
b80f6443 935 if ((flags & RX_CLEXEC) && (redirector > 2))
cce855bc
JA
936 SET_CLOSE_ON_EXEC (redirector);
937 }
938
939 if (fd != redirector)
940 {
941#if defined (BUFFERED_INPUT)
942 if (INPUT_REDIRECT (ri))
943 close_buffered_fd (fd);
944 else
945#endif /* !BUFFERED_INPUT */
946 close (fd); /* Don't close what we just opened! */
947 }
948
949 /* If we are hacking both stdout and stderr, do the stderr
0001803f 950 redirection here. XXX - handle {var} here? */
3185942a 951 if (ri == r_err_and_out || ri == r_append_err_and_out)
cce855bc 952 {
b80f6443 953 if (flags & RX_ACTIVE)
cce855bc 954 {
b80f6443 955 if (flags & RX_UNDOABLE)
3185942a 956 add_undo_redirect (2, ri, -1);
cce855bc
JA
957 if (dup2 (1, 2) < 0)
958 return (errno);
959 }
960 }
961 break;
962
963 case r_reading_until:
964 case r_deblank_reading_until:
7117c2d2 965 case r_reading_string:
cce855bc
JA
966 /* REDIRECTEE is a pointer to a WORD_DESC containing the text of
967 the new input. Place it in a temporary file. */
968 if (redirectee)
969 {
7117c2d2 970 fd = here_document_to_fd (redirectee, ri);
cce855bc
JA
971
972 if (fd < 0)
973 {
974 heredoc_errno = errno;
975 return (HEREDOC_REDIRECT);
976 }
977
0001803f 978 if (redirect->rflags & REDIR_VARASSIGN)
495aee44
CR
979 {
980 redirector = fcntl (fd, F_DUPFD, SHELL_FD_BASE); /* XXX try this for now */
981 r = errno;
982 if (redirector < 0)
983 sys_error (_("redirection error: cannot duplicate fd"));
984 REDIRECTION_ERROR (redirector, r, fd);
985 }
0001803f 986
b80f6443 987 if (flags & RX_ACTIVE)
cce855bc 988 {
ac50fbac 989 if ((flags & RX_UNDOABLE) && (redirect->rflags & REDIR_VARASSIGN) == 0)
f73dda09
JA
990 {
991 /* Only setup to undo it if the thing to undo is active. */
992 if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
495aee44 993 r = add_undo_redirect (redirector, ri, -1);
f73dda09 994 else
495aee44 995 r = add_undo_close_redirect (redirector);
495aee44 996 REDIRECTION_ERROR (r, errno, fd);
f73dda09 997 }
cce855bc
JA
998
999#if defined (BUFFERED_INPUT)
1000 check_bash_input (redirector);
1001#endif
0001803f
CR
1002 if (redirect->rflags & REDIR_VARASSIGN)
1003 {
1004 if ((r = redir_varassign (redirect, redirector)) < 0)
1005 {
1006 close (redirector);
1007 close (fd);
1008 return (r); /* XXX */
1009 }
1010 }
1011 else if (fd != redirector && dup2 (fd, redirector) < 0)
cce855bc
JA
1012 {
1013 r = errno;
1014 close (fd);
1015 return (r);
1016 }
1017
1018#if defined (BUFFERED_INPUT)
1019 duplicate_buffered_stream (fd, redirector);
1020#endif
1021
b80f6443 1022 if ((flags & RX_CLEXEC) && (redirector > 2))
cce855bc
JA
1023 SET_CLOSE_ON_EXEC (redirector);
1024 }
1025
bb70624e 1026 if (fd != redirector)
cce855bc 1027#if defined (BUFFERED_INPUT)
bb70624e 1028 close_buffered_fd (fd);
cce855bc 1029#else
bb70624e 1030 close (fd);
cce855bc
JA
1031#endif
1032 }
1033 break;
1034
1035 case r_duplicating_input:
1036 case r_duplicating_output:
7117c2d2
JA
1037 case r_move_input:
1038 case r_move_output:
0001803f 1039 if ((flags & RX_ACTIVE) && (redirect->rflags & REDIR_VARASSIGN))
495aee44
CR
1040 {
1041 redirector = fcntl (redir_fd, F_DUPFD, SHELL_FD_BASE); /* XXX try this for now */
1042 r = errno;
1043 if (redirector < 0)
1044 sys_error (_("redirection error: cannot duplicate fd"));
1045 REDIRECTION_ERROR (redirector, r, -1);
1046 }
0001803f 1047
b80f6443 1048 if ((flags & RX_ACTIVE) && (redir_fd != redirector))
cce855bc 1049 {
ac50fbac 1050 if ((flags & RX_UNDOABLE) && (redirect->rflags & REDIR_VARASSIGN) == 0)
f73dda09
JA
1051 {
1052 /* Only setup to undo it if the thing to undo is active. */
1053 if (fcntl (redirector, F_GETFD, 0) != -1)
495aee44 1054 r = add_undo_redirect (redirector, ri, redir_fd);
f73dda09 1055 else
495aee44 1056 r = add_undo_close_redirect (redirector);
495aee44 1057 REDIRECTION_ERROR (r, errno, -1);
f73dda09 1058 }
f281b8f4
CR
1059 if ((flags & RX_UNDOABLE) && (ri == r_move_input || ri == r_move_output))
1060 {
1061 /* r_move_input and r_move_output add an additional close()
1062 that needs to be undone */
1063 if (fcntl (redirector, F_GETFD, 0) != -1)
1064 {
1065 r = add_undo_redirect (redir_fd, r_close_this, -1);
1066 REDIRECTION_ERROR (r, errno, -1);
1067 }
1068 }
cce855bc 1069#if defined (BUFFERED_INPUT)
ac50fbac
CR
1070 /* inhibit call to sync_buffered_stream() for async processes */
1071 if (redirector != 0 || (subshell_environment & SUBSHELL_ASYNC) == 0)
1072 check_bash_input (redirector);
cce855bc 1073#endif
0001803f
CR
1074 if (redirect->rflags & REDIR_VARASSIGN)
1075 {
1076 if ((r = redir_varassign (redirect, redirector)) < 0)
1077 {
1078 close (redirector);
1079 return (r); /* XXX */
1080 }
1081 }
cce855bc 1082 /* This is correct. 2>&1 means dup2 (1, 2); */
0001803f 1083 else if (dup2 (redir_fd, redirector) < 0)
cce855bc
JA
1084 return (errno);
1085
1086#if defined (BUFFERED_INPUT)
7117c2d2 1087 if (ri == r_duplicating_input || ri == r_move_input)
cce855bc
JA
1088 duplicate_buffered_stream (redir_fd, redirector);
1089#endif /* BUFFERED_INPUT */
1090
1091 /* First duplicate the close-on-exec state of redirectee. dup2
1092 leaves the flag unset on the new descriptor, which means it
1093 stays open. Only set the close-on-exec bit for file descriptors
1094 greater than 2 in any case, since 0-2 should always be open
95732b49
JA
1095 unless closed by something like `exec 2<&-'. It should always
1096 be safe to set fds > 2 to close-on-exec if they're being used to
1097 save file descriptors < 2, since we don't need to preserve the
1098 state of the close-on-exec flag for those fds -- they should
1099 always be open. */
cce855bc
JA
1100 /* if ((already_set || set_unconditionally) && (ok_to_set))
1101 set_it () */
95732b49
JA
1102#if 0
1103 if (((fcntl (redir_fd, F_GETFD, 0) == 1) || redir_fd < 2 || (flags & RX_CLEXEC)) &&
1104 (redirector > 2))
1105#else
1106 if (((fcntl (redir_fd, F_GETFD, 0) == 1) || (redir_fd < 2 && (flags & RX_INTERNAL)) || (flags & RX_CLEXEC)) &&
cce855bc 1107 (redirector > 2))
95732b49 1108#endif
cce855bc 1109 SET_CLOSE_ON_EXEC (redirector);
7117c2d2 1110
3185942a
JA
1111 /* When undoing saving of non-standard file descriptors (>=3) using
1112 file descriptors >= SHELL_FD_BASE, we set the saving fd to be
1113 close-on-exec and use a flag to decide how to set close-on-exec
1114 when the fd is restored. */
ac50fbac 1115 if ((redirect->flags & RX_INTERNAL) && (redirect->flags & RX_SAVCLEXEC) && redirector >= 3 && (redir_fd >= SHELL_FD_BASE || (redirect->flags & RX_SAVEFD)))
3185942a
JA
1116 SET_OPEN_ON_EXEC (redirector);
1117
7117c2d2
JA
1118 /* dup-and-close redirection */
1119 if (ri == r_move_input || ri == r_move_output)
3185942a 1120 {
0001803f
CR
1121 xtrace_fdchk (redir_fd);
1122
3185942a
JA
1123 close (redir_fd);
1124#if defined (COPROCESS_SUPPORT)
1125 coproc_fdchk (redir_fd); /* XXX - loses coproc fds */
1126#endif
1127 }
cce855bc
JA
1128 }
1129 break;
1130
1131 case r_close_this:
b80f6443 1132 if (flags & RX_ACTIVE)
cce855bc 1133 {
0001803f
CR
1134 if (redirect->rflags & REDIR_VARASSIGN)
1135 {
1136 redirector = redir_varvalue (redirect);
1137 if (redirector < 0)
1138 return AMBIGUOUS_REDIRECT;
1139 }
1140
495aee44 1141 r = 0;
ac50fbac 1142 /* XXX - only if REDIR_VARASSIGN not set? */
b80f6443 1143 if ((flags & RX_UNDOABLE) && (fcntl (redirector, F_GETFD, 0) != -1))
495aee44
CR
1144 {
1145 r = add_undo_redirect (redirector, ri, -1);
1146 REDIRECTION_ERROR (r, errno, redirector);
1147 }
3185942a
JA
1148
1149#if defined (COPROCESS_SUPPORT)
1150 coproc_fdchk (redirector);
1151#endif
0001803f 1152 xtrace_fdchk (redirector);
cce855bc
JA
1153
1154#if defined (BUFFERED_INPUT)
ac50fbac
CR
1155 /* inhibit call to sync_buffered_stream() for async processes */
1156 if (redirector != 0 || (subshell_environment & SUBSHELL_ASYNC) == 0)
1157 check_bash_input (redirector);
774d3bf6 1158 r = close_buffered_fd (redirector);
cce855bc 1159#else /* !BUFFERED_INPUT */
774d3bf6 1160 r = close (redirector);
cce855bc 1161#endif /* !BUFFERED_INPUT */
ac50fbac 1162
774d3bf6
CR
1163 if (r < 0 && (flags & RX_INTERNAL) && (errno == EIO || errno == ENOSPC))
1164 REDIRECTION_ERROR (r, errno, -1);
cce855bc
JA
1165 }
1166 break;
1167
1168 case r_duplicating_input_word:
1169 case r_duplicating_output_word:
1170 break;
1171 }
1172 return (0);
1173}
1174
cce855bc
JA
1175/* Remember the file descriptor associated with the slot FD,
1176 on REDIRECTION_UNDO_LIST. Note that the list will be reversed
1177 before it is executed. Any redirections that need to be undone
1178 even if REDIRECTION_UNDO_LIST is discarded by the exec builtin
3185942a
JA
1179 are also saved on EXEC_REDIRECTION_UNDO_LIST. FDBASE says where to
1180 start the duplicating. If it's less than SHELL_FD_BASE, we're ok,
1181 and can use SHELL_FD_BASE (-1 == don't care). If it's >= SHELL_FD_BASE,
1182 we have to make sure we don't use fdbase to save a file descriptor,
1183 since we're going to use it later (e.g., make sure we don't save fd 0
1184 to fd 10 if we have a redirection like 0<&10). If the value of fdbase
1185 puts the process over its fd limit, causing fcntl to fail, we try
495aee44 1186 again with SHELL_FD_BASE. Return 0 on success, -1 on error. */
cce855bc 1187static int
3185942a 1188add_undo_redirect (fd, ri, fdbase)
cce855bc 1189 int fd;
0628567a 1190 enum r_instruction ri;
3185942a 1191 int fdbase;
cce855bc 1192{
ac50fbac 1193 int new_fd, clexec_flag, savefd_flag;
cce855bc 1194 REDIRECT *new_redirect, *closer, *dummy_redirect;
0001803f 1195 REDIRECTEE sd;
cce855bc 1196
ac50fbac 1197 savefd_flag = 0;
3185942a
JA
1198 new_fd = fcntl (fd, F_DUPFD, (fdbase < SHELL_FD_BASE) ? SHELL_FD_BASE : fdbase+1);
1199 if (new_fd < 0)
1200 new_fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
ac50fbac
CR
1201 if (new_fd < 0)
1202 {
1203 new_fd = fcntl (fd, F_DUPFD, 0);
1204 savefd_flag = 1;
1205 }
cce855bc
JA
1206
1207 if (new_fd < 0)
1208 {
b80f6443 1209 sys_error (_("redirection error: cannot duplicate fd"));
cce855bc
JA
1210 return (-1);
1211 }
1212
1213 clexec_flag = fcntl (fd, F_GETFD, 0);
1214
0001803f 1215 sd.dest = new_fd;
f73dda09 1216 rd.dest = 0;
0001803f 1217 closer = make_redirection (sd, r_close_this, rd, 0);
95732b49 1218 closer->flags |= RX_INTERNAL;
cce855bc
JA
1219 dummy_redirect = copy_redirects (closer);
1220
0001803f 1221 sd.dest = fd;
f73dda09 1222 rd.dest = new_fd;
28ef6c31 1223 if (fd == 0)
0001803f 1224 new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
28ef6c31 1225 else
0001803f 1226 new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
95732b49 1227 new_redirect->flags |= RX_INTERNAL;
ac50fbac
CR
1228 if (savefd_flag)
1229 new_redirect->flags |= RX_SAVEFD;
1230 if (clexec_flag == 0 && fd >= 3 && (new_fd >= SHELL_FD_BASE || savefd_flag))
3185942a 1231 new_redirect->flags |= RX_SAVCLEXEC;
cce855bc
JA
1232 new_redirect->next = closer;
1233
1234 closer->next = redirection_undo_list;
1235 redirection_undo_list = new_redirect;
1236
1237 /* Save redirections that need to be undone even if the undo list
1238 is thrown away by the `exec' builtin. */
1239 add_exec_redirect (dummy_redirect);
1240
95732b49
JA
1241 /* experimental: if we're saving a redirection to undo for a file descriptor
1242 above SHELL_FD_BASE, add a redirection to be undone if the exec builtin
3185942a
JA
1243 causes redirections to be discarded. There needs to be a difference
1244 between fds that are used to save other fds and then are the target of
495aee44 1245 user redirections and fds that are just the target of user redirections.
3185942a
JA
1246 We use the close-on-exec flag to tell the difference; fds > SHELL_FD_BASE
1247 that have the close-on-exec flag set are assumed to be fds used internally
1248 to save others. */
1249 if (fd >= SHELL_FD_BASE && ri != r_close_this && clexec_flag)
95732b49 1250 {
0001803f 1251 sd.dest = fd;
95732b49 1252 rd.dest = new_fd;
0001803f 1253 new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
3185942a
JA
1254 new_redirect->flags |= RX_INTERNAL;
1255
95732b49 1256 add_exec_redirect (new_redirect);
95732b49
JA
1257 }
1258
cce855bc
JA
1259 /* File descriptors used only for saving others should always be
1260 marked close-on-exec. Unfortunately, we have to preserve the
1261 close-on-exec state of the file descriptor we are saving, since
1262 fcntl (F_DUPFD) sets the new file descriptor to remain open
1263 across execs. If, however, the file descriptor whose state we
1264 are saving is <= 2, we can just set the close-on-exec flag,
1265 because file descriptors 0-2 should always be open-on-exec,
1266 and the restore above in do_redirection() will take care of it. */
1267 if (clexec_flag || fd < 3)
1268 SET_CLOSE_ON_EXEC (new_fd);
3185942a
JA
1269 else if (redirection_undo_list->flags & RX_SAVCLEXEC)
1270 SET_CLOSE_ON_EXEC (new_fd);
cce855bc
JA
1271
1272 return (0);
1273}
1274
1275/* Set up to close FD when we are finished with the current command
495aee44
CR
1276 and its redirections. Return 0 on success, -1 on error. */
1277static int
cce855bc
JA
1278add_undo_close_redirect (fd)
1279 int fd;
1280{
1281 REDIRECT *closer;
0001803f 1282 REDIRECTEE sd;
cce855bc 1283
0001803f 1284 sd.dest = fd;
f73dda09 1285 rd.dest = 0;
0001803f 1286 closer = make_redirection (sd, r_close_this, rd, 0);
95732b49 1287 closer->flags |= RX_INTERNAL;
cce855bc
JA
1288 closer->next = redirection_undo_list;
1289 redirection_undo_list = closer;
495aee44
CR
1290
1291 return 0;
cce855bc
JA
1292}
1293
1294static void
1295add_exec_redirect (dummy_redirect)
1296 REDIRECT *dummy_redirect;
1297{
1298 dummy_redirect->next = exec_redirection_undo_list;
1299 exec_redirection_undo_list = dummy_redirect;
1300}
1301
bb70624e
JA
1302/* Return 1 if the redirection specified by RI and REDIRECTOR alters the
1303 standard input. */
1304static int
1305stdin_redirection (ri, redirector)
1306 enum r_instruction ri;
1307 int redirector;
1308{
1309 switch (ri)
1310 {
1311 case r_input_direction:
1312 case r_inputa_direction:
1313 case r_input_output:
1314 case r_reading_until:
1315 case r_deblank_reading_until:
7117c2d2 1316 case r_reading_string:
bb70624e
JA
1317 return (1);
1318 case r_duplicating_input:
1319 case r_duplicating_input_word:
1320 case r_close_this:
1321 return (redirector == 0);
1322 case r_output_direction:
1323 case r_appending_to:
1324 case r_duplicating_output:
1325 case r_err_and_out:
3185942a 1326 case r_append_err_and_out:
bb70624e
JA
1327 case r_output_force:
1328 case r_duplicating_output_word:
1329 return (0);
1330 }
1331 return (0);
1332}
1333
cce855bc
JA
1334/* Return non-zero if any of the redirections in REDIRS alter the standard
1335 input. */
1336int
1337stdin_redirects (redirs)
1338 REDIRECT *redirs;
1339{
1340 REDIRECT *rp;
1341 int n;
1342
1343 for (n = 0, rp = redirs; rp; rp = rp->next)
0001803f
CR
1344 if ((rp->rflags & REDIR_VARASSIGN) == 0)
1345 n += stdin_redirection (rp->instruction, rp->redirector.dest);
cce855bc
JA
1346 return n;
1347}
ac50fbac 1348/* bind_var_to_int handles array references */
0001803f
CR
1349static int
1350redir_varassign (redir, fd)
1351 REDIRECT *redir;
1352 int fd;
1353{
1354 WORD_DESC *w;
1355 SHELL_VAR *v;
1356
1357 w = redir->redirector.filename;
1358 v = bind_var_to_int (w->word, fd);
1359 if (v == 0 || readonly_p (v) || noassign_p (v))
1360 return BADVAR_REDIRECT;
1361
ac50fbac 1362 stupidly_hack_special_variables (w->word);
0001803f
CR
1363 return 0;
1364}
1365
ac50fbac 1366/* Handles {array[ind]} for redirection words */
0001803f
CR
1367static int
1368redir_varvalue (redir)
1369 REDIRECT *redir;
1370{
1371 SHELL_VAR *v;
ac50fbac 1372 char *val, *w;
0001803f
CR
1373 intmax_t vmax;
1374 int i;
ac50fbac
CR
1375#if defined (ARRAY_VARS)
1376 char *sub;
1377 int len, vr;
1378#endif
0001803f 1379
ac50fbac 1380 w = redir->redirector.filename->word; /* shorthand */
0001803f 1381 /* XXX - handle set -u here? */
ac50fbac 1382#if defined (ARRAY_VARS)
a0c0a00f
CR
1383 if (vr = valid_array_reference (w, 0))
1384 {
1385 v = array_variable_part (w, &sub, &len);
1386 }
ac50fbac
CR
1387 else
1388#endif
a0c0a00f
CR
1389 {
1390 v = find_variable (w);
1391#if defined (ARRAY_VARS)
1392 if (v == 0)
1393 {
1394 v = find_variable_last_nameref (w, 0);
1395 if (v && nameref_p (v))
1396 {
1397 w = nameref_cell (v);
1398 if (vr = valid_array_reference (w, 0))
1399 v = array_variable_part (w, &sub, &len);
1400 else
1401 v = find_variable (w);
1402 }
1403 }
1404#endif
1405 }
1406
0001803f
CR
1407 if (v == 0 || invisible_p (v))
1408 return -1;
1409
ac50fbac
CR
1410#if defined (ARRAY_VARS)
1411 /* get_variable_value handles references to array variables without
1412 subscripts */
1413 if (vr && (array_p (v) || assoc_p (v)))
1414 val = get_array_value (w, 0, (int *)NULL, (arrayind_t *)0);
1415 else
1416#endif
0001803f
CR
1417 val = get_variable_value (v);
1418 if (val == 0 || *val == 0)
1419 return -1;
1420
1421 if (legal_number (val, &vmax) < 0)
1422 return -1;
1423
1424 i = vmax; /* integer truncation */
1425 return i;
1426}