Imported from ../bash-2.05b.tar.gz.

This commit is contained in:
Jari Aalto 2002-07-17 14:10:11 +00:00
commit 7117c2d221
362 changed files with 34387 additions and 15063 deletions

105
redir.c
View file

@ -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: