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