mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-30 00:49:57 +02:00
commit bash-20060322 snapshot
This commit is contained in:
@@ -48,7 +48,7 @@ and the previous version, bash-3.1-beta1.
|
||||
|
||||
1. Changes to Bash
|
||||
|
||||
a. Fixed a bug that could cause core dumps due of accessing the current
|
||||
a. Fixed a bug that could cause core dumps due to accessing the current
|
||||
pipeline while in the middle of modifying it.
|
||||
|
||||
b. Fixed a bug that caused pathnames with backslashes still quoting characters
|
||||
|
||||
@@ -13191,3 +13191,26 @@ builtins/mkbuiltins.c
|
||||
lib/glob/glob.c
|
||||
- make sure globbing is interrupted if the shell receives a terminating
|
||||
signal
|
||||
|
||||
3/14
|
||||
----
|
||||
lib/readline/search.c
|
||||
- call rl_message with format argument of "%" in _rl_nsearch_init
|
||||
to avoid `%' characters in the prompt string from being interpreted
|
||||
as format specifiers to vsnprintf/vsprintf
|
||||
|
||||
3/19
|
||||
----
|
||||
parse.y, eval.c, input.h
|
||||
- change execute_prompt_command to execute_variable_command; takes the
|
||||
variable name as a new second argument
|
||||
|
||||
3/25
|
||||
----
|
||||
bashline.c
|
||||
- command_word_completion_function keeps track of when it's searching
|
||||
$PATH and doesn't return directory names as matches in that case.
|
||||
Problem reported by Pascal Terjan <pterjan@mandriva.com>
|
||||
- command_word_completion_function returns what it's passed as a
|
||||
possible match if it's the name of a directory in the current
|
||||
directory (only non-absolute pathnames are so tested).
|
||||
|
||||
@@ -13185,3 +13185,32 @@ builtins/reserved.def
|
||||
builtins/mkbuiltins.c
|
||||
- changes to avoid the annoying extra space that keeps gettext from
|
||||
being passed an empty string
|
||||
|
||||
3/9
|
||||
---
|
||||
lib/glob/glob.c
|
||||
- make sure globbing is interrupted if the shell receives a terminating
|
||||
signal
|
||||
|
||||
3/14
|
||||
----
|
||||
lib/readline/search.c
|
||||
- call rl_message with format argument of "%" in _rl_nsearch_init
|
||||
to avoid `%' characters in the prompt string from being interpreted
|
||||
as format specifiers to vsnprintf/vsprintf
|
||||
|
||||
3/19
|
||||
----
|
||||
parse.y, eval.c, input.h
|
||||
- change execute_prompt_command to execute_variable_command; takes the
|
||||
variable name as a new second argument
|
||||
|
||||
3/25
|
||||
----
|
||||
bashline.c
|
||||
- command_word_completion_function keeps track of when it's searching
|
||||
$PATH and doesn't return directory names as matches in that case
|
||||
- command_word_completion_function returns what it's passed as a
|
||||
possible match if it's the name of a directory in the current
|
||||
directory (only non-absolute pathnames are so tested). Problem
|
||||
reported by Pascal Terjan <pterjan@mandriva.com>
|
||||
|
||||
@@ -679,6 +679,7 @@ examples/misc/aliasconv.sh f
|
||||
examples/misc/aliasconv.bash f
|
||||
examples/misc/cshtobash f
|
||||
tests/README f
|
||||
tests/COPYRIGHT f
|
||||
tests/alias.tests f
|
||||
tests/alias.right f
|
||||
tests/appendop.tests f
|
||||
|
||||
+24
-3
@@ -1,6 +1,6 @@
|
||||
/* bashline.c -- Bash's interface to the readline library. */
|
||||
|
||||
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -1236,7 +1236,7 @@ command_word_completion_function (hint_text, state)
|
||||
static char *filename_hint = (char *)NULL;
|
||||
static char *dequoted_hint = (char *)NULL;
|
||||
static int path_index, hint_len, dequoted_len, istate, igncase;
|
||||
static int mapping_over, local_index;
|
||||
static int mapping_over, local_index, searching_path, hint_is_dir;
|
||||
static SHELL_VAR **varlist = (SHELL_VAR **)NULL;
|
||||
#if defined (ALIAS)
|
||||
static alias_t **alias_list = (alias_t **)NULL;
|
||||
@@ -1252,7 +1252,8 @@ command_word_completion_function (hint_text, state)
|
||||
if (hint)
|
||||
free (hint);
|
||||
|
||||
mapping_over = 0;
|
||||
mapping_over = searching_path = 0;
|
||||
hint_is_dir = CMD_IS_DIR (hint_text);
|
||||
val = (char *)NULL;
|
||||
|
||||
temp = rl_variable_value ("completion-ignore-case");
|
||||
@@ -1391,6 +1392,16 @@ command_word_completion_function (hint_text, state)
|
||||
mapping_over++;
|
||||
}
|
||||
|
||||
/* If the text passed is a directory in the current directory, return it
|
||||
as a possible match. Executables in directories in the current
|
||||
directory can be specified using relative pathnames and successfully
|
||||
executed even when `.' is not in $PATH. */
|
||||
if (hint_is_dir)
|
||||
{
|
||||
hint_is_dir = 0; /* only return the hint text once */
|
||||
return (savestring (hint_text));
|
||||
}
|
||||
|
||||
/* Repeatedly call filename_completion_function while we have
|
||||
members of PATH left. Question: should we stat each file?
|
||||
Answer: we call executable_file () on each file. */
|
||||
@@ -1408,6 +1419,7 @@ command_word_completion_function (hint_text, state)
|
||||
(current_path = extract_colon_unit (path, &path_index)) == 0)
|
||||
return ((char *)NULL);
|
||||
|
||||
searching_path = 1;
|
||||
if (*current_path == 0)
|
||||
{
|
||||
free (current_path);
|
||||
@@ -1501,9 +1513,18 @@ command_word_completion_function (hint_text, state)
|
||||
freetemp = match = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* If we have found a match, and it is an executable file or a
|
||||
directory name, return it. */
|
||||
if (match && executable_or_directory (val))
|
||||
#else
|
||||
/* If we have found a match, and it is an executable file, return it.
|
||||
We don't return directory names when searching $PATH, since the
|
||||
bash execution code won't find executables in directories which
|
||||
appear in directories in $PATH when they're specified using
|
||||
relative pathnames. */
|
||||
if (match && (searching_path ? executable_file (val) : executable_or_directory (val)))
|
||||
#endif
|
||||
{
|
||||
free (val);
|
||||
val = ""; /* So it won't be NULL. */
|
||||
|
||||
+41
-13
@@ -1,6 +1,6 @@
|
||||
/* bashline.c -- Bash's interface to the readline library. */
|
||||
|
||||
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -238,6 +238,9 @@ static int dot_in_path = 0;
|
||||
#define COMPLETE_BSQUOTE 3
|
||||
static int completion_quoting_style = COMPLETE_BSQUOTE;
|
||||
|
||||
/* Flag values for the final argument to bash_default_completion */
|
||||
#define DEFCOMP_CMDPOS 1
|
||||
|
||||
/* Change the readline VI-mode keymaps into or out of Posix.2 compliance.
|
||||
Called when the shell is put into or out of `posix' mode. */
|
||||
void
|
||||
@@ -999,7 +1002,7 @@ attempt_shell_completion (text, start, end)
|
||||
const char *text;
|
||||
int start, end;
|
||||
{
|
||||
int in_command_position, ti, saveti, qc;
|
||||
int in_command_position, ti, saveti, qc, dflags;
|
||||
char **matches, *command_separator_chars;
|
||||
|
||||
command_separator_chars = COMMAND_SEPARATORS;
|
||||
@@ -1112,15 +1115,20 @@ attempt_shell_completion (text, start, end)
|
||||
#endif
|
||||
|
||||
if (matches == 0)
|
||||
matches = bash_default_completion (text, start, end, qc, in_command_position);
|
||||
{
|
||||
dflags = 0;
|
||||
if (in_command_position)
|
||||
dflags |= DEFCOMP_CMDPOS;
|
||||
matches = bash_default_completion (text, start, end, qc, dflags);
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
char **
|
||||
bash_default_completion (text, start, end, qc, in_command_position)
|
||||
bash_default_completion (text, start, end, qc, compflags)
|
||||
const char *text;
|
||||
int start, end, qc, in_command_position;
|
||||
int start, end, qc, compflags;
|
||||
{
|
||||
char **matches;
|
||||
|
||||
@@ -1148,9 +1156,11 @@ bash_default_completion (text, start, end, qc, in_command_position)
|
||||
/* And last, (but not least) if this word is in a command position, then
|
||||
complete over possible command names, including aliases, functions,
|
||||
and command names. */
|
||||
if (!matches && in_command_position)
|
||||
if (matches == 0 && (compflags & DEFCOMP_CMDPOS))
|
||||
{
|
||||
if (start == 0 && end == 0 && text[0] == '\0' && no_empty_command_completion)
|
||||
/* If END == START and text[0] == 0, we are trying to complete an empty
|
||||
command word. */
|
||||
if (no_empty_command_completion && end == start && text[0] == '\0')
|
||||
{
|
||||
matches = (char **)NULL;
|
||||
rl_ignore_some_completions_function = bash_ignore_everything;
|
||||
@@ -1226,7 +1236,7 @@ command_word_completion_function (hint_text, state)
|
||||
static char *filename_hint = (char *)NULL;
|
||||
static char *dequoted_hint = (char *)NULL;
|
||||
static int path_index, hint_len, dequoted_len, istate, igncase;
|
||||
static int mapping_over, local_index;
|
||||
static int mapping_over, local_index, searching_path, hint_is_dir;
|
||||
static SHELL_VAR **varlist = (SHELL_VAR **)NULL;
|
||||
#if defined (ALIAS)
|
||||
static alias_t **alias_list = (alias_t **)NULL;
|
||||
@@ -1242,7 +1252,9 @@ command_word_completion_function (hint_text, state)
|
||||
if (hint)
|
||||
free (hint);
|
||||
|
||||
mapping_over = 0;
|
||||
mapping_over = searching_path = 0;
|
||||
hint_is_dir = CMD_IS_DIR (hint_text);
|
||||
|
||||
val = (char *)NULL;
|
||||
|
||||
temp = rl_variable_value ("completion-ignore-case");
|
||||
@@ -1381,6 +1393,16 @@ command_word_completion_function (hint_text, state)
|
||||
mapping_over++;
|
||||
}
|
||||
|
||||
/* If the text passed is a directory in the current directory, return it
|
||||
as a possible match. Executables in directories in the current
|
||||
directory can be specified using relative pathnames and successfully
|
||||
executed even when `.' is not in $PATH. */
|
||||
if (hint_is_dir)
|
||||
{
|
||||
hint_is_dir = 0; /* only return the hint text once */
|
||||
return (savestring (hint_text));
|
||||
}
|
||||
|
||||
/* Repeatedly call filename_completion_function while we have
|
||||
members of PATH left. Question: should we stat each file?
|
||||
Answer: we call executable_file () on each file. */
|
||||
@@ -1398,6 +1420,7 @@ command_word_completion_function (hint_text, state)
|
||||
(current_path = extract_colon_unit (path, &path_index)) == 0)
|
||||
return ((char *)NULL);
|
||||
|
||||
searching_path = 1;
|
||||
if (*current_path == 0)
|
||||
{
|
||||
free (current_path);
|
||||
@@ -1491,9 +1514,18 @@ command_word_completion_function (hint_text, state)
|
||||
freetemp = match = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* If we have found a match, and it is an executable file or a
|
||||
directory name, return it. */
|
||||
if (match && executable_or_directory (val))
|
||||
#else
|
||||
/* If we have found a match, and it is an executable file, return it.
|
||||
We don't return directory names when searching $PATH, since the
|
||||
bash execution code won't find executables in directories which
|
||||
appear in directories in $PATH when they're specified using
|
||||
relative pathnames. */
|
||||
if (match && (searching_path ? executable_file (val) : executable_or_directory (val)))
|
||||
#endif
|
||||
{
|
||||
free (val);
|
||||
val = ""; /* So it won't be NULL. */
|
||||
@@ -3137,11 +3169,7 @@ bash_directory_completion_matches (text)
|
||||
char *dfn;
|
||||
int qc;
|
||||
|
||||
#if 0
|
||||
qc = (text[0] == '"' || text[0] == '\'') ? text[0] : 0;
|
||||
#else
|
||||
qc = rl_dispatching ? rl_completion_quote_character : 0;
|
||||
#endif
|
||||
dfn = bash_dequote_filename ((char *)text, qc);
|
||||
m1 = rl_completion_matches (dfn, rl_filename_completion_function);
|
||||
free (dfn);
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
/* Copyright (C) 1996-2003 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 2, 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; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashtypes.h"
|
||||
#include "posixstat.h"
|
||||
#include "filecntl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../jobs.h"
|
||||
#include "../builtins.h"
|
||||
#include "../flags.h"
|
||||
#include "../input.h"
|
||||
#include "../execute_cmd.h"
|
||||
#include "../trap.h"
|
||||
|
||||
#if defined (HISTORY)
|
||||
# include "../bashhist.h"
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Flags for _evalfile() */
|
||||
#define FEVAL_ENOENTOK 0x001
|
||||
#define FEVAL_BUILTIN 0x002
|
||||
#define FEVAL_UNWINDPROT 0x004
|
||||
#define FEVAL_NONINT 0x008
|
||||
#define FEVAL_LONGJMP 0x010
|
||||
#define FEVAL_HISTORY 0x020
|
||||
#define FEVAL_CHECKBINARY 0x040
|
||||
#define FEVAL_REGFILE 0x080
|
||||
#define FEVAL_NOPUSHARGS 0x100
|
||||
|
||||
extern int posixly_correct;
|
||||
extern int indirection_level, startup_state, subshell_environment;
|
||||
extern int return_catch_flag, return_catch_value;
|
||||
extern int last_command_exit_value;
|
||||
|
||||
/* How many `levels' of sourced files we have. */
|
||||
int sourcelevel = 0;
|
||||
|
||||
static int
|
||||
_evalfile (filename, flags)
|
||||
const char *filename;
|
||||
int flags;
|
||||
{
|
||||
volatile int old_interactive;
|
||||
procenv_t old_return_catch;
|
||||
int return_val, fd, result, pflags;
|
||||
char *string;
|
||||
struct stat finfo;
|
||||
size_t file_size;
|
||||
sh_vmsg_func_t *errfunc;
|
||||
#if defined (ARRAY_VARS)
|
||||
SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;
|
||||
ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
|
||||
# if defined (DEBUGGER)
|
||||
SHELL_VAR *bash_argv_v, *bash_argc_v;
|
||||
ARRAY *bash_argv_a, *bash_argc_a;
|
||||
# endif
|
||||
char *t, tt[2];
|
||||
#endif
|
||||
|
||||
USE_VAR(pflags);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
|
||||
# if defined (DEBUGGER)
|
||||
GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
fd = open (filename, O_RDONLY);
|
||||
|
||||
if (fd < 0 || (fstat (fd, &finfo) == -1))
|
||||
{
|
||||
file_error_and_exit:
|
||||
if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
|
||||
file_error (filename);
|
||||
|
||||
if (flags & FEVAL_LONGJMP)
|
||||
{
|
||||
last_command_exit_value = 1;
|
||||
jump_to_top_level (EXITPROG);
|
||||
}
|
||||
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE
|
||||
: ((errno == ENOENT) ? 0 : -1));
|
||||
}
|
||||
|
||||
errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error);
|
||||
|
||||
if (S_ISDIR (finfo.st_mode))
|
||||
{
|
||||
(*errfunc) (_("%s: is a directory"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
|
||||
}
|
||||
else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
|
||||
{
|
||||
(*errfunc) (_("%s: not a regular file"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
|
||||
}
|
||||
|
||||
file_size = (size_t)finfo.st_size;
|
||||
/* Check for overflow with large files. */
|
||||
if (file_size != finfo.st_size || file_size + 1 < file_size)
|
||||
{
|
||||
(*errfunc) (_("%s: file is too large"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
|
||||
}
|
||||
|
||||
#if defined (__CYGWIN__) && defined (O_TEXT)
|
||||
setmode (fd, O_TEXT);
|
||||
#endif
|
||||
|
||||
string = (char *)xmalloc (1 + file_size);
|
||||
result = read (fd, string, file_size);
|
||||
string[result] = '\0';
|
||||
|
||||
return_val = errno;
|
||||
close (fd);
|
||||
errno = return_val;
|
||||
|
||||
if (result < 0) /* XXX was != file_size, not < 0 */
|
||||
{
|
||||
free (string);
|
||||
goto file_error_and_exit;
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
free (string);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1);
|
||||
}
|
||||
|
||||
if ((flags & FEVAL_CHECKBINARY) &&
|
||||
check_binary_file (string, (result > 80) ? 80 : result))
|
||||
{
|
||||
free (string);
|
||||
(*errfunc) ("%s: cannot execute binary file", filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
|
||||
}
|
||||
|
||||
if (flags & FEVAL_UNWINDPROT)
|
||||
{
|
||||
begin_unwind_frame ("_evalfile");
|
||||
|
||||
unwind_protect_int (return_catch_flag);
|
||||
unwind_protect_jmp_buf (return_catch);
|
||||
if (flags & FEVAL_NONINT)
|
||||
unwind_protect_int (interactive);
|
||||
unwind_protect_int (sourcelevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
COPY_PROCENV (return_catch, old_return_catch);
|
||||
if (flags & FEVAL_NONINT)
|
||||
old_interactive = interactive;
|
||||
}
|
||||
|
||||
if (flags & FEVAL_NONINT)
|
||||
interactive = 0;
|
||||
|
||||
return_catch_flag++;
|
||||
sourcelevel++;
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
array_push (bash_source_a, (char *)filename);
|
||||
t = itos (executing_line_number ());
|
||||
itrace("evalfile: pushing %s to bash_lineno array");
|
||||
array_push (bash_lineno_a, t);
|
||||
free (t);
|
||||
array_push (funcname_a, "source"); /* not exactly right */
|
||||
# if defined (DEBUGGER)
|
||||
/* Have to figure out a better way to do this when `source' is supplied
|
||||
arguments */
|
||||
if ((flags & FEVAL_NOPUSHARGS) == 0)
|
||||
{
|
||||
array_push (bash_argv_a, (char *)filename);
|
||||
tt[0] = '1'; tt[1] = '\0';
|
||||
array_push (bash_argc_a, tt);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* set the flags to be passed to parse_and_execute */
|
||||
pflags = SEVAL_RESETLINE;
|
||||
pflags |= (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;
|
||||
|
||||
if (flags & FEVAL_BUILTIN)
|
||||
result = EXECUTION_SUCCESS;
|
||||
|
||||
return_val = setjmp (return_catch);
|
||||
|
||||
/* If `return' was seen outside of a function, but in the script, then
|
||||
force parse_and_execute () to clean up. */
|
||||
if (return_val)
|
||||
{
|
||||
parse_and_execute_cleanup ();
|
||||
result = return_catch_value;
|
||||
}
|
||||
else
|
||||
result = parse_and_execute (string, filename, pflags);
|
||||
|
||||
if (flags & FEVAL_UNWINDPROT)
|
||||
run_unwind_frame ("_evalfile");
|
||||
else
|
||||
{
|
||||
if (flags & FEVAL_NONINT)
|
||||
interactive = old_interactive;
|
||||
return_catch_flag--;
|
||||
sourcelevel--;
|
||||
COPY_PROCENV (old_return_catch, return_catch);
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
/* These two variables cannot be unset, and cannot be affected by the
|
||||
sourced file. */
|
||||
array_pop (bash_source_a);
|
||||
array_pop (bash_lineno_a);
|
||||
|
||||
/* FUNCNAME can be unset, and so can potentially be changed by the
|
||||
sourced file. */
|
||||
GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
|
||||
if (nfv == funcname_v)
|
||||
array_pop (funcname_a);
|
||||
# if defined (DEBUGGER)
|
||||
if ((flags & FEVAL_NOPUSHARGS) == 0)
|
||||
{
|
||||
array_pop (bash_argc_a);
|
||||
array_pop (bash_argv_a);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
return ((flags & FEVAL_BUILTIN) ? result : 1);
|
||||
}
|
||||
|
||||
int
|
||||
maybe_execute_file (fname, force_noninteractive)
|
||||
const char *fname;
|
||||
int force_noninteractive;
|
||||
{
|
||||
char *filename;
|
||||
int result, flags;
|
||||
|
||||
filename = bash_tilde_expand (fname, 0);
|
||||
flags = FEVAL_ENOENTOK;
|
||||
if (force_noninteractive)
|
||||
flags |= FEVAL_NONINT;
|
||||
result = _evalfile (filename, flags);
|
||||
free (filename);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined (HISTORY)
|
||||
int
|
||||
fc_execute_file (filename)
|
||||
const char *filename;
|
||||
{
|
||||
int flags;
|
||||
|
||||
/* We want these commands to show up in the history list if
|
||||
remember_on_history is set. */
|
||||
flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE;
|
||||
return (_evalfile (filename, flags));
|
||||
}
|
||||
#endif /* HISTORY */
|
||||
|
||||
int
|
||||
source_file (filename, sflags)
|
||||
const char *filename;
|
||||
int sflags;
|
||||
{
|
||||
int flags, rval;
|
||||
|
||||
flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;
|
||||
if (sflags)
|
||||
flags |= FEVAL_NOPUSHARGS;
|
||||
/* POSIX shells exit if non-interactive and file error. */
|
||||
if (posixly_correct && !interactive_shell)
|
||||
flags |= FEVAL_LONGJMP;
|
||||
rval = _evalfile (filename, flags);
|
||||
|
||||
run_return_trap ();
|
||||
return rval;
|
||||
}
|
||||
+1
-1
@@ -35,7 +35,7 @@ option is given, it is interpreted as follows:
|
||||
-c the maximum size of core files created
|
||||
-d the maximum size of a process's data segment
|
||||
-e the maximum scheduling priority (`nice')
|
||||
-f the maximum size of files created by the shell
|
||||
-f the maximum size of files written by the shell and its children
|
||||
-i the maximum number of pending signals
|
||||
-l the maximum size a process may lock into memory
|
||||
-m the maximum resident set size
|
||||
|
||||
+1
-1
@@ -8530,7 +8530,7 @@ The maximum size of a process's data segment
|
||||
The maximum scheduling priority ("nice")
|
||||
.TP
|
||||
.B \-f
|
||||
The maximum size of files created by the shell
|
||||
The maximum size of files written by the shell and its children
|
||||
.TP
|
||||
.B \-i
|
||||
The maximum number of pending signals
|
||||
|
||||
+12
-7
@@ -6,12 +6,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet@po.cwru.edu
|
||||
.\"
|
||||
.\" Last Change: Wed Dec 28 19:58:45 EST 2005
|
||||
.\" Last Change: Thu Jan 26 09:04:43 EST 2006
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2005 Dec 28" "GNU Bash-3.1"
|
||||
.TH BASH 1 "2006 Jan 26" "GNU Bash-3.2"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -62,8 +62,9 @@ also incorporates useful features from the \fIKorn\fP and \fIC\fP
|
||||
shells (\fBksh\fP and \fBcsh\fP).
|
||||
.PP
|
||||
.B Bash
|
||||
is intended to be a conformant implementation of the IEEE
|
||||
POSIX Shell and Tools specification (IEEE Working Group 1003\.2).
|
||||
is intended to be a conformant implementation of the
|
||||
Shell and Utilities portion of the IEEE POSIX specification
|
||||
(IEEE Standard 1003.1).
|
||||
.B Bash
|
||||
can be configured to be POSIX-conformant by default.
|
||||
.SH OPTIONS
|
||||
@@ -223,7 +224,7 @@ This option is on by default if the shell is invoked as
|
||||
.TP
|
||||
.B \-\-posix
|
||||
Change the behavior of \fBbash\fP where the default operation differs
|
||||
from the POSIX 1003.2 standard to match the standard (\fIposix mode\fP).
|
||||
from the POSIX standard to match the standard (\fIposix mode\fP).
|
||||
.TP
|
||||
.B \-\-restricted
|
||||
The shell becomes restricted (see
|
||||
@@ -2862,7 +2863,7 @@ and
|
||||
.BR ] ,
|
||||
\fIcharacter classes\fP can be specified using the syntax
|
||||
\fB[:\fP\fIclass\fP\fB:]\fP, where \fIclass\fP is one of the
|
||||
following classes defined in the POSIX.2 standard:
|
||||
following classes defined in the POSIX standard:
|
||||
.PP
|
||||
.RS
|
||||
.B
|
||||
@@ -3418,6 +3419,10 @@ automatically have them defined with the
|
||||
option to the
|
||||
.B export
|
||||
builtin.
|
||||
A function definition may be deleted using the \fB\-f\fP option to
|
||||
the
|
||||
.B unset
|
||||
builtin.
|
||||
Note that shell functions and variables with the same name may result
|
||||
in multiple identically-named entries in the environment passed to the
|
||||
shell's children.
|
||||
@@ -7713,7 +7718,7 @@ This option is disabled by default.
|
||||
Change the behavior of
|
||||
.B bash
|
||||
where the default operation differs
|
||||
from the POSIX 1003.2 standard to match the standard (\fIposix mode\fP).
|
||||
from the POSIX standard to match the standard (\fIposix mode\fP).
|
||||
.TP 8
|
||||
.B privileged
|
||||
Same as
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ are preserved on all copies.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||||
under the terms of the GNU Free Documentation License, Version 1.2 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
|
||||
and with the Back-Cover Texts as in (a) below. A copy of the license is
|
||||
@@ -3861,7 +3861,7 @@ The maximum size of a process's data segment.
|
||||
The maximum scheduling priority ("nice").
|
||||
|
||||
@item -f
|
||||
The maximum size of files created by the shell.
|
||||
The maximum size of files written by the shell and its children.
|
||||
|
||||
@item -i
|
||||
The maximum number of pending signals.
|
||||
|
||||
+31
-26
@@ -24,7 +24,7 @@ are preserved on all copies.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||||
under the terms of the GNU Free Documentation License, Version 1.2 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
|
||||
and with the Back-Cover Texts as in (a) below. A copy of the license is
|
||||
@@ -74,7 +74,7 @@ USA @*
|
||||
@top Bash Features
|
||||
|
||||
This text is a brief description of the features that are present in
|
||||
the Bash shell (version @value{VERSION}, @value{UPDATED})..
|
||||
the Bash shell (version @value{VERSION}, @value{UPDATED}).
|
||||
|
||||
This is Edition @value{EDITION}, last updated @value{UPDATED},
|
||||
of @cite{The GNU Bash Reference Manual},
|
||||
@@ -142,7 +142,8 @@ of Unix.
|
||||
Bash is largely compatible with @code{sh} and incorporates useful
|
||||
features from the Korn shell @code{ksh} and the C shell @code{csh}.
|
||||
It is intended to be a conformant implementation of the @sc{ieee}
|
||||
@sc{posix} Shell and Tools specification (@sc{ieee} Working Group 1003.2).
|
||||
@sc{posix} Shell and Tools portion of the @sc{ieee} @sc{posix}
|
||||
specification (@sc{ieee} Standard 1003.1).
|
||||
It offers functional improvements over @code{sh} for both interactive and
|
||||
programming use.
|
||||
|
||||
@@ -217,7 +218,8 @@ These definitions are used throughout the remainder of this manual.
|
||||
@item POSIX
|
||||
@cindex POSIX
|
||||
A family of open system standards based on Unix. Bash
|
||||
is concerned with @sc{posix} 1003.2, the Shell and Tools Standard.
|
||||
is primarily concerned with the Shell and Utilities portion of the
|
||||
@sc{posix} 1003.1 standard.
|
||||
|
||||
@item blank
|
||||
A space or tab character.
|
||||
@@ -307,7 +309,7 @@ of an event occurring in the system.
|
||||
@item special builtin
|
||||
@cindex special builtin
|
||||
A shell builtin command that has been classified as special by the
|
||||
@sc{posix} 1003.2 standard.
|
||||
@sc{posix} standard.
|
||||
|
||||
@item token
|
||||
@cindex token
|
||||
@@ -1084,6 +1086,9 @@ name of a command.
|
||||
Any redirections (@pxref{Redirections}) associated with the shell function
|
||||
are performed when the function is executed.
|
||||
|
||||
A function definition may be deleted using the @option{-f} option to the
|
||||
@code{unset} builtin (@pxref{Bourne Shell Builtins}).
|
||||
|
||||
The exit status of a function definition is zero unless a syntax error
|
||||
occurs or a readonly function with the same name already exists.
|
||||
When executed, the exit status of a function is the exit status of the
|
||||
@@ -1901,7 +1906,7 @@ force the use of the C locale by setting the @env{LC_COLLATE} or
|
||||
Within @samp{[} and @samp{]}, @var{character classes} can be specified
|
||||
using the syntax
|
||||
@code{[:}@var{class}@code{:]}, where @var{class} is one of the
|
||||
following classes defined in the @sc{posix} 1003.2 standard:
|
||||
following classes defined in the @sc{posix} standard:
|
||||
@example
|
||||
alnum alpha ascii blank cntrl digit graph lower
|
||||
print punct space upper word xdigit
|
||||
@@ -2586,7 +2591,7 @@ under another shell.
|
||||
* The Set Builtin:: This builtin is so overloaded it
|
||||
deserves its own section.
|
||||
* Special Builtins:: Builtin commands classified specially by
|
||||
POSIX.2.
|
||||
POSIX.
|
||||
@end menu
|
||||
|
||||
Builtin commands are contained within the shell itself.
|
||||
@@ -2619,7 +2624,7 @@ builtins do not accept options.
|
||||
@section Bourne Shell Builtins
|
||||
|
||||
The following shell builtin commands are inherited from the Bourne Shell.
|
||||
These commands are implemented as specified by the @sc{posix} 1003.2 standard.
|
||||
These commands are implemented as specified by the @sc{posix} standard.
|
||||
|
||||
@table @code
|
||||
@item : @r{(a colon)}
|
||||
@@ -2807,7 +2812,7 @@ If @code{getopts} is silent, then a colon (@samp{:}) is placed in
|
||||
@item hash
|
||||
@btindex hash
|
||||
@example
|
||||
hash [-'r] [-p @var{filename}] [-dt] [@var{name}]
|
||||
hash [-r] [-p @var{filename}] [-dt] [@var{name}]
|
||||
@end example
|
||||
Remember the full pathnames of commands specified as @var{name} arguments,
|
||||
so they need not be searched for on subsequent invocations.
|
||||
@@ -3071,7 +3076,7 @@ The return status is zero unless a @var{name} is readonly.
|
||||
|
||||
This section describes builtin commands which are unique to
|
||||
or have been extended in Bash.
|
||||
Some of these commands are specified in the @sc{posix} 1003.2 standard.
|
||||
Some of these commands are specified in the @sc{posix} standard.
|
||||
|
||||
@table @code
|
||||
|
||||
@@ -4058,7 +4063,7 @@ This option is disabled by default.
|
||||
|
||||
@item posix
|
||||
Change the behavior of Bash where the default operation differs
|
||||
from the @sc{posix} 1003.2 standard to match the standard
|
||||
from the @sc{posix} standard to match the standard
|
||||
(@pxref{Bash POSIX Mode}).
|
||||
This is intended to make Bash behave as a strict superset of that
|
||||
standard.
|
||||
@@ -4185,7 +4190,7 @@ The return status is always zero unless an invalid option is supplied.
|
||||
@section Special Builtins
|
||||
@cindex special builtin
|
||||
|
||||
For historical reasons, the @sc{posix} 1003.2 standard has classified
|
||||
For historical reasons, the @sc{posix} standard has classified
|
||||
several builtin commands as @emph{special}.
|
||||
When Bash is executing in @sc{posix} mode, the special builtins
|
||||
differ from other builtin commands in three respects:
|
||||
@@ -4888,7 +4893,7 @@ invoked as @code{sh}.
|
||||
|
||||
@item --posix
|
||||
Change the behavior of Bash where the default operation differs
|
||||
from the @sc{posix} 1003.2 standard to match the standard. This
|
||||
from the @sc{posix} standard to match the standard. This
|
||||
is intended to make Bash behave as a strict superset of that
|
||||
standard. @xref{Bash POSIX Mode}, for a description of the Bash
|
||||
@sc{posix} mode.
|
||||
@@ -5901,7 +5906,7 @@ the shell spawned to execute the script.
|
||||
|
||||
Starting Bash with the @option{--posix} command-line option or executing
|
||||
@samp{set -o posix} while Bash is running will cause Bash to conform more
|
||||
closely to the @sc{posix} 1003.2 standard by changing the behavior to
|
||||
closely to the @sc{posix} standard by changing the behavior to
|
||||
match that specified by @sc{posix} in areas where the Bash default differs.
|
||||
|
||||
When invoked as @code{sh}, Bash enters @sc{posix} mode after reading the
|
||||
@@ -5934,13 +5939,13 @@ Reserved words appearing in a context where reserved words are recognized
|
||||
do not undergo alias expansion.
|
||||
|
||||
@item
|
||||
The @sc{posix} 1003.2 @env{PS1} and @env{PS2} expansions of @samp{!} to
|
||||
The @sc{posix} @env{PS1} and @env{PS2} expansions of @samp{!} to
|
||||
the history number and @samp{!!} to @samp{!} are enabled,
|
||||
and parameter expansion is performed on the values of @env{PS1} and
|
||||
@env{PS2} regardless of the setting of the @code{promptvars} option.
|
||||
|
||||
@item
|
||||
The @sc{posix} 1003.2 startup files are executed (@env{$ENV}) rather than
|
||||
The @sc{posix} startup files are executed (@env{$ENV}) rather than
|
||||
the normal Bash files.
|
||||
|
||||
@item
|
||||
@@ -5982,13 +5987,13 @@ may not start with a digit. Declaring a function with an invalid name
|
||||
causes a fatal syntax error in non-interactive shells.
|
||||
|
||||
@item
|
||||
@sc{posix} 1003.2 special builtins are found before shell functions
|
||||
@sc{posix} special builtins are found before shell functions
|
||||
during command lookup.
|
||||
|
||||
@item
|
||||
If a @sc{posix} 1003.2 special builtin returns an error status, a
|
||||
If a @sc{posix} special builtin returns an error status, a
|
||||
non-interactive shell exits. The fatal errors are those listed in
|
||||
the POSIX.2 standard, and include things like passing incorrect options,
|
||||
the POSIX standard, and include things like passing incorrect options,
|
||||
redirection errors, variable assignment errors for assignments preceding
|
||||
the command name, and so on.
|
||||
|
||||
@@ -6016,7 +6021,7 @@ variable in a @code{for} statement or the selection variable in a
|
||||
Process substitution is not available.
|
||||
|
||||
@item
|
||||
Assignment statements preceding @sc{posix} 1003.2 special builtins
|
||||
Assignment statements preceding @sc{posix} special builtins
|
||||
persist in the shell environment after the builtin completes.
|
||||
|
||||
@item
|
||||
@@ -6026,7 +6031,7 @@ special builtin command had been executed.
|
||||
|
||||
@item
|
||||
The @code{export} and @code{readonly} builtin commands display their
|
||||
output in the format required by @sc{posix} 1003.2.
|
||||
output in the format required by @sc{posix}.
|
||||
|
||||
@item
|
||||
The @code{trap} builtin displays signal names without the leading
|
||||
@@ -6105,7 +6110,7 @@ escape characters are converted.
|
||||
|
||||
@end enumerate
|
||||
|
||||
There is other @sc{posix} 1003.2 behavior that Bash does not implement by
|
||||
There is other @sc{posix} behavior that Bash does not implement by
|
||||
default even when in @sc{posix} mode.
|
||||
Specifically:
|
||||
|
||||
@@ -6928,7 +6933,7 @@ Please send all reports concerning this manual to
|
||||
|
||||
Bash implements essentially the same grammar, parameter and
|
||||
variable expansion, redirection, and quoting as the Bourne Shell.
|
||||
Bash uses the @sc{posix} 1003.2 standard as the specification of
|
||||
Bash uses the @sc{posix} standard as the specification of
|
||||
how these features are to be implemented. There are some
|
||||
differences between the traditional Bourne shell and Bash; this
|
||||
section quickly details the differences of significance. A
|
||||
@@ -7092,7 +7097,7 @@ not all words (@pxref{Word Splitting}).
|
||||
This closes a longstanding shell security hole.
|
||||
|
||||
@item
|
||||
Bash implements the full set of @sc{posix} 1003.2 filename expansion operators,
|
||||
Bash implements the full set of @sc{posix} filename expansion operators,
|
||||
including @var{character classes}, @var{equivalence classes}, and
|
||||
@var{collating symbols} (@pxref{Filename Expansion}).
|
||||
|
||||
@@ -7377,8 +7382,8 @@ with a @samp{-}.
|
||||
|
||||
@item
|
||||
The SVR4.2 shell exits a script if any builtin fails; Bash exits
|
||||
a script only if one of the @sc{posix} 1003.2 special builtins fails, and
|
||||
only for certain failures, as enumerated in the @sc{posix} 1003.2 standard.
|
||||
a script only if one of the @sc{posix} special builtins fails, and
|
||||
only for certain failures, as enumerated in the @sc{posix} standard.
|
||||
|
||||
@item
|
||||
The SVR4.2 shell behaves differently when invoked as @code{jsh}
|
||||
|
||||
@@ -212,7 +212,7 @@ parse_command ()
|
||||
{
|
||||
command_to_execute = get_string_value ("PROMPT_COMMAND");
|
||||
if (command_to_execute)
|
||||
execute_prompt_command (command_to_execute);
|
||||
execute_variable_command (command_to_execute, "PROMPT_COMMAND");
|
||||
|
||||
if (running_under_emacs == 2)
|
||||
send_pwd_to_eterm (); /* Yuck */
|
||||
|
||||
@@ -100,7 +100,7 @@ extern int stream_on_stack __P((enum stream_type));
|
||||
extern char *read_secondary_line __P((int));
|
||||
extern int find_reserved_word __P((char *));
|
||||
extern void gather_here_documents __P((void));
|
||||
extern void execute_prompt_command __P((char *));
|
||||
extern void execute_variable_command __P((char *, char *));
|
||||
|
||||
extern int *save_token_state __P((void));
|
||||
extern void restore_token_state __P((int *));
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
#
|
||||
# NOTE: we ignore `realloc' tags because they're just extra information
|
||||
#
|
||||
# Copyright (c) 2001 Chester Ramey
|
||||
# Permission is hereby granted to deal in this Software without restriction.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
|
||||
#
|
||||
# Chet Ramey
|
||||
# chet@po.cwru.edu
|
||||
#
|
||||
|
||||
@@ -14,7 +14,7 @@ This document describes the GNU History library
|
||||
a programming tool that provides a consistent user interface for
|
||||
recalling lines of previously typed input.
|
||||
|
||||
Copyright @copyright{} 1988-2004 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1988-2006 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -22,7 +22,7 @@ are preserved on all copies.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||||
under the terms of the GNU Free Documentation License, Version 1.2 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
|
||||
and with the Back-Cover Texts as in (a) below. A copy of the license is
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@ignore
|
||||
This file documents the user interface to the GNU History library.
|
||||
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2006 Free Software Foundation, Inc.
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this manual
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@ignore
|
||||
This file documents the user interface to the GNU History library.
|
||||
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2006 Free Software Foundation, Inc.
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this manual
|
||||
|
||||
@@ -14,7 +14,7 @@ This manual describes the GNU Readline Library
|
||||
consistency of user interface across discrete programs which provide
|
||||
a command line interface.
|
||||
|
||||
Copyright @copyright{} 1988-2004 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1988-2006 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -22,7 +22,7 @@ are preserved on all copies.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||||
under the terms of the GNU Free Documentation License, Version 1.2 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
|
||||
and with the Back-Cover Texts as in (a) below. A copy of the license is
|
||||
|
||||
@@ -8,7 +8,7 @@ This document describes the GNU Readline Library, a utility for aiding
|
||||
in the consistency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
Copyright (C) 1988-2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2006 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
|
||||
@@ -14,7 +14,7 @@ This manual describes the end user interface of the GNU Readline Library
|
||||
consistency of user interface across discrete programs which provide
|
||||
a command line interface.
|
||||
|
||||
Copyright @copyright{} 1988-2005 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1988-2006 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -22,7 +22,7 @@ are preserved on all copies.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||||
under the terms of the GNU Free Documentation License, Version 1.2 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
|
||||
and with the Back-Cover Texts as in (a) below. A copy of the license is
|
||||
|
||||
@@ -32,6 +32,9 @@ Let me know what you think.
|
||||
|
||||
Jeff
|
||||
*/
|
||||
/*
|
||||
Copyright (C) 1999 Jeff Solomon
|
||||
*/
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
#include <config.h>
|
||||
|
||||
@@ -211,7 +211,7 @@ _rl_nsearch_init (dir, pchar)
|
||||
rl_end = rl_point = 0;
|
||||
|
||||
p = _rl_make_prompt_for_search (pchar ? pchar : ':');
|
||||
rl_message (p, 0, 0);
|
||||
rl_message ("%s", p, 0);
|
||||
free (p);
|
||||
|
||||
RL_SETSTATE(RL_STATE_NSEARCH);
|
||||
|
||||
@@ -507,6 +507,7 @@ make_bare_simple_command ()
|
||||
command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
|
||||
|
||||
temp->flags = 0;
|
||||
itrace("make_bare_simple_command: line_number = %d", line_number);
|
||||
temp->line = line_number;
|
||||
temp->words = (WORD_LIST *)NULL;
|
||||
temp->redirects = (REDIRECT *)NULL;
|
||||
@@ -532,7 +533,10 @@ make_simple_command (element, command)
|
||||
command = make_bare_simple_command ();
|
||||
|
||||
if (element.word)
|
||||
{
|
||||
itrace("make_simple_command: adding %s", element.word->word);
|
||||
command->value.Simple->words = make_word_list (element.word, command->value.Simple->words);
|
||||
}
|
||||
else if (element.redirect)
|
||||
{
|
||||
REDIRECT *r = element.redirect;
|
||||
|
||||
+853
@@ -0,0 +1,853 @@
|
||||
/* make_cmd.c -- Functions for making instances of the various
|
||||
parser constructs. */
|
||||
|
||||
/* Copyright (C) 1989-2005 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 2, 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; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bashtypes.h"
|
||||
#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
#include "filecntl.h"
|
||||
#include "bashansi.h"
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "bashintl.h"
|
||||
|
||||
#include "syntax.h"
|
||||
#include "command.h"
|
||||
#include "general.h"
|
||||
#include "error.h"
|
||||
#include "flags.h"
|
||||
#include "make_cmd.h"
|
||||
#include "dispose_cmd.h"
|
||||
#include "variables.h"
|
||||
#include "subst.h"
|
||||
#include "input.h"
|
||||
#include "ocache.h"
|
||||
#include "externs.h"
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
#include "jobs.h"
|
||||
#endif
|
||||
|
||||
#include "shmbutil.h"
|
||||
|
||||
extern int line_number, current_command_line_count;
|
||||
extern int last_command_exit_value;
|
||||
|
||||
/* Object caching */
|
||||
sh_obj_cache_t wdcache = {0, 0, 0};
|
||||
sh_obj_cache_t wlcache = {0, 0, 0};
|
||||
|
||||
#define WDCACHESIZE 60
|
||||
#define WLCACHESIZE 60
|
||||
|
||||
static COMMAND *make_for_or_select __P((enum command_type, WORD_DESC *, WORD_LIST *, COMMAND *, int));
|
||||
#if defined (ARITH_FOR_COMMAND)
|
||||
static WORD_LIST *make_arith_for_expr __P((char *));
|
||||
#endif
|
||||
static COMMAND *make_until_or_while __P((enum command_type, COMMAND *, COMMAND *));
|
||||
|
||||
void
|
||||
cmd_init ()
|
||||
{
|
||||
ocache_create (wdcache, WORD_DESC, WDCACHESIZE);
|
||||
ocache_create (wlcache, WORD_LIST, WLCACHESIZE);
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
alloc_word_desc ()
|
||||
{
|
||||
WORD_DESC *temp;
|
||||
|
||||
ocache_alloc (wdcache, WORD_DESC, temp);
|
||||
temp->flags = 0;
|
||||
temp->word = 0;
|
||||
return temp;
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_bare_word (string)
|
||||
const char *string;
|
||||
{
|
||||
WORD_DESC *temp;
|
||||
|
||||
temp = alloc_word_desc ();
|
||||
|
||||
if (*string)
|
||||
temp->word = savestring (string);
|
||||
else
|
||||
{
|
||||
temp->word = (char *)xmalloc (1);
|
||||
temp->word[0] = '\0';
|
||||
}
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_word_flags (w, string)
|
||||
WORD_DESC *w;
|
||||
const char *string;
|
||||
{
|
||||
register int i;
|
||||
size_t slen;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
i = 0;
|
||||
slen = strlen (string);
|
||||
while (i < slen)
|
||||
{
|
||||
switch (string[i])
|
||||
{
|
||||
case '$':
|
||||
w->flags |= W_HASDOLLAR;
|
||||
break;
|
||||
case '\\':
|
||||
break; /* continue the loop */
|
||||
case '\'':
|
||||
case '`':
|
||||
case '"':
|
||||
w->flags |= W_QUOTED;
|
||||
break;
|
||||
}
|
||||
|
||||
ADVANCE_CHAR (string, slen, i);
|
||||
}
|
||||
|
||||
return (w);
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_word (string)
|
||||
const char *string;
|
||||
{
|
||||
WORD_DESC *temp;
|
||||
|
||||
temp = make_bare_word (string);
|
||||
return (make_word_flags (temp, string));
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_word_from_token (token)
|
||||
int token;
|
||||
{
|
||||
char tokenizer[2];
|
||||
|
||||
tokenizer[0] = token;
|
||||
tokenizer[1] = '\0';
|
||||
|
||||
return (make_word (tokenizer));
|
||||
}
|
||||
|
||||
WORD_LIST *
|
||||
make_word_list (word, wlink)
|
||||
WORD_DESC *word;
|
||||
WORD_LIST *wlink;
|
||||
{
|
||||
WORD_LIST *temp;
|
||||
|
||||
ocache_alloc (wlcache, WORD_LIST, temp);
|
||||
|
||||
temp->word = word;
|
||||
temp->next = wlink;
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_command (type, pointer)
|
||||
enum command_type type;
|
||||
SIMPLE_COM *pointer;
|
||||
{
|
||||
COMMAND *temp;
|
||||
|
||||
temp = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
temp->type = type;
|
||||
temp->value.Simple = pointer;
|
||||
temp->value.Simple->flags = temp->flags = 0;
|
||||
temp->redirects = (REDIRECT *)NULL;
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
command_connect (com1, com2, connector)
|
||||
COMMAND *com1, *com2;
|
||||
int connector;
|
||||
{
|
||||
CONNECTION *temp;
|
||||
|
||||
temp = (CONNECTION *)xmalloc (sizeof (CONNECTION));
|
||||
temp->connector = connector;
|
||||
temp->first = com1;
|
||||
temp->second = com2;
|
||||
return (make_command (cm_connection, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
static COMMAND *
|
||||
make_for_or_select (type, name, map_list, action, lineno)
|
||||
enum command_type type;
|
||||
WORD_DESC *name;
|
||||
WORD_LIST *map_list;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
FOR_COM *temp;
|
||||
|
||||
temp = (FOR_COM *)xmalloc (sizeof (FOR_COM));
|
||||
temp->flags = 0;
|
||||
temp->name = name;
|
||||
temp->line = lineno;
|
||||
temp->map_list = map_list;
|
||||
temp->action = action;
|
||||
return (make_command (type, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_for_command (name, map_list, action, lineno)
|
||||
WORD_DESC *name;
|
||||
WORD_LIST *map_list;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
return (make_for_or_select (cm_for, name, map_list, action, lineno));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_select_command (name, map_list, action, lineno)
|
||||
WORD_DESC *name;
|
||||
WORD_LIST *map_list;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
#if defined (SELECT_COMMAND)
|
||||
return (make_for_or_select (cm_select, name, map_list, action, lineno));
|
||||
#else
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (ARITH_FOR_COMMAND)
|
||||
static WORD_LIST *
|
||||
make_arith_for_expr (s)
|
||||
char *s;
|
||||
{
|
||||
WORD_LIST *result;
|
||||
WORD_DESC *wd;
|
||||
|
||||
if (s == 0 || *s == '\0')
|
||||
return ((WORD_LIST *)NULL);
|
||||
wd = make_word (s);
|
||||
wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_DQUOTE; /* no word splitting or globbing */
|
||||
result = make_word_list (wd, (WORD_LIST *)NULL);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note that this function calls dispose_words on EXPRS, since it doesn't
|
||||
use the word list directly. We free it here rather than at the caller
|
||||
because no other function in this file requires that the caller free
|
||||
any arguments. */
|
||||
COMMAND *
|
||||
make_arith_for_command (exprs, action, lineno)
|
||||
WORD_LIST *exprs;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
#if defined (ARITH_FOR_COMMAND)
|
||||
ARITH_FOR_COM *temp;
|
||||
WORD_LIST *init, *test, *step;
|
||||
char *s, *t, *start;
|
||||
int nsemi;
|
||||
|
||||
init = test = step = (WORD_LIST *)NULL;
|
||||
/* Parse the string into the three component sub-expressions. */
|
||||
start = t = s = exprs->word->word;
|
||||
for (nsemi = 0; ;)
|
||||
{
|
||||
/* skip whitespace at the start of each sub-expression. */
|
||||
while (whitespace (*s))
|
||||
s++;
|
||||
start = s;
|
||||
/* skip to the semicolon or EOS */
|
||||
while (*s && *s != ';')
|
||||
s++;
|
||||
|
||||
t = (s > start) ? substring (start, 0, s - start) : (char *)NULL;
|
||||
|
||||
nsemi++;
|
||||
switch (nsemi)
|
||||
{
|
||||
case 1:
|
||||
init = make_arith_for_expr (t);
|
||||
break;
|
||||
case 2:
|
||||
test = make_arith_for_expr (t);
|
||||
break;
|
||||
case 3:
|
||||
step = make_arith_for_expr (t);
|
||||
break;
|
||||
}
|
||||
|
||||
FREE (t);
|
||||
if (*s == '\0')
|
||||
break;
|
||||
s++; /* skip over semicolon */
|
||||
}
|
||||
|
||||
if (nsemi != 3)
|
||||
{
|
||||
if (nsemi < 3)
|
||||
parser_error (lineno, _("syntax error: arithmetic expression required"));
|
||||
else
|
||||
parser_error (lineno, _("syntax error: `;' unexpected"));
|
||||
parser_error (lineno, _("syntax error: `((%s))'"), exprs->word->word);
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
}
|
||||
|
||||
temp = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM));
|
||||
temp->flags = 0;
|
||||
temp->line = lineno;
|
||||
temp->init = init ? init : make_arith_for_expr ("1");
|
||||
temp->test = test ? test : make_arith_for_expr ("1");
|
||||
temp->step = step ? step : make_arith_for_expr ("1");
|
||||
temp->action = action;
|
||||
|
||||
dispose_words (exprs);
|
||||
return (make_command (cm_arith_for, (SIMPLE_COM *)temp));
|
||||
#else
|
||||
dispose_words (exprs);
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif /* ARITH_FOR_COMMAND */
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_group_command (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
GROUP_COM *temp;
|
||||
|
||||
temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
|
||||
temp->command = command;
|
||||
return (make_command (cm_group, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_case_command (word, clauses, lineno)
|
||||
WORD_DESC *word;
|
||||
PATTERN_LIST *clauses;
|
||||
int lineno;
|
||||
{
|
||||
CASE_COM *temp;
|
||||
|
||||
temp = (CASE_COM *)xmalloc (sizeof (CASE_COM));
|
||||
temp->flags = 0;
|
||||
temp->line = lineno;
|
||||
temp->word = word;
|
||||
temp->clauses = REVERSE_LIST (clauses, PATTERN_LIST *);
|
||||
return (make_command (cm_case, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
PATTERN_LIST *
|
||||
make_pattern_list (patterns, action)
|
||||
WORD_LIST *patterns;
|
||||
COMMAND *action;
|
||||
{
|
||||
PATTERN_LIST *temp;
|
||||
|
||||
temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
|
||||
temp->patterns = REVERSE_LIST (patterns, WORD_LIST *);
|
||||
temp->action = action;
|
||||
temp->next = NULL;
|
||||
temp->flags = 0;
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_if_command (test, true_case, false_case)
|
||||
COMMAND *test, *true_case, *false_case;
|
||||
{
|
||||
IF_COM *temp;
|
||||
|
||||
temp = (IF_COM *)xmalloc (sizeof (IF_COM));
|
||||
temp->flags = 0;
|
||||
temp->test = test;
|
||||
temp->true_case = true_case;
|
||||
temp->false_case = false_case;
|
||||
return (make_command (cm_if, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
static COMMAND *
|
||||
make_until_or_while (which, test, action)
|
||||
enum command_type which;
|
||||
COMMAND *test, *action;
|
||||
{
|
||||
WHILE_COM *temp;
|
||||
|
||||
temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
|
||||
temp->flags = 0;
|
||||
temp->test = test;
|
||||
temp->action = action;
|
||||
return (make_command (which, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_while_command (test, action)
|
||||
COMMAND *test, *action;
|
||||
{
|
||||
return (make_until_or_while (cm_while, test, action));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_until_command (test, action)
|
||||
COMMAND *test, *action;
|
||||
{
|
||||
return (make_until_or_while (cm_until, test, action));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_arith_command (exp)
|
||||
WORD_LIST *exp;
|
||||
{
|
||||
#if defined (DPAREN_ARITHMETIC)
|
||||
COMMAND *command;
|
||||
ARITH_COM *temp;
|
||||
|
||||
command = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));
|
||||
|
||||
temp->flags = 0;
|
||||
temp->line = line_number;
|
||||
temp->exp = exp;
|
||||
|
||||
command->type = cm_arith;
|
||||
command->redirects = (REDIRECT *)NULL;
|
||||
command->flags = 0;
|
||||
|
||||
return (command);
|
||||
#else
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (COND_COMMAND)
|
||||
struct cond_com *
|
||||
make_cond_node (type, op, left, right)
|
||||
int type;
|
||||
WORD_DESC *op;
|
||||
struct cond_com *left, *right;
|
||||
{
|
||||
COND_COM *temp;
|
||||
|
||||
temp = (COND_COM *)xmalloc (sizeof (COND_COM));
|
||||
temp->flags = 0;
|
||||
temp->line = line_number;
|
||||
temp->type = type;
|
||||
temp->op = op;
|
||||
temp->left = left;
|
||||
temp->right = right;
|
||||
|
||||
return (temp);
|
||||
}
|
||||
#endif
|
||||
|
||||
COMMAND *
|
||||
make_cond_command (cond_node)
|
||||
COND_COM *cond_node;
|
||||
{
|
||||
#if defined (COND_COMMAND)
|
||||
COMMAND *command;
|
||||
|
||||
command = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
command->value.Cond = cond_node;
|
||||
|
||||
command->type = cm_cond;
|
||||
command->redirects = (REDIRECT *)NULL;
|
||||
command->flags = 0;
|
||||
command->line = cond_node ? cond_node->line : 0;
|
||||
|
||||
return (command);
|
||||
#else
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_bare_simple_command ()
|
||||
{
|
||||
COMMAND *command;
|
||||
SIMPLE_COM *temp;
|
||||
|
||||
command = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
|
||||
|
||||
temp->flags = 0;
|
||||
itrace("make_bare_simple_command: line_number = %d", line_number);
|
||||
temp->line = line_number;
|
||||
temp->words = (WORD_LIST *)NULL;
|
||||
temp->redirects = (REDIRECT *)NULL;
|
||||
|
||||
command->type = cm_simple;
|
||||
command->redirects = (REDIRECT *)NULL;
|
||||
command->flags = 0;
|
||||
|
||||
return (command);
|
||||
}
|
||||
|
||||
/* Return a command which is the connection of the word or redirection
|
||||
in ELEMENT, and the command * or NULL in COMMAND. */
|
||||
COMMAND *
|
||||
make_simple_command (element, command)
|
||||
ELEMENT element;
|
||||
COMMAND *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. */
|
||||
if (!command)
|
||||
command = make_bare_simple_command ();
|
||||
|
||||
if (element.word)
|
||||
command->value.Simple->words = make_word_list (element.word, command->value.Simple->words);
|
||||
else if (element.redirect)
|
||||
{
|
||||
REDIRECT *r = element.redirect;
|
||||
/* Due to the way <> is implemented, there may be more than a single
|
||||
redirection in element.redirect. We just follow the chain as far
|
||||
as it goes, and hook onto the end. */
|
||||
while (r->next)
|
||||
r = r->next;
|
||||
r->next = command->value.Simple->redirects;
|
||||
command->value.Simple->redirects = element.redirect;
|
||||
}
|
||||
return (command);
|
||||
}
|
||||
|
||||
/* Because we are Bourne compatible, we read the input for this
|
||||
<< or <<- redirection now, from wherever input is coming from.
|
||||
We store the input read into a WORD_DESC. Replace the text of
|
||||
the redirectee.word with the new input text. If <<- is on,
|
||||
then remove leading TABS from each line. */
|
||||
void
|
||||
make_here_document (temp)
|
||||
REDIRECT *temp;
|
||||
{
|
||||
int kill_leading, redir_len;
|
||||
char *redir_word, *document, *full_line;
|
||||
int document_index, document_size, delim_unquoted;
|
||||
|
||||
if (temp->instruction != r_deblank_reading_until &&
|
||||
temp->instruction != r_reading_until)
|
||||
{
|
||||
internal_error (_("make_here_document: bad instruction type %d"), temp->instruction);
|
||||
return;
|
||||
}
|
||||
|
||||
kill_leading = temp->instruction == r_deblank_reading_until;
|
||||
|
||||
document = (char *)NULL;
|
||||
document_index = document_size = 0;
|
||||
|
||||
/* Quote removal is the only expansion performed on the delimiter
|
||||
for here documents, making it an extremely special case. */
|
||||
redir_word = string_quote_removal (temp->redirectee.filename->word, 0);
|
||||
|
||||
/* redirection_expand will return NULL if the expansion results in
|
||||
multiple words or no words. Check for that here, and just abort
|
||||
this here document if it does. */
|
||||
if (redir_word)
|
||||
redir_len = strlen (redir_word);
|
||||
else
|
||||
{
|
||||
temp->here_doc_eof = (char *)xmalloc (1);
|
||||
temp->here_doc_eof[0] = '\0';
|
||||
goto document_done;
|
||||
}
|
||||
|
||||
free (temp->redirectee.filename->word);
|
||||
temp->here_doc_eof = redir_word;
|
||||
|
||||
/* Read lines from wherever lines are coming from.
|
||||
For each line read, if kill_leading, then kill the
|
||||
leading tab characters.
|
||||
If the line matches redir_word exactly, then we have
|
||||
manufactured the document. Otherwise, add the line to the
|
||||
list of lines in the document. */
|
||||
|
||||
/* If the here-document delimiter was quoted, the lines should
|
||||
be read verbatim from the input. If it was not quoted, we
|
||||
need to perform backslash-quoted newline removal. */
|
||||
delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0;
|
||||
while (full_line = read_secondary_line (delim_unquoted))
|
||||
{
|
||||
register char *line;
|
||||
int len;
|
||||
|
||||
line = full_line;
|
||||
line_number++;
|
||||
|
||||
if (kill_leading && *line)
|
||||
{
|
||||
/* Hack: To be compatible with some Bourne shells, we
|
||||
check the word before stripping the whitespace. This
|
||||
is a hack, though. */
|
||||
if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
|
||||
goto document_done;
|
||||
|
||||
while (*line == '\t')
|
||||
line++;
|
||||
}
|
||||
|
||||
if (*line == 0)
|
||||
continue;
|
||||
|
||||
if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
|
||||
goto document_done;
|
||||
|
||||
len = strlen (line);
|
||||
if (len + document_index >= document_size)
|
||||
{
|
||||
document_size = document_size ? 2 * (document_size + len) : len + 2;
|
||||
document = (char *)xrealloc (document, document_size);
|
||||
}
|
||||
|
||||
/* len is guaranteed to be > 0 because of the check for line
|
||||
being an empty string before the call to strlen. */
|
||||
FASTCOPY (line, document + document_index, len);
|
||||
document_index += len;
|
||||
}
|
||||
|
||||
document_done:
|
||||
if (document)
|
||||
document[document_index] = '\0';
|
||||
else
|
||||
{
|
||||
document = (char *)xmalloc (1);
|
||||
document[0] = '\0';
|
||||
}
|
||||
temp->redirectee.filename->word = document;
|
||||
}
|
||||
|
||||
/* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION.
|
||||
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;
|
||||
enum r_instruction instruction;
|
||||
REDIRECTEE dest_and_filename;
|
||||
{
|
||||
REDIRECT *temp;
|
||||
WORD_DESC *w;
|
||||
int wlen;
|
||||
intmax_t lfd;
|
||||
|
||||
temp = (REDIRECT *)xmalloc (sizeof (REDIRECT));
|
||||
|
||||
/* First do the common cases. */
|
||||
temp->redirector = source;
|
||||
temp->redirectee = dest_and_filename;
|
||||
temp->instruction = instruction;
|
||||
temp->flags = 0;
|
||||
temp->next = (REDIRECT *)NULL;
|
||||
|
||||
switch (instruction)
|
||||
{
|
||||
|
||||
case r_output_direction: /* >foo */
|
||||
case r_output_force: /* >| foo */
|
||||
case r_err_and_out: /* command &>filename */
|
||||
temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
|
||||
break;
|
||||
|
||||
case r_appending_to: /* >>foo */
|
||||
temp->flags = O_APPEND | O_WRONLY | O_CREAT;
|
||||
break;
|
||||
|
||||
case r_input_direction: /* <foo */
|
||||
case r_inputa_direction: /* foo & makes this. */
|
||||
temp->flags = O_RDONLY;
|
||||
break;
|
||||
|
||||
case r_input_output: /* <>foo */
|
||||
temp->flags = O_RDWR | O_CREAT;
|
||||
break;
|
||||
|
||||
case r_deblank_reading_until: /* <<-foo */
|
||||
case r_reading_until: /* << foo */
|
||||
case r_reading_string: /* <<< foo */
|
||||
case r_close_this: /* <&- */
|
||||
case r_duplicating_input: /* 1<&2 */
|
||||
case r_duplicating_output: /* 1>&2 */
|
||||
break;
|
||||
|
||||
/* the parser doesn't pass these. */
|
||||
case r_move_input: /* 1<&2- */
|
||||
case r_move_output: /* 1>&2- */
|
||||
case r_move_input_word: /* 1<&$foo- */
|
||||
case r_move_output_word: /* 1>&$foo- */
|
||||
break;
|
||||
|
||||
/* The way the lexer works we have to do this here. */
|
||||
case r_duplicating_input_word: /* 1<&$foo */
|
||||
case r_duplicating_output_word: /* 1>&$foo */
|
||||
w = dest_and_filename.filename;
|
||||
wlen = strlen (w->word) - 1;
|
||||
if (w->word[wlen] == '-') /* Yuck */
|
||||
{
|
||||
w->word[wlen] = '\0';
|
||||
if (all_digits (w->word) && legal_number (w->word, &lfd) && lfd == (int)lfd)
|
||||
{
|
||||
dispose_word (w);
|
||||
temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input : r_move_output;
|
||||
temp->redirectee.dest = lfd;
|
||||
}
|
||||
else
|
||||
temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input_word : r_move_output_word;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction);
|
||||
abort ();
|
||||
break;
|
||||
}
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_function_def (name, command, lineno, lstart)
|
||||
WORD_DESC *name;
|
||||
COMMAND *command;
|
||||
int lineno, lstart;
|
||||
{
|
||||
FUNCTION_DEF *temp;
|
||||
#if defined (ARRAY_VARS)
|
||||
SHELL_VAR *bash_source_v;
|
||||
ARRAY *bash_source_a;
|
||||
char *t;
|
||||
#endif
|
||||
|
||||
temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
|
||||
temp->command = command;
|
||||
temp->name = name;
|
||||
temp->line = lineno;
|
||||
temp->flags = 0;
|
||||
command->line = lstart;
|
||||
|
||||
/* Information used primarily for debugging. */
|
||||
temp->source_file = 0;
|
||||
#if defined (ARRAY_VARS)
|
||||
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
|
||||
if (bash_source_a && array_num_elements (bash_source_a) > 0)
|
||||
temp->source_file = array_reference (bash_source_a, 0);
|
||||
#endif
|
||||
bind_function_def (name->word, temp);
|
||||
|
||||
temp->source_file = 0;
|
||||
return (make_command (cm_function_def, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_subshell_command (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
SUBSHELL_COM *temp;
|
||||
|
||||
temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
|
||||
temp->command = command;
|
||||
temp->flags = CMD_WANT_SUBSHELL;
|
||||
return (make_command (cm_subshell, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
/* Reverse the word list and redirection list in the simple command
|
||||
has just been parsed. It seems simpler to do this here the one
|
||||
time then by any other method that I can think of. */
|
||||
COMMAND *
|
||||
clean_simple_command (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
if (command->type != cm_simple)
|
||||
command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0);
|
||||
else
|
||||
{
|
||||
command->value.Simple->words =
|
||||
REVERSE_LIST (command->value.Simple->words, WORD_LIST *);
|
||||
command->value.Simple->redirects =
|
||||
REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
|
||||
}
|
||||
|
||||
return (command);
|
||||
}
|
||||
|
||||
/* The Yacc grammar productions have a problem, in that they take a
|
||||
list followed by an ampersand (`&') and do a simple command connection,
|
||||
making the entire list effectively asynchronous, instead of just
|
||||
the last command. This means that when the list is executed, all
|
||||
the commands have stdin set to /dev/null when job control is not
|
||||
active, instead of just the last. This is wrong, and needs fixing
|
||||
up. This function takes the `&' and applies it to the last command
|
||||
in the list. This is done only for lists connected by `;'; it makes
|
||||
`;' bind `tighter' than `&'. */
|
||||
COMMAND *
|
||||
connect_async_list (command, command2, connector)
|
||||
COMMAND *command, *command2;
|
||||
int connector;
|
||||
{
|
||||
COMMAND *t, *t1, *t2;
|
||||
|
||||
t1 = command;
|
||||
t = command->value.Connection->second;
|
||||
|
||||
if (!t || (command->flags & CMD_WANT_SUBSHELL) ||
|
||||
command->value.Connection->connector != ';')
|
||||
{
|
||||
t = command_connect (command, command2, connector);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* This is just defensive programming. The Yacc precedence rules
|
||||
will generally hand this function a command where t points directly
|
||||
to the command we want (e.g. given a ; b ; c ; d &, t1 will point
|
||||
to the `a ; b ; c' list and t will be the `d'). We only want to do
|
||||
this if the list is not being executed as a unit in the background
|
||||
with `( ... )', so we have to check for CMD_WANT_SUBSHELL. That's
|
||||
the only way to tell. */
|
||||
while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection &&
|
||||
t->value.Connection->connector == ';')
|
||||
{
|
||||
t1 = t;
|
||||
t = t->value.Connection->second;
|
||||
}
|
||||
/* Now we have t pointing to the last command in the list, and
|
||||
t1->value.Connection->second == t. */
|
||||
t2 = command_connect (t, command2, connector);
|
||||
t1->value.Connection->second = t2;
|
||||
return command;
|
||||
}
|
||||
@@ -2149,8 +2149,8 @@ discard_until (character)
|
||||
}
|
||||
|
||||
void
|
||||
execute_prompt_command (command)
|
||||
char *command;
|
||||
execute_variable_command (command, vname)
|
||||
char *command, *vname;
|
||||
{
|
||||
char *last_lastarg;
|
||||
sh_parser_state_t ps;
|
||||
@@ -2160,7 +2160,7 @@ execute_prompt_command (command)
|
||||
if (last_lastarg)
|
||||
last_lastarg = savestring (last_lastarg);
|
||||
|
||||
parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
|
||||
parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
|
||||
|
||||
restore_parser_state (&ps);
|
||||
bind_variable ("_", last_lastarg, 0);
|
||||
|
||||
@@ -21,6 +21,7 @@ Icons {
|
||||
|
||||
Simon.
|
||||
|
||||
Copyright (C) 1992 Simon Marshall
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#define bash_width 64
|
||||
#define bash_height 48
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
Unless otherwise stated, all files in this directory are Copyright (C)
|
||||
1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
The file ifs-posix.tests is Copyright (C) 2005 Glen Fowler.
|
||||
@@ -1 +1,3 @@
|
||||
Type `sh run-all'.
|
||||
|
||||
Read COPYRIGHT for copyright information.
|
||||
|
||||
Reference in New Issue
Block a user