aboutsummaryrefslogtreecommitdiffstats
path: root/redir.c
diff options
context:
space:
mode:
authorJari Aalto <jari.aalto@cante.net>2002-07-17 14:10:11 +0000
committerJari Aalto <jari.aalto@cante.net>2009-09-12 16:46:55 +0000
commit7117c2d221b2aed4ede8600f6a36b7c1454b4f55 (patch)
treeb792f26ecca68813c51ed5ba2e381790758ef31b /redir.c
parentf73dda092b33638d2d5e9c35375f687a607b5403 (diff)
downloadandroid_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.c105
1 files changed, 87 insertions, 18 deletions
diff --git a/redir.c b/redir.c
index 6fdcc94..e420011 100644
--- a/redir.c
+++ b/redir.c
@@ -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: