commit bash-20060322 snapshot

This commit is contained in:
Chet Ramey
2011-12-03 22:46:30 -05:00
parent 74d9692be0
commit 591dd2e5f8
30 changed files with 6661 additions and 69 deletions
+1 -1
View File
@@ -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
+5287
View File
File diff suppressed because it is too large Load Diff
+23
View File
@@ -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).
+29
View File
@@ -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>
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+321
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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}
+1 -1
View File
@@ -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 */
+1 -1
View File
@@ -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 *));
+4
View File
@@ -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
#
+2 -2
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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
+3
View File
@@ -32,6 +32,9 @@ Let me know what you think.
Jeff
*/
/*
Copyright (C) 1999 Jeff Solomon
*/
#if defined (HAVE_CONFIG_H)
#include <config.h>
+1 -1
View File
@@ -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);
+4
View File
@@ -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
View File
@@ -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;
}
+3 -3
View File
@@ -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);
+1
View File
@@ -21,6 +21,7 @@ Icons {
Simon.
Copyright (C) 1992 Simon Marshall
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define bash_width 64
#define bash_height 48
+5
View File
@@ -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.
+2
View File
@@ -1 +1,3 @@
Type `sh run-all'.
Read COPYRIGHT for copyright information.