commit bash-20090910 snapshot

This commit is contained in:
Chet Ramey
2011-12-08 20:15:36 -05:00
parent 824dfe6803
commit e6dfa71744
17 changed files with 2201 additions and 102 deletions
+34
View File
@@ -8767,3 +8767,37 @@ variables.c
bashline.c
- fix to bash_execute_unix_command to avoid possible null pointer
dereference if READLINE_LINE or READLINE_POINT is not bound
9/11
----
[Prayers for the victimes of 9/11/2001]
command.h
- add `rflags' member to struct redirect to hold private flags and
state information
- change redirector to a REDIRECTEE instead of int to prepare for
possible future changes
{copy_cmd,dispose_cmd,make_cmd,print_cmd,redir}.c
- changes resulting from type change of `redirector' member of struct
redirect: change x->redirector to x->redirector.dest and add code
where appropriate to deal with x->redirector.filename
make_cmd.h
- change extern declaration for make_redirection
make_cmd.c
- first argument of make_redirection is now a `REDIRECTEE' to prepare
for possible future changes. First arg is now assigned directly to
redirector member instead of assigning int to redirector.dest
{make_cmd,redir}.c,parse.y
- changes resulting from type change of first argument to
make_redirection from int to REDIRECTEE. In general, changes are
using REDIRECTEE sd and assigning old argument to sd.dest, then
passing sd to make_redirection
make_cmd.[ch],parse.y
- add fourth argument to make_redirection: flags. Sets initial value
of `rflags' member of struct redirect
- changed all callers of make_redirection to add fourth argument of 0
+33
View File
@@ -8763,3 +8763,36 @@ builtins/mapfile.def
variables.c
- fix to valid_exportstr to avoid possible null pointer dereferences
pointed out by clang/scan-build
bashline.c
- fix to bash_execute_unix_command to avoid possible null pointer
dereference if READLINE_LINE or READLINE_POINT is not bound
9/11
----
[Prayers for the victimes of 9/11/2001]
command.h
- add `rflags' member to struct redirect to hold private flags and
state information
- change redirector to a REDIRECTEE instead of int to prepare for
possible future changes
{copy_cmd,dispose_cmd,make_cmd,print_cmd,redir}.c
- changes resulting from type change of `redirector' member of struct
redirect: change x->redirector to x->redirector.dest and add code
where appropriate to deal with x->redirector.filename
make_cmd.h
- change extern declaration for make_redirection
make_cmd.c
- first argument of make_redirection is now a `REDIRECTEE' to prepare
for possible future changes. First arg is now assigned directly to
redirector member instead of assigning int to redirector.dest
{make_cmd,redir}.c,parse.y
- changes resulting from type change of first argument to
make_redirection from int to REDIRECTEE. In general, changes are
using REDIRECTEE sd and assigning old argument to sd.dest, then
passing sd to make_redirection
+6 -1
View File
@@ -35,11 +35,15 @@ enum r_instruction {
r_append_err_and_out
};
/* Redirection flags; values for rflags */
#define REDIR_VARASSIGN 0x01
/* Redirection errors. */
#define AMBIGUOUS_REDIRECT -1
#define NOCLOBBER_REDIRECT -2
#define RESTRICTED_REDIRECT -3 /* can only happen in restricted shells. */
#define HEREDOC_REDIRECT -4 /* here-doc temp file can't be created */
#define BADVAR_REDIRECT -5 /* something wrong with {varname}redir */
#define CLOBBERING_REDIRECT(ri) \
(ri == r_output_direction || ri == r_err_and_out)
@@ -135,7 +139,8 @@ typedef union {
(or translator in redir.c) encountered an out-of-range file descriptor. */
typedef struct redirect {
struct redirect *next; /* Next element, or NULL. */
int redirector; /* Descriptor to be redirected. */
REDIRECTEE redirector; /* Descriptor or varname to be redirected. */
int rflags; /* Private flags for this redirection */
int flags; /* Flag value for `open'. */
enum r_instruction instruction; /* What to do with the information. */
REDIRECTEE redirectee; /* File descriptor or filename */
+384
View File
@@ -0,0 +1,384 @@
/* command.h -- The structures used internally to represent commands, and
the extern declarations of the functions used to create them. */
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_COMMAND_H_)
#define _COMMAND_H_
#include "stdc.h"
/* Instructions describing what kind of thing to do for a redirection. */
enum r_instruction {
r_output_direction, r_input_direction, r_inputa_direction,
r_appending_to, r_reading_until, r_reading_string,
r_duplicating_input, r_duplicating_output, r_deblank_reading_until,
r_close_this, r_err_and_out, r_input_output, r_output_force,
r_duplicating_input_word, r_duplicating_output_word,
r_move_input, r_move_output, r_move_input_word, r_move_output_word,
r_append_err_and_out
};
/* Redirection flags; values for rflags */
#define REDIR_VARASSIGN 0x01
/* Redirection errors. */
#define AMBIGUOUS_REDIRECT -1
#define NOCLOBBER_REDIRECT -2
#define RESTRICTED_REDIRECT -3 /* can only happen in restricted shells. */
#define HEREDOC_REDIRECT -4 /* here-doc temp file can't be created */
#define BADVAR_REDIRECT -5 /* something wrong with {varname}redir
#define CLOBBERING_REDIRECT(ri) \
(ri == r_output_direction || ri == r_err_and_out)
#define OUTPUT_REDIRECT(ri) \
(ri == r_output_direction || ri == r_input_output || ri == r_err_and_out || ri == r_append_err_and_out)
#define INPUT_REDIRECT(ri) \
(ri == r_input_direction || ri == r_inputa_direction || ri == r_input_output)
#define WRITE_REDIRECT(ri) \
(ri == r_output_direction || \
ri == r_input_output || \
ri == r_err_and_out || \
ri == r_appending_to || \
ri == r_append_err_and_out || \
ri == r_output_force)
/* redirection needs translation */
#define TRANSLATE_REDIRECT(ri) \
(ri == r_duplicating_input_word || ri == r_duplicating_output_word || \
ri == r_move_input_word || ri == r_move_output_word)
/* Command Types: */
enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
cm_connection, cm_function_def, cm_until, cm_group,
cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc };
/* Possible values for the `flags' field of a WORD_DESC. */
#define W_HASDOLLAR 0x000001 /* Dollar sign present. */
#define W_QUOTED 0x000002 /* Some form of quote character is present. */
#define W_ASSIGNMENT 0x000004 /* This word is a variable assignment. */
#define W_GLOBEXP 0x000008 /* This word is the result of a glob expansion. */
#define W_NOSPLIT 0x000010 /* Do not perform word splitting on this word. */
#define W_NOGLOB 0x000020 /* Do not perform globbing on this word. */
#define W_NOSPLIT2 0x000040 /* Don't split word except for $@ expansion. */
#define W_TILDEEXP 0x000080 /* Tilde expand this assignment word */
#define W_DOLLARAT 0x000100 /* $@ and its special handling */
#define W_DOLLARSTAR 0x000200 /* $* and its special handling */
#define W_NOCOMSUB 0x000400 /* Don't perform command substitution on this word */
#define W_ASSIGNRHS 0x000800 /* Word is rhs of an assignment statement */
#define W_NOTILDE 0x001000 /* Don't perform tilde expansion on this word */
#define W_ITILDE 0x002000 /* Internal flag for word expansion */
#define W_NOEXPAND 0x004000 /* Don't expand at all -- do quote removal */
#define W_COMPASSIGN 0x008000 /* Compound assignment */
#define W_ASSNBLTIN 0x010000 /* word is a builtin command that takes assignments */
#define W_ASSIGNARG 0x020000 /* word is assignment argument to command */
#define W_HASQUOTEDNULL 0x040000 /* word contains a quoted null character */
#define W_DQUOTE 0x080000 /* word should be treated as if double-quoted */
#define W_NOPROCSUB 0x100000 /* don't perform process substitution */
#define W_HASCTLESC 0x200000 /* word contains literal CTLESC characters */
#define W_ASSIGNASSOC 0x400000 /* word looks like associative array assignment */
/* Possible values for subshell_environment */
#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */
#define SUBSHELL_PAREN 0x02 /* subshell caused by ( ... ) */
#define SUBSHELL_COMSUB 0x04 /* subshell caused by `command` or $(command) */
#define SUBSHELL_FORK 0x08 /* subshell caused by executing a disk command */
#define SUBSHELL_PIPE 0x10 /* subshell from a pipeline element */
#define SUBSHELL_PROCSUB 0x20 /* subshell caused by <(command) or >(command) */
#define SUBSHELL_COPROC 0x40 /* subshell from a coproc pipeline */
/* A structure which represents a word. */
typedef struct word_desc {
char *word; /* Zero terminated string. */
int flags; /* Flags associated with this word. */
} WORD_DESC;
/* A linked list of words. */
typedef struct word_list {
struct word_list *next;
WORD_DESC *word;
} WORD_LIST;
/* **************************************************************** */
/* */
/* Shell Command Structs */
/* */
/* **************************************************************** */
/* What a redirection descriptor looks like. If the redirection instruction
is ri_duplicating_input or ri_duplicating_output, use DEST, otherwise
use the file in FILENAME. Out-of-range descriptors are identified by a
negative DEST. */
typedef union {
int dest; /* Place to redirect REDIRECTOR to, or ... */
WORD_DESC *filename; /* filename to redirect to. */
} REDIRECTEE;
/* Structure describing a redirection. If REDIRECTOR is negative, the parser
(or translator in redir.c) encountered an out-of-range file descriptor. */
typedef struct redirect {
struct redirect *next; /* Next element, or NULL. */
REDIRECTEE redirector; /* Descriptor or varname to be redirected. */
int rflags; /* Private flags for this redirection */
int flags; /* Flag value for `open'. */
enum r_instruction instruction; /* What to do with the information. */
REDIRECTEE redirectee; /* File descriptor or filename */
char *here_doc_eof; /* The word that appeared in <<foo. */
} REDIRECT;
/* An element used in parsing. A single word or a single redirection.
This is an ephemeral construct. */
typedef struct element {
WORD_DESC *word;
REDIRECT *redirect;
} ELEMENT;
/* Possible values for command->flags. */
#define CMD_WANT_SUBSHELL 0x01 /* User wants a subshell: ( command ) */
#define CMD_FORCE_SUBSHELL 0x02 /* Shell needs to force a subshell. */
#define CMD_INVERT_RETURN 0x04 /* Invert the exit value. */
#define CMD_IGNORE_RETURN 0x08 /* Ignore the exit value. For set -e. */
#define CMD_NO_FUNCTIONS 0x10 /* Ignore functions during command lookup. */
#define CMD_INHIBIT_EXPANSION 0x20 /* Do not expand the command words. */
#define CMD_NO_FORK 0x40 /* Don't fork; just call execve */
#define CMD_TIME_PIPELINE 0x80 /* Time a pipeline */
#define CMD_TIME_POSIX 0x100 /* time -p; use POSIX.2 time output spec. */
#define CMD_AMPERSAND 0x200 /* command & */
#define CMD_STDIN_REDIR 0x400 /* async command needs implicit </dev/null */
#define CMD_COMMAND_BUILTIN 0x0800 /* command executed by `command' builtin */
#define CMD_COPROC_SUBSHELL 0x1000
/* What a command looks like. */
typedef struct command {
enum command_type type; /* FOR CASE WHILE IF CONNECTION or SIMPLE. */
int flags; /* Flags controlling execution environment. */
int line; /* line number the command starts on */
REDIRECT *redirects; /* Special redirects for FOR CASE, etc. */
union {
struct for_com *For;
struct case_com *Case;
struct while_com *While;
struct if_com *If;
struct connection *Connection;
struct simple_com *Simple;
struct function_def *Function_def;
struct group_com *Group;
#if defined (SELECT_COMMAND)
struct select_com *Select;
#endif
#if defined (DPAREN_ARITHMETIC)
struct arith_com *Arith;
#endif
#if defined (COND_COMMAND)
struct cond_com *Cond;
#endif
#if defined (ARITH_FOR_COMMAND)
struct arith_for_com *ArithFor;
#endif
struct subshell_com *Subshell;
struct coproc_com *Coproc;
} value;
} COMMAND;
/* Structure used to represent the CONNECTION type. */
typedef struct connection {
int ignore; /* Unused; simplifies make_command (). */
COMMAND *first; /* Pointer to the first command. */
COMMAND *second; /* Pointer to the second command. */
int connector; /* What separates this command from others. */
} CONNECTION;
/* Structures used to represent the CASE command. */
/* Values for FLAGS word in a PATTERN_LIST */
#define CASEPAT_FALLTHROUGH 0x01
#define CASEPAT_TESTNEXT 0x02
/* Pattern/action structure for CASE_COM. */
typedef struct pattern_list {
struct pattern_list *next; /* Clause to try in case this one failed. */
WORD_LIST *patterns; /* Linked list of patterns to test. */
COMMAND *action; /* Thing to execute if a pattern matches. */
int flags;
} PATTERN_LIST;
/* The CASE command. */
typedef struct case_com {
int flags; /* See description of CMD flags. */
int line; /* line number the `case' keyword appears on */
WORD_DESC *word; /* The thing to test. */
PATTERN_LIST *clauses; /* The clauses to test against, or NULL. */
} CASE_COM;
/* FOR command. */
typedef struct for_com {
int flags; /* See description of CMD flags. */
int line; /* line number the `for' keyword appears on */
WORD_DESC *name; /* The variable name to get mapped over. */
WORD_LIST *map_list; /* The things to map over. This is never NULL. */
COMMAND *action; /* The action to execute.
During execution, NAME is bound to successive
members of MAP_LIST. */
} FOR_COM;
#if defined (ARITH_FOR_COMMAND)
typedef struct arith_for_com {
int flags;
int line; /* generally used for error messages */
WORD_LIST *init;
WORD_LIST *test;
WORD_LIST *step;
COMMAND *action;
} ARITH_FOR_COM;
#endif
#if defined (SELECT_COMMAND)
/* KSH SELECT command. */
typedef struct select_com {
int flags; /* See description of CMD flags. */
int line; /* line number the `select' keyword appears on */
WORD_DESC *name; /* The variable name to get mapped over. */
WORD_LIST *map_list; /* The things to map over. This is never NULL. */
COMMAND *action; /* The action to execute.
During execution, NAME is bound to the member of
MAP_LIST chosen by the user. */
} SELECT_COM;
#endif /* SELECT_COMMAND */
/* IF command. */
typedef struct if_com {
int flags; /* See description of CMD flags. */
COMMAND *test; /* Thing to test. */
COMMAND *true_case; /* What to do if the test returned non-zero. */
COMMAND *false_case; /* What to do if the test returned zero. */
} IF_COM;
/* WHILE command. */
typedef struct while_com {
int flags; /* See description of CMD flags. */
COMMAND *test; /* Thing to test. */
COMMAND *action; /* Thing to do while test is non-zero. */
} WHILE_COM;
#if defined (DPAREN_ARITHMETIC)
/* The arithmetic evaluation command, ((...)). Just a set of flags and
a WORD_LIST, of which the first element is the only one used, for the
time being. */
typedef struct arith_com {
int flags;
int line;
WORD_LIST *exp;
} ARITH_COM;
#endif /* DPAREN_ARITHMETIC */
/* The conditional command, [[...]]. This is a binary tree -- we slippped
a recursive-descent parser into the YACC grammar to parse it. */
#define COND_AND 1
#define COND_OR 2
#define COND_UNARY 3
#define COND_BINARY 4
#define COND_TERM 5
#define COND_EXPR 6
typedef struct cond_com {
int flags;
int line;
int type;
WORD_DESC *op;
struct cond_com *left, *right;
} COND_COM;
/* The "simple" command. Just a collection of words and redirects. */
typedef struct simple_com {
int flags; /* See description of CMD flags. */
int line; /* line number the command starts on */
WORD_LIST *words; /* The program name, the arguments,
variable assignments, etc. */
REDIRECT *redirects; /* Redirections to perform. */
} SIMPLE_COM;
/* The "function definition" command. */
typedef struct function_def {
int flags; /* See description of CMD flags. */
int line; /* Line number the function def starts on. */
WORD_DESC *name; /* The name of the function. */
COMMAND *command; /* The parsed execution tree. */
char *source_file; /* file in which function was defined, if any */
} FUNCTION_DEF;
/* A command that is `grouped' allows pipes and redirections to affect all
commands in the group. */
typedef struct group_com {
int ignore; /* See description of CMD flags. */
COMMAND *command;
} GROUP_COM;
typedef struct subshell_com {
int flags;
COMMAND *command;
} SUBSHELL_COM;
#define COPROC_RUNNING 0x01
#define COPROC_DEAD 0x02
typedef struct coproc {
char *c_name;
pid_t c_pid;
int c_rfd;
int c_wfd;
int c_rsave;
int c_wsave;
int c_flags;
int c_status;
} Coproc;
typedef struct coproc_com {
int flags;
char *name;
COMMAND *command;
} COPROC_COM;
extern COMMAND *global_command;
extern Coproc sh_coproc;
/* Possible command errors */
#define CMDERR_DEFAULT 0
#define CMDERR_BADTYPE 1
#define CMDERR_BADCONN 2
#define CMDERR_BADJUMP 3
#define CMDERR_LAST 3
/* Forward declarations of functions declared in copy_cmd.c. */
extern FUNCTION_DEF *copy_function_def_contents __P((FUNCTION_DEF *, FUNCTION_DEF *));
extern FUNCTION_DEF *copy_function_def __P((FUNCTION_DEF *));
extern WORD_DESC *copy_word __P((WORD_DESC *));
extern WORD_LIST *copy_word_list __P((WORD_LIST *));
extern REDIRECT *copy_redirect __P((REDIRECT *));
extern REDIRECT *copy_redirects __P((REDIRECT *));
extern COMMAND *copy_command __P((COMMAND *));
#endif /* _COMMAND_H_ */
+8
View File
@@ -113,7 +113,15 @@ copy_redirect (redirect)
REDIRECT *new_redirect;
new_redirect = (REDIRECT *)xmalloc (sizeof (REDIRECT));
#if 0
FASTCOPY ((char *)redirect, (char *)new_redirect, (sizeof (REDIRECT)));
#else
*new_redirect = *redirect; /* let the compiler do the fast structure copy */
#endif
if (redirect->rflags & REDIR_VARASSIGN)
new_redirect->redirector.filename = copy_word (redirect->redirector.filename);
switch (redirect->instruction)
{
case r_reading_until:
+286
View File
@@ -0,0 +1,286 @@
*** ../bash-20090903/redir.c 2009-08-17 17:46:34.000000000 -0400
--- redir.c 2009-09-11 17:29:54.000000000 -0400
***************
*** 99,111 ****
int oflags;
allocname = 0;
! if (temp->redirector < 0)
/* This can happen when read_token_word encounters overflow, like in
exec 4294967297>x */
filename = _("file descriptor out of range");
#ifdef EBADF
/* This error can never involve NOCLOBBER */
! else if (error != NOCLOBBER_REDIRECT && temp->redirector >= 0 && error == EBADF)
{
/* 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
--- 99,113 ----
int oflags;
allocname = 0;
! if (temp->rflags & REDIR_VARASSIGN)
! filename = savestring (temp->redirector.filename->word);
! else if (temp->redirector.dest < 0)
/* This can happen when read_token_word encounters overflow, like in
exec 4294967297>x */
filename = _("file descriptor out of range");
#ifdef EBADF
/* This error can never involve NOCLOBBER */
! else if (error != NOCLOBBER_REDIRECT && temp->redirector.dest >= 0 && error == EBADF)
{
/* 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
***************
*** 119,125 ****
filename = allocname = itos (temp->redirectee.dest);
break;
default:
! filename = allocname = itos (temp->redirector);
break;
}
}
--- 121,127 ----
filename = allocname = itos (temp->redirectee.dest);
break;
default:
! filename = allocname = itos (temp->redirector.dest);
break;
}
}
***************
*** 162,167 ****
--- 164,173 ----
internal_error (_("cannot create temp file for here-document: %s"), strerror (heredoc_errno));
break;
+ case BADVAR_REDIRECT:
+ internal_error (_("cannot assign fd to variable %s"), filename);
+ break;
+
default:
internal_error ("%s: %s", filename, strerror (error));
break;
***************
*** 649,658 ****
char *redirectee_word;
enum r_instruction ri;
REDIRECT *new_redirect;
redirectee = redirect->redirectee.filename;
redir_fd = redirect->redirectee.dest;
! redirector = redirect->redirector;
ri = redirect->instruction;
if (redirect->flags & RX_INTERNAL)
--- 655,665 ----
char *redirectee_word;
enum r_instruction ri;
REDIRECT *new_redirect;
+ REDIRECTEE sd;
redirectee = redirect->redirectee.filename;
redir_fd = redirect->redirectee.dest;
! redirector = redirect->redirector.dest;
ri = redirect->instruction;
if (redirect->flags & RX_INTERNAL)
***************
*** 670,680 ****
return (AMBIGUOUS_REDIRECT);
else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
{
rd.dest = 0;
! new_redirect = make_redirection (redirector, r_close_this, rd);
}
else if (all_digits (redirectee_word))
{
if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
rd.dest = lfd;
else
--- 677,689 ----
return (AMBIGUOUS_REDIRECT);
else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
{
+ sd.dest = redirector;
rd.dest = 0;
! new_redirect = make_redirection (sd, r_close_this, rd, 0);
}
else if (all_digits (redirectee_word))
{
+ sd.dest = redirector;
if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
rd.dest = lfd;
else
***************
*** 682,704 ****
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)
{
rd.filename = make_bare_word (redirectee_word);
! new_redirect = make_redirection (1, r_err_and_out, rd);
}
else
{
--- 691,714 ----
switch (ri)
{
case r_duplicating_input_word:
! new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
break;
case r_duplicating_output_word:
! new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
break;
case r_move_input_word:
! new_redirect = make_redirection (sd, r_move_input, rd, 0);
break;
case r_move_output_word:
! new_redirect = make_redirection (sd, r_move_output, rd, 0);
break;
}
}
else if (ri == r_duplicating_output_word && redirector == 1)
{
+ sd.dest = 1;
rd.filename = make_bare_word (redirectee_word);
! new_redirect = make_redirection (sd, r_err_and_out, rd, 0);
}
else
{
***************
*** 730,736 ****
redirectee = new_redirect->redirectee.filename;
redir_fd = new_redirect->redirectee.dest;
! redirector = new_redirect->redirector;
ri = new_redirect->instruction;
/* Overwrite the flags element of the old redirect with the new value. */
--- 740,746 ----
redirectee = new_redirect->redirectee.filename;
redir_fd = new_redirect->redirectee.dest;
! redirector = new_redirect->redirector.dest;
ri = new_redirect->instruction;
/* Overwrite the flags element of the old redirect with the new value. */
***************
*** 1021,1026 ****
--- 1031,1037 ----
{
int new_fd, clexec_flag;
REDIRECT *new_redirect, *closer, *dummy_redirect;
+ REDIRECTEE sd;
new_fd = fcntl (fd, F_DUPFD, (fdbase < SHELL_FD_BASE) ? SHELL_FD_BASE : fdbase+1);
if (new_fd < 0)
***************
*** 1034,1049 ****
clexec_flag = fcntl (fd, F_GETFD, 0);
rd.dest = 0;
! closer = make_redirection (new_fd, r_close_this, rd);
closer->flags |= RX_INTERNAL;
dummy_redirect = copy_redirects (closer);
rd.dest = new_fd;
if (fd == 0)
! new_redirect = make_redirection (fd, r_duplicating_input, rd);
else
! new_redirect = make_redirection (fd, r_duplicating_output, rd);
new_redirect->flags |= RX_INTERNAL;
if (clexec_flag == 0 && fd >= 3 && new_fd >= SHELL_FD_BASE)
new_redirect->flags |= RX_SAVCLEXEC;
--- 1045,1062 ----
clexec_flag = fcntl (fd, F_GETFD, 0);
+ sd.dest = new_fd;
rd.dest = 0;
! closer = make_redirection (sd, r_close_this, rd, 0);
closer->flags |= RX_INTERNAL;
dummy_redirect = copy_redirects (closer);
+ sd.dest = fd;
rd.dest = new_fd;
if (fd == 0)
! new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
else
! new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
new_redirect->flags |= RX_INTERNAL;
if (clexec_flag == 0 && fd >= 3 && new_fd >= SHELL_FD_BASE)
new_redirect->flags |= RX_SAVCLEXEC;
***************
*** 1066,1073 ****
to save others. */
if (fd >= SHELL_FD_BASE && ri != r_close_this && clexec_flag)
{
rd.dest = new_fd;
! new_redirect = make_redirection (fd, r_duplicating_output, rd);
new_redirect->flags |= RX_INTERNAL;
add_exec_redirect (new_redirect);
--- 1079,1087 ----
to save others. */
if (fd >= SHELL_FD_BASE && ri != r_close_this && clexec_flag)
{
+ sd.dest = fd;
rd.dest = new_fd;
! new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
new_redirect->flags |= RX_INTERNAL;
add_exec_redirect (new_redirect);
***************
*** 1096,1104 ****
int fd;
{
REDIRECT *closer;
rd.dest = 0;
! closer = make_redirection (fd, r_close_this, rd);
closer->flags |= RX_INTERNAL;
closer->next = redirection_undo_list;
redirection_undo_list = closer;
--- 1110,1120 ----
int fd;
{
REDIRECT *closer;
+ REDIRECTEE sd;
+ sd.dest = fd;
rd.dest = 0;
! closer = make_redirection (sd, r_close_this, rd, 0);
closer->flags |= RX_INTERNAL;
closer->next = redirection_undo_list;
redirection_undo_list = closer;
***************
*** 1154,1159 ****
int n;
for (n = 0, rp = redirs; rp; rp = rp->next)
! n += stdin_redirection (rp->instruction, rp->redirector);
return n;
}
--- 1170,1175 ----
int n;
for (n = 0, rp = redirs; rp; rp = rp->next)
! n += stdin_redirection (rp->instruction, rp->redirector.dest);
return n;
}
+4
View File
@@ -309,6 +309,10 @@ dispose_redirects (list)
{
t = list;
list = list->next;
if (t->rflags & REDIR_VARASSIGN)
dispose_word (t->redirector.filename);
switch (t->instruction)
{
case r_reading_until:
+4 -2
View File
@@ -673,10 +673,11 @@ document_done:
INSTRUCTION is the instruction type, SOURCE is a file descriptor,
and DEST is a file descriptor or a WORD_DESC *. */
REDIRECT *
make_redirection (source, instruction, dest_and_filename)
int source;
make_redirection (source, instruction, dest_and_filename, flags)
REDIRECTEE source;
enum r_instruction instruction;
REDIRECTEE dest_and_filename;
int flags;
{
REDIRECT *temp;
WORD_DESC *w;
@@ -690,6 +691,7 @@ make_redirection (source, instruction, dest_and_filename)
temp->redirectee = dest_and_filename;
temp->instruction = instruction;
temp->flags = 0;
temp->rflags = flags;
temp->next = (REDIRECT *)NULL;
switch (instruction)
+2 -3
View File
@@ -526,7 +526,6 @@ make_simple_command (element, command)
ELEMENT element;
COMMAND *command;
{
itrace("make_simple_command");
/* If we are starting from scratch, then make the initial command
structure. Also note that we have to fill in all the slots, since
malloc doesn't return zeroed space. */
@@ -675,7 +674,7 @@ document_done:
and DEST is a file descriptor or a WORD_DESC *. */
REDIRECT *
make_redirection (source, instruction, dest_and_filename)
int source;
REDIRECTEE source;
enum r_instruction instruction;
REDIRECTEE dest_and_filename;
{
@@ -690,7 +689,7 @@ make_redirection (source, instruction, dest_and_filename)
temp->redirector = source;
temp->redirectee = dest_and_filename;
temp->instruction = instruction;
temp->flags = 0;
temp->flags = temp->rflags = 0;
temp->next = (REDIRECT *)NULL;
switch (instruction)
+1 -1
View File
@@ -47,7 +47,7 @@ extern COMMAND *make_until_command __P((COMMAND *, COMMAND *));
extern COMMAND *make_bare_simple_command __P((void));
extern COMMAND *make_simple_command __P((ELEMENT, COMMAND *));
extern void make_here_document __P((REDIRECT *, int));
extern REDIRECT *make_redirection __P((int, enum r_instruction, REDIRECTEE));
extern REDIRECT *make_redirection __P((REDIRECTEE, enum r_instruction, REDIRECTEE, int));
extern COMMAND *make_function_def __P((WORD_DESC *, COMMAND *, int, int));
extern COMMAND *clean_simple_command __P((COMMAND *));
+70
View File
@@ -0,0 +1,70 @@
/* make_cmd.h -- Declarations of functions found in make_cmd.c */
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_MAKE_CMD_H_)
#define _MAKE_CMD_H_
#include "stdc.h"
extern void cmd_init __P((void));
extern WORD_DESC *alloc_word_desc __P((void));
extern WORD_DESC *make_bare_word __P((const char *));
extern WORD_DESC *make_word_flags __P((WORD_DESC *, const char *));
extern WORD_DESC *make_word __P((const char *));
extern WORD_DESC *make_word_from_token __P((int));
extern WORD_LIST *make_word_list __P((WORD_DESC *, WORD_LIST *));
#define add_string_to_list(s, l) make_word_list (make_word(s), (l))
extern COMMAND *make_command __P((enum command_type, SIMPLE_COM *));
extern COMMAND *command_connect __P((COMMAND *, COMMAND *, int));
extern COMMAND *make_for_command __P((WORD_DESC *, WORD_LIST *, COMMAND *, int));
extern COMMAND *make_group_command __P((COMMAND *));
extern COMMAND *make_case_command __P((WORD_DESC *, PATTERN_LIST *, int));
extern PATTERN_LIST *make_pattern_list __P((WORD_LIST *, COMMAND *));
extern COMMAND *make_if_command __P((COMMAND *, COMMAND *, COMMAND *));
extern COMMAND *make_while_command __P((COMMAND *, COMMAND *));
extern COMMAND *make_until_command __P((COMMAND *, COMMAND *));
extern COMMAND *make_bare_simple_command __P((void));
extern COMMAND *make_simple_command __P((ELEMENT, COMMAND *));
extern void make_here_document __P((REDIRECT *, int));
extern REDIRECT *make_redirection __P((REDIRECTEE, enum r_instruction, REDIRECTEE));
extern COMMAND *make_function_def __P((WORD_DESC *, COMMAND *, int, int));
extern COMMAND *clean_simple_command __P((COMMAND *));
extern COMMAND *make_arith_command __P((WORD_LIST *));
extern COMMAND *make_select_command __P((WORD_DESC *, WORD_LIST *, COMMAND *, int));
#if defined (COND_COMMAND)
extern COND_COM *make_cond_node __P((int, WORD_DESC *, COND_COM *, COND_COM *));
extern COMMAND *make_cond_command __P((COND_COM *));
#endif
extern COMMAND *make_arith_for_command __P((WORD_LIST *, COMMAND *, int));
extern COMMAND *make_subshell_command __P((COMMAND *));
extern COMMAND *make_coproc_command __P((char *, COMMAND *));
extern COMMAND *connect_async_list __P((COMMAND *, COMMAND *, int));
#endif /* !_MAKE_CMD_H */
+65 -35
View File
@@ -310,6 +310,7 @@ static int word_top = -1;
static int token_to_read;
static WORD_DESC *word_desc_to_read;
static REDIRECTEE source;
static REDIRECTEE redir;
%}
@@ -332,7 +333,7 @@ static REDIRECTEE redir;
%token IN BANG TIME TIMEOPT
/* More general tokens. yylex () knows how to make these. */
%token <word> WORD ASSIGNMENT_WORD
%token <word> WORD ASSIGNMENT_WORD REDIR_WORD
%token <number> NUMBER
%token <word_list> ARITH_CMD ARITH_FOR_EXPRS
%token <command> COND_CMD
@@ -419,159 +420,187 @@ word_list: WORD
redirection: '>' WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_output_direction, redir);
$$ = make_redirection (source, r_output_direction, redir, 0);
}
| '<' WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (0, r_input_direction, redir);
$$ = make_redirection (source, r_input_direction, redir, 0);
}
| NUMBER '>' WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_output_direction, redir);
$$ = make_redirection (source, r_output_direction, redir, 0);
}
| NUMBER '<' WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_input_direction, redir);
$$ = make_redirection (source, r_input_direction, redir, 0);
}
| GREATER_GREATER WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_appending_to, redir);
$$ = make_redirection (source, r_appending_to, redir, 0);
}
| NUMBER GREATER_GREATER WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_appending_to, redir);
$$ = make_redirection (source, r_appending_to, redir, 0);
}
| LESS_LESS WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (0, r_reading_until, redir);
$$ = make_redirection (source, r_reading_until, redir, 0);
redir_stack[need_here_doc++] = $$;
}
| NUMBER LESS_LESS WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_reading_until, redir);
$$ = make_redirection (source, r_reading_until, redir, 0);
redir_stack[need_here_doc++] = $$;
}
| LESS_LESS_LESS WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (0, r_reading_string, redir);
$$ = make_redirection (source, r_reading_string, redir, 0);
}
| NUMBER LESS_LESS_LESS WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_reading_string, redir);
$$ = make_redirection (source, r_reading_string, redir, 0);
}
| LESS_AND NUMBER
{
source.dest = 0;
redir.dest = $2;
$$ = make_redirection (0, r_duplicating_input, redir);
$$ = make_redirection (source, r_duplicating_input, redir, 0);
}
| NUMBER LESS_AND NUMBER
{
source.dest = $1;
redir.dest = $3;
$$ = make_redirection ($1, r_duplicating_input, redir);
$$ = make_redirection (source, r_duplicating_input, redir, 0);
}
| GREATER_AND NUMBER
{
source.dest = 1;
redir.dest = $2;
$$ = make_redirection (1, r_duplicating_output, redir);
$$ = make_redirection (source, r_duplicating_output, redir, 0);
}
| NUMBER GREATER_AND NUMBER
{
source.dest = $1;
redir.dest = $3;
$$ = make_redirection ($1, r_duplicating_output, redir);
$$ = make_redirection (source, r_duplicating_output, redir, 0);
}
| LESS_AND WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (0, r_duplicating_input_word, redir);
$$ = make_redirection (source, r_duplicating_input_word, redir, 0);
}
| NUMBER LESS_AND WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_duplicating_input_word, redir);
$$ = make_redirection (source, r_duplicating_input_word, redir, 0);
}
| GREATER_AND WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_duplicating_output_word, redir);
$$ = make_redirection (source, r_duplicating_output_word, redir, 0);
}
| NUMBER GREATER_AND WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_duplicating_output_word, redir);
$$ = make_redirection (source, r_duplicating_output_word, redir, 0);
}
| LESS_LESS_MINUS WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection
(0, r_deblank_reading_until, redir);
$$ = make_redirection (source, r_deblank_reading_until, redir, 0);
redir_stack[need_here_doc++] = $$;
}
| NUMBER LESS_LESS_MINUS WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection
($1, r_deblank_reading_until, redir);
$$ = make_redirection (source, r_deblank_reading_until, redir, 0);
redir_stack[need_here_doc++] = $$;
}
| GREATER_AND '-'
{
source.dest = 1;
redir.dest = 0;
$$ = make_redirection (1, r_close_this, redir);
$$ = make_redirection (source, r_close_this, redir, 0);
}
| NUMBER GREATER_AND '-'
{
source.dest = $1;
redir.dest = 0;
$$ = make_redirection ($1, r_close_this, redir);
$$ = make_redirection (source, r_close_this, redir, 0);
}
| LESS_AND '-'
{
source.dest = 0;
redir.dest = 0;
$$ = make_redirection (0, r_close_this, redir);
$$ = make_redirection (source, r_close_this, redir, 0);
}
| NUMBER LESS_AND '-'
{
source.dest = $1;
redir.dest = 0;
$$ = make_redirection ($1, r_close_this, redir);
$$ = make_redirection (source, r_close_this, redir, 0);
}
| AND_GREATER WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_err_and_out, redir);
$$ = make_redirection (source, r_err_and_out, redir, 0);
}
| AND_GREATER_GREATER WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_append_err_and_out, redir);
$$ = make_redirection (source, r_append_err_and_out, redir, 0);
}
| NUMBER LESS_GREATER WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_input_output, redir);
$$ = make_redirection (source, r_input_output, redir, 0);
}
| LESS_GREATER WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (0, r_input_output, redir);
$$ = make_redirection (source, r_input_output, redir, 0);
}
| GREATER_BAR WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_output_force, redir);
$$ = make_redirection (source, r_output_force, redir, 0);
}
| NUMBER GREATER_BAR WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_output_force, redir);
$$ = make_redirection (source, r_output_force, redir, 0);
}
;
@@ -1119,12 +1148,13 @@ pipeline: pipeline '|' newline_list pipeline
{
/* Make cmd1 |& cmd2 equivalent to cmd1 2>&1 | cmd2 */
COMMAND *tc;
REDIRECTEE rd;
REDIRECTEE rd, sd;
REDIRECT *r;
tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1;
sd.dest = 2;
rd.dest = 1;
r = make_redirection (2, r_duplicating_output, rd);
r = make_redirection (sd, r_duplicating_output, rd, 0);
if (tc->redirects)
{
register REDIRECT *t;
+66 -36
View File
@@ -310,6 +310,7 @@ static int word_top = -1;
static int token_to_read;
static WORD_DESC *word_desc_to_read;
static REDIRECTEE source;
static REDIRECTEE redir;
%}
@@ -419,159 +420,187 @@ word_list: WORD
redirection: '>' WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_output_direction, redir);
$$ = make_redirection (source, r_output_direction, redir, 0);
}
| '<' WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (0, r_input_direction, redir);
$$ = make_redirection (source, r_input_direction, redir, 0);
}
| NUMBER '>' WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_output_direction, redir);
$$ = make_redirection (source, r_output_direction, redir, 0);
}
| NUMBER '<' WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_input_direction, redir);
$$ = make_redirection (source, r_input_direction, redir, 0);
}
| GREATER_GREATER WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_appending_to, redir);
$$ = make_redirection (source, r_appending_to, redir, 0);
}
| NUMBER GREATER_GREATER WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_appending_to, redir);
$$ = make_redirection (source, r_appending_to, redir, 0);
}
| LESS_LESS WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (0, r_reading_until, redir);
$$ = make_redirection (source, r_reading_until, redir, 0);
redir_stack[need_here_doc++] = $$;
}
| NUMBER LESS_LESS WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_reading_until, redir);
$$ = make_redirection (source, r_reading_until, redir, 0);
redir_stack[need_here_doc++] = $$;
}
| LESS_LESS_LESS WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (0, r_reading_string, redir);
$$ = make_redirection (source, r_reading_string, redir, 0);
}
| NUMBER LESS_LESS_LESS WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_reading_string, redir);
$$ = make_redirection (source, r_reading_string, redir, 0);
}
| LESS_AND NUMBER
{
source.dest = 0;
redir.dest = $2;
$$ = make_redirection (0, r_duplicating_input, redir);
$$ = make_redirection (source, r_duplicating_input, redir, 0);
}
| NUMBER LESS_AND NUMBER
{
source.dest = $1;
redir.dest = $3;
$$ = make_redirection ($1, r_duplicating_input, redir);
$$ = make_redirection (source, r_duplicating_input, redir, 0);
}
| GREATER_AND NUMBER
{
source.dest = 1;
redir.dest = $2;
$$ = make_redirection (1, r_duplicating_output, redir);
$$ = make_redirection (source, r_duplicating_output, redir, 0);
}
| NUMBER GREATER_AND NUMBER
{
source.dest = $1;
redir.dest = $3;
$$ = make_redirection ($1, r_duplicating_output, redir);
$$ = make_redirection (source, r_duplicating_output, redir, 0);
}
| LESS_AND WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (0, r_duplicating_input_word, redir);
$$ = make_redirection (source, r_duplicating_input_word, redir, 0);
}
| NUMBER LESS_AND WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_duplicating_input_word, redir);
$$ = make_redirection (source, r_duplicating_input_word, redir, 0);
}
| GREATER_AND WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_duplicating_output_word, redir);
$$ = make_redirection (source, r_duplicating_output_word, redir, 0);
}
| NUMBER GREATER_AND WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_duplicating_output_word, redir);
$$ = make_redirection (source, r_duplicating_output_word, redir, 0);
}
| LESS_LESS_MINUS WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection
(0, r_deblank_reading_until, redir);
$$ = make_redirection (source, r_deblank_reading_until, redir, 0);
redir_stack[need_here_doc++] = $$;
}
| NUMBER LESS_LESS_MINUS WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection
($1, r_deblank_reading_until, redir);
$$ = make_redirection (source, r_deblank_reading_until, redir, 0);
redir_stack[need_here_doc++] = $$;
}
| GREATER_AND '-'
{
source.dest = 1;
redir.dest = 0;
$$ = make_redirection (1, r_close_this, redir);
$$ = make_redirection (source, r_close_this, redir, 0);
}
| NUMBER GREATER_AND '-'
{
source.dest = $1;
redir.dest = 0;
$$ = make_redirection ($1, r_close_this, redir);
$$ = make_redirection (source, r_close_this, redir, 0);
}
| LESS_AND '-'
{
source.dest = 0;
redir.dest = 0;
$$ = make_redirection (0, r_close_this, redir);
$$ = make_redirection (source, r_close_this, redir, 0);
}
| NUMBER LESS_AND '-'
{
source.dest = $1;
redir.dest = 0;
$$ = make_redirection ($1, r_close_this, redir);
$$ = make_redirection (source, r_close_this, redir, 0);
}
| AND_GREATER WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_err_and_out, redir);
$$ = make_redirection (source, r_err_and_out, redir, 0);
}
| AND_GREATER_GREATER WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_append_err_and_out, redir);
$$ = make_redirection (source, r_append_err_and_out, redir, 0);
}
| NUMBER LESS_GREATER WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_input_output, redir);
$$ = make_redirection (source, r_input_output, redir, 0);
}
| LESS_GREATER WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (0, r_input_output, redir);
$$ = make_redirection (source, r_input_output, redir, 0);
}
| GREATER_BAR WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (1, r_output_force, redir);
$$ = make_redirection (source, r_output_force, redir, 0);
}
| NUMBER GREATER_BAR WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection ($1, r_output_force, redir);
$$ = make_redirection (source, r_output_force, redir, 0);
}
;
@@ -1119,12 +1148,13 @@ pipeline: pipeline '|' newline_list pipeline
{
/* Make cmd1 |& cmd2 equivalent to cmd1 2>&1 | cmd2 */
COMMAND *tc;
REDIRECTEE rd;
REDIRECTEE rd, sd;
REDIRECT *r;
tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1;
sd.dest = 2;
rd.dest = 1;
r = make_redirection (2, r_duplicating_output, rd);
r = make_redirection (sd, r_duplicating_output, rd, 0);
if (tc->redirects)
{
register REDIRECT *t;
@@ -3505,12 +3535,12 @@ eof_error:
else if MBTEST(ch == close && (tflags & LEX_INCASE) == 0) /* ending delimiter */
{
count--;
itrace("parse_comsub:%d: found close: count = %d", line_number, count);
/*itrace("parse_comsub:%d: found close: count = %d", line_number, count);*/
}
else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && (tflags & LEX_INCASE) == 0 && ch == open) /* nested begin */
{
count++;
itrace("parse_comsub:%d: found open: count = %d", line_number, count);
/*itrace("parse_comsub:%d: found open: count = %d", line_number, count);*/
}
/* Add this character. */
+4 -4
View File
@@ -988,7 +988,7 @@ print_redirection_list (redirects)
else
hdtail = heredocs = newredir;
}
else if (redirects->instruction == r_duplicating_output_word && redirects->redirector == 1)
else if (redirects->instruction == r_duplicating_output_word && redirects->redirector.dest == 1)
{
/* Temporarily translate it as the execution code does. */
redirects->instruction = r_err_and_out;
@@ -1024,8 +1024,8 @@ print_heredoc_header (redirect)
kill_leading = redirect->instruction == r_deblank_reading_until;
/* Here doc header */
if (redirect->redirector != 0)
cprintf ("%d", redirect->redirector);
if (redirect->redirector.dest != 0)
cprintf ("%d", redirect->redirector.dest);
/* If the here document delimiter is quoted, single-quote it. */
if (redirect->redirectee.filename->flags & W_QUOTED)
@@ -1055,7 +1055,7 @@ print_redirection (redirect)
kill_leading = 0;
redirectee = redirect->redirectee.filename;
redirector = redirect->redirector;
redirector = redirect->redirector.dest;
redir_fd = redirect->redirectee.dest;
switch (redirect->instruction)
+26 -3
View File
@@ -360,16 +360,16 @@ xtrace_set (fd, fp)
{
if (fd >= 0 && sh_validfd (fd) == 0)
{
internal_error ("xtrace_set: %d: invalid file descriptor", fd);
internal_error (_("xtrace_set: %d: invalid file descriptor"), fd);
return;
}
if (fp == 0)
{
internal_error ("xtrace_set: NULL file pointer");
internal_error (_("xtrace_set: NULL file pointer"));
return;
}
if (fd >= 0 && fileno (fp) != fd)
internal_warning ("xtrace fd (%d) != fileno xtrace fp (%d)", fd, fileno (fp));
internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd, fileno (fp));
xtrace_fd = fd;
xtrace_fp = fp;
@@ -381,6 +381,29 @@ xtrace_init ()
xtrace_set (-1, stderr);
}
void
xtrace_reset ()
{
if (xtrace_fd >= 0 && xtrace_fp)
{
fflush (xtrace_fp);
fclose (xtrace_fp);
}
else if (xtrace_fd >= 0)
close (xtrace_fd);
xtrace_fd = -1;
xtrace_fp = stderr;
}
void
xtrace_fdchk (fd)
int fd;
{
if (fd == xtrace_fd)
xtrace_reset ();
}
/* Return a string denoting what our indirection level is. */
char *
+33 -17
View File
@@ -99,13 +99,15 @@ redirection_error (temp, error)
int oflags;
allocname = 0;
if (temp->redirector < 0)
if (temp->rflags & REDIR_VARASSIGN)
filename = savestring (temp->redirector.filename->word);
else if (temp->redirector.dest < 0)
/* This can happen when read_token_word encounters overflow, like in
exec 4294967297>x */
filename = _("file descriptor out of range");
#ifdef EBADF
/* This error can never involve NOCLOBBER */
else if (error != NOCLOBBER_REDIRECT && temp->redirector >= 0 && error == EBADF)
else if (error != NOCLOBBER_REDIRECT && temp->redirector.dest >= 0 && error == EBADF)
{
/* 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
@@ -119,7 +121,7 @@ redirection_error (temp, error)
filename = allocname = itos (temp->redirectee.dest);
break;
default:
filename = allocname = itos (temp->redirector);
filename = allocname = itos (temp->redirector.dest);
break;
}
}
@@ -162,6 +164,10 @@ redirection_error (temp, error)
internal_error (_("cannot create temp file for here-document: %s"), strerror (heredoc_errno));
break;
case BADVAR_REDIRECT:
internal_error (_("cannot assign fd to variable %s"), filename);
break;
default:
internal_error ("%s: %s", filename, strerror (error));
break;
@@ -649,10 +655,11 @@ do_redirection_internal (redirect, flags)
char *redirectee_word;
enum r_instruction ri;
REDIRECT *new_redirect;
REDIRECTEE sd;
redirectee = redirect->redirectee.filename;
redir_fd = redirect->redirectee.dest;
redirector = redirect->redirector;
redirector = redirect->redirector.dest;
ri = redirect->instruction;
if (redirect->flags & RX_INTERNAL)
@@ -670,11 +677,13 @@ do_redirection_internal (redirect, flags)
return (AMBIGUOUS_REDIRECT);
else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
{
sd.dest = redirector;
rd.dest = 0;
new_redirect = make_redirection (redirector, r_close_this, rd);
new_redirect = make_redirection (sd, r_close_this, rd, 0);
}
else if (all_digits (redirectee_word))
{
sd.dest = redirector;
if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
rd.dest = lfd;
else
@@ -682,23 +691,24 @@ do_redirection_internal (redirect, flags)
switch (ri)
{
case r_duplicating_input_word:
new_redirect = make_redirection (redirector, r_duplicating_input, rd);
new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
break;
case r_duplicating_output_word:
new_redirect = make_redirection (redirector, r_duplicating_output, rd);
new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
break;
case r_move_input_word:
new_redirect = make_redirection (redirector, r_move_input, rd);
new_redirect = make_redirection (sd, r_move_input, rd, 0);
break;
case r_move_output_word:
new_redirect = make_redirection (redirector, r_move_output, rd);
new_redirect = make_redirection (sd, r_move_output, rd, 0);
break;
}
}
else if (ri == r_duplicating_output_word && redirector == 1)
{
sd.dest = 1;
rd.filename = make_bare_word (redirectee_word);
new_redirect = make_redirection (1, r_err_and_out, rd);
new_redirect = make_redirection (sd, r_err_and_out, rd, 0);
}
else
{
@@ -730,7 +740,7 @@ do_redirection_internal (redirect, flags)
redirectee = new_redirect->redirectee.filename;
redir_fd = new_redirect->redirectee.dest;
redirector = new_redirect->redirector;
redirector = new_redirect->redirector.dest;
ri = new_redirect->instruction;
/* Overwrite the flags element of the old redirect with the new value. */
@@ -1021,6 +1031,7 @@ add_undo_redirect (fd, ri, fdbase)
{
int new_fd, clexec_flag;
REDIRECT *new_redirect, *closer, *dummy_redirect;
REDIRECTEE sd;
new_fd = fcntl (fd, F_DUPFD, (fdbase < SHELL_FD_BASE) ? SHELL_FD_BASE : fdbase+1);
if (new_fd < 0)
@@ -1034,16 +1045,18 @@ add_undo_redirect (fd, ri, fdbase)
clexec_flag = fcntl (fd, F_GETFD, 0);
sd.dest = new_fd;
rd.dest = 0;
closer = make_redirection (new_fd, r_close_this, rd);
closer = make_redirection (sd, r_close_this, rd, 0);
closer->flags |= RX_INTERNAL;
dummy_redirect = copy_redirects (closer);
sd.dest = fd;
rd.dest = new_fd;
if (fd == 0)
new_redirect = make_redirection (fd, r_duplicating_input, rd);
new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
else
new_redirect = make_redirection (fd, r_duplicating_output, rd);
new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
new_redirect->flags |= RX_INTERNAL;
if (clexec_flag == 0 && fd >= 3 && new_fd >= SHELL_FD_BASE)
new_redirect->flags |= RX_SAVCLEXEC;
@@ -1066,8 +1079,9 @@ add_undo_redirect (fd, ri, fdbase)
to save others. */
if (fd >= SHELL_FD_BASE && ri != r_close_this && clexec_flag)
{
sd.dest = fd;
rd.dest = new_fd;
new_redirect = make_redirection (fd, r_duplicating_output, rd);
new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
new_redirect->flags |= RX_INTERNAL;
add_exec_redirect (new_redirect);
@@ -1096,9 +1110,11 @@ add_undo_close_redirect (fd)
int fd;
{
REDIRECT *closer;
REDIRECTEE sd;
sd.dest = fd;
rd.dest = 0;
closer = make_redirection (fd, r_close_this, rd);
closer = make_redirection (sd, r_close_this, rd, 0);
closer->flags |= RX_INTERNAL;
closer->next = redirection_undo_list;
redirection_undo_list = closer;
@@ -1154,6 +1170,6 @@ stdin_redirects (redirs)
int n;
for (n = 0, rp = redirs; rp; rp = rp->next)
n += stdin_redirection (rp->instruction, rp->redirector);
n += stdin_redirection (rp->instruction, rp->redirector.dest);
return n;
}
+1175
View File
File diff suppressed because it is too large Load Diff