commit bash-20080522 snapshot

This commit is contained in:
Chet Ramey
2011-12-07 09:24:08 -05:00
parent 33fe8777ce
commit 8943768b87
74 changed files with 3052 additions and 462 deletions
+2
View File
@@ -31,6 +31,8 @@
#define SEVAL_NOHIST 0x004
#define SEVAL_NOFREE 0x008
#define SEVAL_RESETLINE 0x010
#define SEVAL_PARSEONLY 0x020
#define SEVAL_NOLONGJMP 0x040
/* Flags for describe_command, shared between type.def and command.def */
#define CDESC_ALL 0x001 /* type -a */
+1
View File
@@ -142,6 +142,7 @@ extern int describe_command __P((char *, int));
/* Functions from setattr.def */
extern int set_or_show_attributes __P((WORD_LIST *, int, int));
extern int show_all_var_attributes __P((int, int));
extern int show_var_attributes __P((SHELL_VAR *, int, int));
extern int show_name_attributes __P((char *, int));
extern void set_var_attribute __P((char *, int, int));
+172 -53
View File
@@ -1,6 +1,6 @@
/* Evaluate a string as one or more shell commands.
Copyright (C) 1996-2005 Free Software Foundation, Inc.
Copyright (C) 1996-2008 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -44,6 +44,8 @@
#include "../redir.h"
#include "../trap.h"
#include <y.tab.h>
#if defined (HISTORY)
# include "../bashhist.h"
#endif
@@ -58,6 +60,7 @@ extern int errno;
extern int indirection_level, subshell_environment;
extern int line_number;
extern int current_token, shell_eof_token;
extern int last_command_exit_value;
extern int running_trap;
extern int loop_level;
@@ -67,6 +70,17 @@ int parse_and_execute_level = 0;
static int cat_file __P((REDIRECT *));
#define PE_TAG "parse_and_execute top"
#define PS_TAG "parse_string top"
#if defined (HISTORY)
static void
set_history_remembering ()
{
remember_on_history = enable_history_list;
}
#endif
/* How to force parse_and_execute () to clean up after itself. */
void
parse_and_execute_cleanup ()
@@ -76,16 +90,59 @@ parse_and_execute_cleanup ()
run_trap_cleanup (running_trap - 1);
unfreeze_jobs_list ();
}
run_unwind_frame ("parse_and_execute_top");
run_unwind_frame (PE_TAG);
}
#if defined (HISTORY)
static void
set_history_remembering ()
parse_prologue (string, flags, tag)
char *string;
int flags;
char *tag;
{
remember_on_history = enable_history_list;
char *orig_string;
int x;
orig_string = string;
/* Unwind protect this invocation of parse_and_execute (). */
begin_unwind_frame (tag);
unwind_protect_int (parse_and_execute_level);
unwind_protect_jmp_buf (top_level);
unwind_protect_int (indirection_level);
unwind_protect_int (line_number);
unwind_protect_int (loop_level);
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
unwind_protect_int (interactive);
#if defined (HISTORY)
if (parse_and_execute_level == 0)
add_unwind_protect (set_history_remembering, (char *)NULL);
else
unwind_protect_int (remember_on_history); /* can be used in scripts */
# if defined (BANG_HISTORY)
if (interactive_shell)
unwind_protect_int (history_expansion_inhibited);
# endif /* BANG_HISTORY */
#endif /* HISTORY */
if (interactive_shell)
{
x = get_current_prompt_level ();
add_unwind_protect (set_current_prompt_level, x);
}
add_unwind_protect (pop_stream, (char *)NULL);
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
add_unwind_protect (xfree, orig_string);
end_unwind_frame ();
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
#if defined (HISTORY)
if (flags & SEVAL_NOHIST)
bash_history_disable ();
#endif /* HISTORY */
}
#endif
/* Parse and execute the commands in STRING. Returns whatever
execute_command () returns. This frees STRING. FLAGS is a
@@ -104,50 +161,16 @@ parse_and_execute (string, from_file, flags)
const char *from_file;
int flags;
{
int code, x, lreset;
int code, lreset;
volatile int should_jump_to_top_level, last_result;
char *orig_string;
COMMAND *volatile command;
orig_string = string;
/* Unwind protect this invocation of parse_and_execute (). */
begin_unwind_frame ("parse_and_execute_top");
unwind_protect_int (parse_and_execute_level);
unwind_protect_jmp_buf (top_level);
unwind_protect_int (indirection_level);
unwind_protect_int (line_number);
unwind_protect_int (loop_level);
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
unwind_protect_int (interactive);
lreset = flags & SEVAL_RESETLINE;
#if defined (HISTORY)
if (parse_and_execute_level == 0)
add_unwind_protect (set_history_remembering, (char *)NULL);
else
unwind_protect_int (remember_on_history);
# if defined (BANG_HISTORY)
if (interactive_shell)
{
unwind_protect_int (history_expansion_inhibited);
}
# endif /* BANG_HISTORY */
#endif /* HISTORY */
if (interactive_shell)
{
x = get_current_prompt_level ();
add_unwind_protect (set_current_prompt_level, x);
}
add_unwind_protect (pop_stream, (char *)NULL);
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
add_unwind_protect (xfree, orig_string);
end_unwind_frame ();
parse_prologue (string, flags, PE_TAG);
parse_and_execute_level++;
lreset = flags & SEVAL_RESETLINE;
/* Reset the line number if the caller wants us to. If we don't reset the
line number, we have to subtract one, because we will add one just
before executing the next command (resetting the line number sets it to
@@ -157,13 +180,6 @@ parse_and_execute (string, from_file, flags)
line_number--;
indirection_level++;
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
#if defined (HISTORY)
if (flags & SEVAL_NOHIST)
bash_history_disable ();
#endif /* HISTORY */
code = should_jump_to_top_level = 0;
last_result = EXECUTION_SUCCESS;
@@ -224,7 +240,7 @@ parse_and_execute (string, from_file, flags)
if (parse_command () == 0)
{
if (interactive_shell == 0 && read_but_dont_execute)
if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
{
last_result = EXECUTION_SUCCESS;
dispose_command (global_command);
@@ -303,7 +319,7 @@ parse_and_execute (string, from_file, flags)
out:
run_unwind_frame ("parse_and_execute_top");
run_unwind_frame (PE_TAG);
if (interrupt_state && parse_and_execute_level == 0)
{
@@ -320,6 +336,109 @@ parse_and_execute (string, from_file, flags)
return (last_result);
}
/* Parse a command contained in STRING according to FLAGS and return the
number of characters consumed from the string. If non-NULL, set *ENDP
to the position in the string where the parse ended. Used to validate
command substitutions during parsing to obey Posix rules about finding
the end of the command and balancing parens. */
int
parse_string (string, from_file, flags, endp)
char *string;
const char *from_file;
int flags;
char **endp;
{
int code, nc;
volatile int should_jump_to_top_level;
COMMAND *volatile command, *oglobal;
char *ostring;
parse_prologue (string, flags, PS_TAG);
/* Reset the line number if the caller wants us to. If we don't reset the
line number, we have to subtract one, because we will add one just
before executing the next command (resetting the line number sets it to
0; the first line number is 1). */
push_stream (0);
code = should_jump_to_top_level = 0;
oglobal = global_command;
with_input_from_string (string, from_file);
while (*(bash_input.location.string))
{
command = (COMMAND *)NULL;
#if 0
if (interrupt_state)
break;
#endif
/* Provide a location for functions which `longjmp (top_level)' to
jump to. */
code = setjmp (top_level);
if (code)
{
#if defined (DEBUG)
itrace("parse_string: longjmp executed: code = %d", code);
#endif
should_jump_to_top_level = 0;
switch (code)
{
case FORCE_EOF:
case ERREXIT:
case EXITPROG:
case DISCARD: /* XXX */
if (command)
dispose_command (command);
/* Remember to call longjmp (top_level) after the old
value for it is restored. */
should_jump_to_top_level = 1;
goto out;
default:
command_error ("parse_string", CMDERR_BADJUMP, code, 0);
break;
}
}
if (parse_command () == 0)
{
dispose_command (global_command);
global_command = (COMMAND *)NULL;
}
else
{
if ((flags & SEVAL_NOLONGJMP) == 0)
{
should_jump_to_top_level = 1;
code = DISCARD;
}
else
reset_parser (); /* XXX - sets token_to_read */
break;
}
if (current_token == yacc_EOF || current_token == shell_eof_token)
break;
}
out:
global_command = oglobal;
nc = bash_input.location.string - ostring;
if (endp)
*endp = bash_input.location.string;
run_unwind_frame (PS_TAG);
if (should_jump_to_top_level)
jump_to_top_level (code);
return (nc);
}
/* Handle a $( < file ) command substitution. This expands the filename,
returning errors as appropriate, then just cats the file to the standard
output. */
+69 -48
View File
@@ -1,6 +1,6 @@
/* Evaluate a string as one or more shell commands.
Copyright (C) 1996-2005 Free Software Foundation, Inc.
Copyright (C) 1996-2008 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -44,6 +44,8 @@
#include "../redir.h"
#include "../trap.h"
#include <y.tab.h>
#if defined (HISTORY)
# include "../bashhist.h"
#endif
@@ -58,6 +60,7 @@ extern int errno;
extern int indirection_level, subshell_environment;
extern int line_number;
extern int current_token, shell_eof_token;
extern int last_command_exit_value;
extern int running_trap;
extern int loop_level;
@@ -67,6 +70,17 @@ int parse_and_execute_level = 0;
static int cat_file __P((REDIRECT *));
#define PE_TAG "parse_and_execute top"
#define PS_TAG "parse_string top"
#if defined (HISTORY)
static void
set_history_remembering ()
{
remember_on_history = enable_history_list;
}
#endif
/* How to force parse_and_execute () to clean up after itself. */
void
parse_and_execute_cleanup ()
@@ -76,13 +90,58 @@ parse_and_execute_cleanup ()
run_trap_cleanup (running_trap - 1);
unfreeze_jobs_list ();
}
run_unwind_frame ("parse_and_execute_top");
run_unwind_frame (PE_TAG);
}
static void
set_history_remembering ()
parse_prologue (string, flags, tag)
char *string;
int flags;
char *tag;
{
remember_on_history = enable_history_list;
char *orig_string;
int x;
orig_string = string;
/* Unwind protect this invocation of parse_and_execute (). */
begin_unwind_frame (tag);
unwind_protect_int (parse_and_execute_level);
unwind_protect_jmp_buf (top_level);
unwind_protect_int (indirection_level);
unwind_protect_int (line_number);
unwind_protect_int (loop_level);
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
unwind_protect_int (interactive);
#if defined (HISTORY)
if (parse_and_execute_level == 0)
add_unwind_protect (set_history_remembering, (char *)NULL);
else
unwind_protect_int (remember_on_history); /* can be used in scripts */
# if defined (BANG_HISTORY)
if (interactive_shell)
unwind_protect_int (history_expansion_inhibited);
# endif /* BANG_HISTORY */
#endif /* HISTORY */
if (interactive_shell)
{
x = get_current_prompt_level ();
add_unwind_protect (set_current_prompt_level, x);
}
add_unwind_protect (pop_stream, (char *)NULL);
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
add_unwind_protect (xfree, orig_string);
end_unwind_frame ();
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
#if defined (HISTORY)
if (flags & SEVAL_NOHIST)
bash_history_disable ();
#endif /* HISTORY */
}
/* Parse and execute the commands in STRING. Returns whatever
@@ -102,47 +161,16 @@ parse_and_execute (string, from_file, flags)
const char *from_file;
int flags;
{
int code, x, lreset;
int code, lreset;
volatile int should_jump_to_top_level, last_result;
char *orig_string;
COMMAND *volatile command;
orig_string = string;
/* Unwind protect this invocation of parse_and_execute (). */
begin_unwind_frame ("parse_and_execute_top");
unwind_protect_int (parse_and_execute_level);
unwind_protect_jmp_buf (top_level);
unwind_protect_int (indirection_level);
unwind_protect_int (line_number);
unwind_protect_int (loop_level);
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
unwind_protect_int (interactive);
lreset = flags & SEVAL_RESETLINE;
#if defined (HISTORY)
add_unwind_protect (set_history_remembering, (char *)NULL);
# if defined (BANG_HISTORY)
if (interactive_shell)
{
unwind_protect_int (history_expansion_inhibited);
}
# endif /* BANG_HISTORY */
#endif /* HISTORY */
if (interactive_shell)
{
x = get_current_prompt_level ();
add_unwind_protect (set_current_prompt_level, x);
}
add_unwind_protect (pop_stream, (char *)NULL);
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
add_unwind_protect (xfree, orig_string);
end_unwind_frame ();
parse_prologue (string, flags, PE_TAG);
parse_and_execute_level++;
lreset = flags & SEVAL_RESETLINE;
/* Reset the line number if the caller wants us to. If we don't reset the
line number, we have to subtract one, because we will add one just
before executing the next command (resetting the line number sets it to
@@ -152,13 +180,6 @@ parse_and_execute (string, from_file, flags)
line_number--;
indirection_level++;
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
#if defined (HISTORY)
if (flags & SEVAL_NOHIST)
bash_history_disable ();
#endif /* HISTORY */
code = should_jump_to_top_level = 0;
last_result = EXECUTION_SUCCESS;
@@ -219,7 +240,7 @@ parse_and_execute (string, from_file, flags)
if (parse_command () == 0)
{
if (interactive_shell == 0 && read_but_dont_execute)
if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
{
last_result = EXECUTION_SUCCESS;
dispose_command (global_command);
@@ -298,7 +319,7 @@ parse_and_execute (string, from_file, flags)
out:
run_unwind_frame ("parse_and_execute_top");
run_unwind_frame (PE_TAG);
if (interrupt_state && parse_and_execute_level == 0)
{
+2 -3
View File
@@ -93,7 +93,6 @@ extern int posixly_correct;
extern int unlink __P((const char *));
extern FILE *sh_mktmpfp __P((char *, int, char **));
extern int delete_last_history __P((void));
/* **************************************************************** */
/* */
@@ -326,7 +325,7 @@ fc_builtin (list)
entered into the history list." */
if (listing == 0 && hist_last_line_added)
{
delete_last_history ();
bash_delete_last_history ();
/* If we're editing a single command -- the last command in the
history -- and we just removed the dummy command added by
edit_and_execute_command (), we need to check whether or not we
@@ -625,7 +624,7 @@ fc_replhist (command)
if (command && *command)
{
delete_last_history ();
bash_delete_last_history ();
maybe_add_history (command); /* Obeys HISTCONTROL setting. */
}
}
-2
View File
@@ -337,8 +337,6 @@ fc_builtin (list)
last_hist = histbeg = --histend;
}
itrace ("fc: last_hist = %d histbeg = %d histend = %d", last_hist, histbeg, histend);
/* We print error messages for line specifications out of range. */
if ((histbeg < 0) || (histend < 0))
{
+5 -50
View File
@@ -87,11 +87,8 @@ extern int errno;
extern int current_command_line_count;
extern int force_append_history; /* shopt -s histappend */
int delete_last_history __P((void));
static char *histtime __P((HIST_ENTRY *, const char *));
static void display_history __P((WORD_LIST *));
static int delete_histent __P((int));
static void push_history __P((WORD_LIST *));
static int expand_and_print_history __P((WORD_LIST *));
@@ -162,7 +159,7 @@ history_builtin (list)
/* clear the history, but allow other arguments to add to it again. */
if (flags & CFLAG)
{
clear_history ();
bash_clear_history ();
if (list == 0)
return (EXECUTION_SUCCESS);
}
@@ -191,7 +188,7 @@ history_builtin (list)
return (EXECUTION_FAILURE);
}
opt = delete_offset;
result = delete_histent (opt - history_base);
result = bash_delete_histent (opt - history_base);
/* Since remove_history changes history_length, this can happen if
we delete the last history entry. */
if (where_history () > history_length)
@@ -310,48 +307,6 @@ display_history (list)
}
}
/* Delete and free the history list entry at offset I. */
static int
delete_histent (i)
int i;
{
HIST_ENTRY *discard;
discard = remove_history (i);
if (discard)
free_history_entry (discard);
return 1;
}
int
delete_last_history ()
{
register int i;
HIST_ENTRY **hlist, *histent;
int r;
hlist = history_list ();
if (hlist == NULL)
return 0;
for (i = 0; hlist[i]; i++)
;
i--;
/* History_get () takes a parameter that must be offset by history_base. */
histent = history_get (history_base + i); /* Don't free this */
if (histent == NULL)
return 0;
r = delete_histent (i);
if (where_history () > history_length)
history_set_pos (history_length);
return r;
}
/* Remove the last entry in the history list and add each argument in
LIST to the history. */
static void
@@ -367,12 +322,12 @@ push_history (list)
If you don't want history -s to remove the compound command from the
history, change #if 0 to #if 1 below. */
#if 0
if (hist_last_line_pushed == 0 && hist_last_line_added && delete_last_history () == 0)
if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0)
#else
if (hist_last_line_pushed == 0 &&
(hist_last_line_added ||
(current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history))
&& delete_last_history () == 0)
&& bash_delete_last_history () == 0)
#endif
return;
@@ -397,7 +352,7 @@ expand_and_print_history (list)
char *s;
int r, result;
if (hist_last_line_pushed == 0 && hist_last_line_added && delete_last_history () == 0)
if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0)
return EXECUTION_FAILURE;
result = EXECUTION_SUCCESS;
while (list)
+6 -18
View File
@@ -51,6 +51,9 @@ if $HISTFILE has a value, that is used, else ~/.bash_history.
If the $HISTTIMEFORMAT variable is set and not null, its value is used
as a format string for strftime(3) to print the time stamp associated
with each displayed history entry. No time stamps are printed otherwise.
Exit Status:
Returns success unless an invalid option is given or an error occurs.
$END
#include <config.h>
@@ -88,7 +91,6 @@ int delete_last_history __P((void));
static char *histtime __P((HIST_ENTRY *, const char *));
static void display_history __P((WORD_LIST *));
static int delete_histent __P((int));
static void push_history __P((WORD_LIST *));
static int expand_and_print_history __P((WORD_LIST *));
@@ -159,7 +161,7 @@ history_builtin (list)
/* clear the history, but allow other arguments to add to it again. */
if (flags & CFLAG)
{
clear_history ();
bash_clear_history ();
if (list == 0)
return (EXECUTION_SUCCESS);
}
@@ -188,7 +190,7 @@ history_builtin (list)
return (EXECUTION_FAILURE);
}
opt = delete_offset;
result = delete_histent (opt - history_base);
result = bash_delete_histent (opt - history_base);
/* Since remove_history changes history_length, this can happen if
we delete the last history entry. */
if (where_history () > history_length)
@@ -307,20 +309,6 @@ display_history (list)
}
}
/* Delete and free the history list entry at offset I. */
static int
delete_histent (i)
int i;
{
HIST_ENTRY *discard;
discard = remove_history (i);
if (discard)
free_history_entry (discard);
return 1;
}
int
delete_last_history ()
{
@@ -341,7 +329,7 @@ delete_last_history ()
if (histent == NULL)
return 0;
r = delete_histent (i);
r = bash_delete_histent (i);
if (where_history () > history_length)
history_set_pos (history_length);