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