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