Imported from ../bash-2.05b.tar.gz.
This commit is contained in:
parent
f73dda092b
commit
7117c2d221
362 changed files with 34387 additions and 15063 deletions
105
redir.c
105
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:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue