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