diff options
| author | Jari Aalto <jari.aalto@cante.net> | 2002-07-17 14:10:11 +0000 |
|---|---|---|
| committer | Jari Aalto <jari.aalto@cante.net> | 2009-09-12 16:46:55 +0000 |
| commit | 7117c2d221b2aed4ede8600f6a36b7c1454b4f55 (patch) | |
| tree | b792f26ecca68813c51ed5ba2e381790758ef31b /redir.c | |
| parent | f73dda092b33638d2d5e9c35375f687a607b5403 (diff) | |
| download | android_external_bash-7117c2d221b2aed4ede8600f6a36b7c1454b4f55.tar.gz android_external_bash-7117c2d221b2aed4ede8600f6a36b7c1454b4f55.tar.bz2 android_external_bash-7117c2d221b2aed4ede8600f6a36b7c1454b4f55.zip | |
Imported from ../bash-2.05b.tar.gz.
Diffstat (limited to 'redir.c')
| -rw-r--r-- | redir.c | 105 |
1 files changed, 87 insertions, 18 deletions
@@ -1,6 +1,6 @@ /* redir.c -- Functions to perform input and output redirection. */ -/* Copyright (C) 1997 Free Software Foundation, Inc. +/* Copyright (C) 1997-2002 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -66,14 +66,15 @@ static int stdin_redirection __P((enum r_instruction, int)); static int do_redirection_internal __P((REDIRECT *, int, int, int)); static int write_here_document __P((int, WORD_DESC *)); -static int here_document_to_fd __P((WORD_DESC *)); +static int write_here_string __P((int, WORD_DESC *)); +static int here_document_to_fd __P((WORD_DESC *, enum r_instruction)); static int redir_special_open __P((int, char *, int, int, enum r_instruction)); static int noclobber_open __P((char *, int, int, enum r_instruction)); static int redir_open __P((char *, int, int, enum r_instruction)); -/* Spare redirector used when translating [N]>&WORD or [N]<&WORD to a new - redirection and when creating the redirection undo list. */ +/* Spare redirector used when translating [N]>&WORD[-] or [N]<&WORD[-] to + a new redirection and when creating the redirection undo list. */ static REDIRECTEE rd; /* Set to errno when a here document cannot be created for some reason. @@ -95,7 +96,23 @@ redirection_error (temp, error) filename = "file descriptor out of range"; #ifdef EBADF else if (temp->redirector >= 0 && errno == EBADF) - filename = allocname = itos (temp->redirector); + { + /* If we're dealing with two file descriptors, we have to guess about + which one is invalid; in the cases of r_{duplicating,move}_input and + r_{duplicating,move}_output we're here because dup2() failed. */ + switch (temp->instruction) + { + case r_duplicating_input: + case r_duplicating_output: + case r_move_input: + case r_move_output: + filename = allocname = itos (temp->redirectee.dest); + break; + default: + filename = allocname = itos (temp->redirector); + break; + } + } #endif else if (expandable_redirection_filename (temp)) { @@ -197,6 +214,8 @@ expandable_redirection_filename (redirect) case r_output_force: case r_duplicating_input_word: case r_duplicating_output_word: + case r_move_input_word: + case r_move_output_word: return 1; default: @@ -235,6 +254,34 @@ redirection_expand (word) return (result); } +static int +write_here_string (fd, redirectee) + int fd; + WORD_DESC *redirectee; +{ + char *herestr; + int herelen, n, e; + + herestr = expand_string_to_string (redirectee->word, 0); + herelen = strlen (herestr); + + n = write (fd, herestr, herelen); + if (n == herelen) + { + n = write (fd, "\n", 1); + herelen = 1; + } + e = errno; + free (herestr); + if (n != herelen) + { + if (e == 0) + e = ENOSPC; + return e; + } + return 0; +} + /* Write the text of the here document pointed to by REDIRECTEE to the file descriptor FD, which is already open to a temp file. Return 0 if the write is successful, otherwise return errno. */ @@ -316,8 +363,9 @@ write_here_document (fd, redirectee) by REDIRECTEE, and return a file descriptor open for reading to the temp file. Return -1 on any error, and make sure errno is set appropriately. */ static int -here_document_to_fd (redirectee) +here_document_to_fd (redirectee, ri) WORD_DESC *redirectee; + enum r_instruction ri; { char *filename; int r, fd, fd2; @@ -334,7 +382,8 @@ here_document_to_fd (redirectee) errno = r = 0; /* XXX */ /* write_here_document returns 0 on success, errno on failure. */ if (redirectee->word) - r = write_here_document (fd, redirectee); + r = (ri != r_reading_string) ? write_here_document (fd, redirectee) + : write_here_string (fd, redirectee); if (r) { @@ -416,7 +465,7 @@ redir_special_open (spec, filename, flags, mode, ri) { int fd; #if !defined (HAVE_DEV_FD) - long lfd; + intmax_t lfd; #endif fd = -1; @@ -562,7 +611,7 @@ do_redirection_internal (redirect, for_real, remembering, set_clexec) { WORD_DESC *redirectee; int redir_fd, fd, redirector, r, oflags; - long lfd; + intmax_t lfd; char *redirectee_word; enum r_instruction ri; REDIRECT *new_redirect; @@ -572,12 +621,14 @@ do_redirection_internal (redirect, for_real, remembering, set_clexec) redirector = redirect->redirector; ri = redirect->instruction; - if (ri == r_duplicating_input_word || ri == r_duplicating_output_word) + if (TRANSLATE_REDIRECT (ri)) { - /* We have [N]>&WORD or [N]<&WORD. Expand WORD, then translate + /* We have [N]>&WORD[-] or [N]<&WORD[-]. Expand WORD, then translate the redirection into a new one and continue. */ redirectee_word = redirection_expand (redirectee); + /* XXX - what to do with [N]<&$w- where w is unset or null? ksh93 + closes N. */ if (redirectee_word == 0) return (AMBIGUOUS_REDIRECT); else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0') @@ -591,11 +642,21 @@ do_redirection_internal (redirect, for_real, remembering, set_clexec) rd.dest = lfd; else rd.dest = -1; /* XXX */ - new_redirect = make_redirection (redirector, - (ri == r_duplicating_input_word - ? r_duplicating_input - : r_duplicating_output), - rd); + switch (ri) + { + case r_duplicating_input_word: + new_redirect = make_redirection (redirector, r_duplicating_input, rd); + break; + case r_duplicating_output_word: + new_redirect = make_redirection (redirector, r_duplicating_output, rd); + break; + case r_move_input_word: + new_redirect = make_redirection (redirector, r_move_input, rd); + break; + case r_move_output_word: + new_redirect = make_redirection (redirector, r_move_output, rd); + break; + } } else if (ri == r_duplicating_output_word && redirector == 1) { @@ -744,11 +805,12 @@ do_redirection_internal (redirect, for_real, remembering, set_clexec) case r_reading_until: case r_deblank_reading_until: + case r_reading_string: /* REDIRECTEE is a pointer to a WORD_DESC containing the text of the new input. Place it in a temporary file. */ if (redirectee) { - fd = here_document_to_fd (redirectee); + fd = here_document_to_fd (redirectee, ri); if (fd < 0) { @@ -796,6 +858,8 @@ do_redirection_internal (redirect, for_real, remembering, set_clexec) case r_duplicating_input: case r_duplicating_output: + case r_move_input: + case r_move_output: if (for_real && (redir_fd != redirector)) { if (remembering) @@ -815,7 +879,7 @@ do_redirection_internal (redirect, for_real, remembering, set_clexec) return (errno); #if defined (BUFFERED_INPUT) - if (ri == r_duplicating_input) + if (ri == r_duplicating_input || ri == r_move_input) duplicate_buffered_stream (redir_fd, redirector); #endif /* BUFFERED_INPUT */ @@ -829,6 +893,10 @@ do_redirection_internal (redirect, for_real, remembering, set_clexec) if (((fcntl (redir_fd, F_GETFD, 0) == 1) || set_clexec) && (redirector > 2)) SET_CLOSE_ON_EXEC (redirector); + + /* dup-and-close redirection */ + if (ri == r_move_input || ri == r_move_output) + close (redir_fd); } break; @@ -946,6 +1014,7 @@ stdin_redirection (ri, redirector) case r_input_output: case r_reading_until: case r_deblank_reading_until: + case r_reading_string: return (1); case r_duplicating_input: case r_duplicating_input_word: |
