Imported from ../bash-2.0.tar.gz.
This commit is contained in:
@@ -1 +1 @@
|
|||||||
1.14
|
2.0
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
7
|
0
|
||||||
|
|||||||
575
CHANGES
Normal file
575
CHANGES
Normal file
@@ -0,0 +1,575 @@
|
|||||||
|
This document details the changes between this version, bash-2.0-release,
|
||||||
|
and the previous version, bash-2.0-beta3.
|
||||||
|
|
||||||
|
1. Changes to Bash
|
||||||
|
|
||||||
|
a. Fix to the `getopts' builtin so that it does the right thing when a
|
||||||
|
required option argument is not present.
|
||||||
|
|
||||||
|
b. The completion code now updates the common prefix of matched names
|
||||||
|
after FIGNORE processing is done, since any names that were removed
|
||||||
|
may have changed the common prefix.
|
||||||
|
|
||||||
|
c. Fixed a bug that made messages in MAILPATH entries not work correctly.
|
||||||
|
|
||||||
|
d. Fixed a serious documentation error in the description of the new
|
||||||
|
${parameter:offset[:length]} expansion.
|
||||||
|
|
||||||
|
e. Fixes to make parameter substring expansion ({$param:offset[:length]})
|
||||||
|
work when within double quotes.
|
||||||
|
|
||||||
|
f. Fixes to make ^A (CTLESC) survive an unquoted expansion of positional
|
||||||
|
parameters.
|
||||||
|
|
||||||
|
g. Corrected a misspelling of `unlimited' in the output of `ulimit'.
|
||||||
|
|
||||||
|
h. Fixed a bug that caused executable scripts without a leading `#!' to
|
||||||
|
occasionally pick up the wrong set of positional parameters.
|
||||||
|
|
||||||
|
i. Linux systems now have a working `ulimit -v', using RLIMIT_AS.
|
||||||
|
|
||||||
|
j. Updated config.guess so that many more machine types are recognized.
|
||||||
|
|
||||||
|
k. Fixed a bug with backslash-quoted slashes in the ${param/pat[/sub]}
|
||||||
|
expansion.
|
||||||
|
|
||||||
|
l. If the shell is named `-su', and `-c command' is supplied, read and
|
||||||
|
execute the login shell startup files even though the shell is not
|
||||||
|
interactive. This is to support the `-' option to `su'.
|
||||||
|
|
||||||
|
m. Fixed a bug that caused core dumps when the DEBUG trap was ignored
|
||||||
|
with `trap "" DEBUG' and a shell function was subsequently executed.
|
||||||
|
|
||||||
|
n. Fixed a bug that caused core dumps in the read builtin when IFS was
|
||||||
|
set to the null string and the input had leading whitespace.
|
||||||
|
|
||||||
|
2. Changes to Readline
|
||||||
|
|
||||||
|
a. Fixed a bug that caused a numeric argument of 1024 to be ignored when
|
||||||
|
inserting text.
|
||||||
|
|
||||||
|
b. Fixed the display code so that the numeric argument is displayed as it's
|
||||||
|
being entered.
|
||||||
|
|
||||||
|
c. Fixed the numeric argument reading code so that `M-- command' is
|
||||||
|
equivalent to `M--1 command', as the prompt implies.
|
||||||
|
|
||||||
|
3. New Features in Bash
|
||||||
|
|
||||||
|
a. `ulimit' now sets both hard and soft limits and reports the soft limit
|
||||||
|
by default (when neither -H nor -S is specified). This is compatible
|
||||||
|
with versions of sh and ksh that implement `ulimit'.
|
||||||
|
|
||||||
|
b. Integer constants have been extended to base 64.
|
||||||
|
|
||||||
|
4. New Features in Readline
|
||||||
|
|
||||||
|
a. The `home' and `end' keys are now bound to beginning-of-line and
|
||||||
|
end-of-line, respectively, if the corresponding termcap capabilities
|
||||||
|
are present.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This document details the changes between this version, bash-2.0-beta3,
|
||||||
|
and the previous version, bash-2.0-beta2.
|
||||||
|
|
||||||
|
1. Changes to Bash
|
||||||
|
|
||||||
|
a. System-specific changes for: AIX 4.2, SCO 3.2v[45], HP-UX.
|
||||||
|
|
||||||
|
b. When in POSIX mode, variable assignments preceding a special builtin
|
||||||
|
persist in the shell environment after the builtin completes.
|
||||||
|
|
||||||
|
c. Changed all calls to getwd() to getcwd(). Improved check for systems
|
||||||
|
where the libc getcwd() calls popen(), since that breaks on some
|
||||||
|
systems when job control is being used.
|
||||||
|
|
||||||
|
d. Fixed a bug that caused seg faults when executing scripts with the
|
||||||
|
execute bit set but without a leading `#!'.
|
||||||
|
|
||||||
|
e. The environment passed to executed commands is never sorted.
|
||||||
|
|
||||||
|
f. A bug was fixed in the code that expands ${name[@]} to the number of
|
||||||
|
elements in an array variable.
|
||||||
|
|
||||||
|
g. A bug was fixed in the array compound assignment code ( A=( ... ) ).
|
||||||
|
|
||||||
|
h. Window size changes now correctly propagate down to readline if
|
||||||
|
the shopt `checkwinsize' option is enabled.
|
||||||
|
|
||||||
|
i. A fix was made in the code that expands to the length of a variable
|
||||||
|
value (${#var}).
|
||||||
|
|
||||||
|
j. A fix was made to the command builtin so that it did not turn on the
|
||||||
|
`no fork' flag inappropriately.
|
||||||
|
|
||||||
|
k. A fix was made to make `set -n' work more reliably.
|
||||||
|
|
||||||
|
l. A fix was made to the job control initialization code so that the
|
||||||
|
terminal process group is set to the shell's process group if the
|
||||||
|
shell changes its own process group.
|
||||||
|
|
||||||
|
2. Changes to Readline
|
||||||
|
|
||||||
|
a. System-specific changes for: SCO 3.2v[45].
|
||||||
|
|
||||||
|
b. The behavior of the vi-mode `.' when redoing an `i' command was changed
|
||||||
|
to insert the text previously inserted by the `i' command rather than
|
||||||
|
simply entering insert mode.
|
||||||
|
|
||||||
|
3. New features in Bash
|
||||||
|
|
||||||
|
a. There is a new version of the autoload function package, in
|
||||||
|
examples/functions/autoload.v2, that uses arrays and provides more
|
||||||
|
functionality.
|
||||||
|
|
||||||
|
b. Support for LC_COLLATE and locale-specific sorting of the results of
|
||||||
|
pathname expansion if strcoll() is available.
|
||||||
|
|
||||||
|
4. New Features in Readline
|
||||||
|
|
||||||
|
a. Support for locale-specific sorting of completion possibilities if
|
||||||
|
strcoll() is available.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This document details the changes between this version, bash-2.0-beta2,
|
||||||
|
and the previous version, bash-2.0-beta1.
|
||||||
|
|
||||||
|
1. Changes to Bash
|
||||||
|
|
||||||
|
a. `pushd -' is once again equivalent to `pushd $OLDPWD'.
|
||||||
|
|
||||||
|
b. OS-specific changes for: SCO 3.2v[45].
|
||||||
|
|
||||||
|
c. A change was made to the fix for the recently-reported security hole
|
||||||
|
when reading characters with octal value 255 to make it work better on
|
||||||
|
systems with restartable system calls when not using readline.
|
||||||
|
|
||||||
|
d. Some changes were made to the test suite so that it works if you
|
||||||
|
configure bash with --enable-usg-echo-default.
|
||||||
|
|
||||||
|
e. A fix was made to the parsing of conditional arithmetic expressions.
|
||||||
|
|
||||||
|
f. Illegal arithmetic bases now cause an arithmetic evaluation error rather
|
||||||
|
than being silently reset.
|
||||||
|
|
||||||
|
g. Multiple arithmetic bases now cause an arithmetic evaluation error
|
||||||
|
instead of being ignored.
|
||||||
|
|
||||||
|
h. A fix was made to the evaluation of ${param?word} to conform to POSIX.2.
|
||||||
|
|
||||||
|
i. A bug that sometimes caused array indices to be evaluated twice (which
|
||||||
|
would cause errors when they contained assignment statements) was fixed.
|
||||||
|
|
||||||
|
j. `ulimit' was rewritten to avoid problems with getrlimit(2) returning
|
||||||
|
unsigned values and to simplify the code.
|
||||||
|
|
||||||
|
k. A bug in the command-oriented-history code that caused it to sometimes
|
||||||
|
put semicolons after right parens inappropriately was fixed.
|
||||||
|
|
||||||
|
l. The values inserted into the prompt by the \w and \W escape sequences
|
||||||
|
are now quoted to prevent further expansion.
|
||||||
|
|
||||||
|
m. An interactive shell invoked as `sh' now reads and executes commands
|
||||||
|
from the file named by $ENV when it starts up. If it's a login shell,
|
||||||
|
it does this after reading /etc/profile and ~/.profile.
|
||||||
|
|
||||||
|
n. The file named by $ENV is never read by non-interactive shells.
|
||||||
|
|
||||||
|
2. Changes to Readline
|
||||||
|
|
||||||
|
a. A few changes were made to hide some macros and functions that should not
|
||||||
|
be public.
|
||||||
|
|
||||||
|
b. An off-by-one error that caused seg faults in the history expansion code
|
||||||
|
was fixed.
|
||||||
|
|
||||||
|
3. New Features in Bash
|
||||||
|
|
||||||
|
a. The ksh-style ((...)) arithmetic command was implemented. It is exactly
|
||||||
|
identical to let "...". This is controlled by a new option to configure,
|
||||||
|
`--enable-dparen-arithmetic', which is on by default.
|
||||||
|
|
||||||
|
b. There is a new #define available in config.h.top: SYS_BASH_LOGOUT. If
|
||||||
|
defined to a filename, bash reads and executes commands from that file
|
||||||
|
when a login shell exits. It's commented out by default.
|
||||||
|
|
||||||
|
c. `ulimit' has a `-l' option that reports the maximum amount of data that
|
||||||
|
may be locked into memory on 4.4BSD-based systems.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This document details the changes between this version, bash-2.0-beta1,
|
||||||
|
and the previous version, bash-2.0-alpha4.
|
||||||
|
|
||||||
|
1. Changes to Bash
|
||||||
|
|
||||||
|
a. A bug that sometimes caused traps to be ignored on signals the
|
||||||
|
shell treats specially was fixed.
|
||||||
|
|
||||||
|
b. The internationalization code was changed to track the values of
|
||||||
|
LC_* variables and call setlocale() as appropriate. The TEXTDOMAIN
|
||||||
|
and TEXTDOMAINDIR variables are also tracked; changes cause calls
|
||||||
|
to textdomain() and bindtextdomain(), if available.
|
||||||
|
|
||||||
|
c. A bug was fixed that sometimes caused double-quoted strings to be
|
||||||
|
parsed incorrectly.
|
||||||
|
|
||||||
|
d. Changes were made so that the siglist code compiles correctly on
|
||||||
|
Solaris 2.5.
|
||||||
|
|
||||||
|
e. Added `:' to the set of characters that cause word breaks for the
|
||||||
|
completion code so that pathnames in assignments to $PATH can be
|
||||||
|
completed.
|
||||||
|
|
||||||
|
f. The `select' command was fixed to print $PS3 to stderr.
|
||||||
|
|
||||||
|
g. Fixed an error in the manual page section describing the effect that
|
||||||
|
setting and unsetting GLOBIGNORE has on the setting of the `dotglob'
|
||||||
|
option.
|
||||||
|
|
||||||
|
h. The time conversion code now uses CLK_TCK rather than CLOCKS_PER_SEC
|
||||||
|
on systems without gettimeofday() and resources.
|
||||||
|
|
||||||
|
i. The getopt static variables are now initialized each time a subshell
|
||||||
|
is started, so subshells using `getopts' work right.
|
||||||
|
|
||||||
|
j. A sign-extension bug that caused a possible security hole was fixed.
|
||||||
|
|
||||||
|
k. The parser now reads characters between backquotes within a double-
|
||||||
|
quoted string as a single word, so double quotes in the backquoted
|
||||||
|
string don't terminate the enclosing double-quoted string.
|
||||||
|
|
||||||
|
l. A bug that caused `^O' to work incorrectly when typed as the first
|
||||||
|
thing to an interactive shell was fixed.
|
||||||
|
|
||||||
|
m. A rarely-exercised off-by-one error in the code that quotes variable
|
||||||
|
values was fixed.
|
||||||
|
|
||||||
|
n. Some memory and file descriptor leaks encountered when running a
|
||||||
|
shell script that is executable but does not have a leading `#!'
|
||||||
|
were plugged.
|
||||||
|
|
||||||
|
2. Changes to Readline
|
||||||
|
|
||||||
|
a. A bug that sometimes caused incorrect results when trying to read
|
||||||
|
typeahead on systems without FIONREAD was fixed.
|
||||||
|
|
||||||
|
3. New Features in Bash
|
||||||
|
|
||||||
|
a. The command timing code now uses the value of the TIMEFORMAT variable
|
||||||
|
to format and display timing statistics.
|
||||||
|
|
||||||
|
b. The `time' reserved word now accepts a `-p' option to force the
|
||||||
|
POSIX.2 output format.
|
||||||
|
|
||||||
|
c. There are a couple of new and updated scripts to convert csh startup
|
||||||
|
files to bash format.
|
||||||
|
|
||||||
|
d. There is a new builtin array variable: BASH_VERSINFO. The various
|
||||||
|
members hold the parts of the version information in BASH_VERSION,
|
||||||
|
plus the value of MACHTYPE.
|
||||||
|
|
||||||
|
4. New Features in Readline
|
||||||
|
|
||||||
|
a. Setting LANG to `en_US.ISO8859-1' now causes readline to enter
|
||||||
|
eight-bit mode.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This document details the changes between this version, bash-2.0-alpha4,
|
||||||
|
and the previous version, bash-2.0-alpha3.
|
||||||
|
|
||||||
|
1. Changes to Bash
|
||||||
|
|
||||||
|
a. There is better detection of rsh connections on Solaris 2.
|
||||||
|
|
||||||
|
b. Assignments to read-only variables preceding a command name are now
|
||||||
|
variable assignment errors. Variable assignment errors cause
|
||||||
|
non-interactive shells running in posix mode to exit.
|
||||||
|
|
||||||
|
c. The word tokenizer was rewritten to handle nested quotes and pairs
|
||||||
|
('', "", ``, ${...}, $(...), $[...], $'...', $"...", <(...), >(...))
|
||||||
|
correctly. Some of the parameter expansion code was updated as a
|
||||||
|
consequence.
|
||||||
|
|
||||||
|
d. A fix was made to `test' when given three arguments so that a binary
|
||||||
|
operator is checked for first, before checking that the first argument
|
||||||
|
is `!'.
|
||||||
|
|
||||||
|
e. 2''>/dev/null is no longer equivalent to 2>/dev/null.
|
||||||
|
|
||||||
|
f. Parser error messages were regularized, and in most cases the name of
|
||||||
|
the shell script being read by a non-interactive shell is not printed
|
||||||
|
twice.
|
||||||
|
|
||||||
|
g. A fix was made to the completion code so that it no longer removes the
|
||||||
|
text the user typed in some cases.
|
||||||
|
|
||||||
|
h. The special glibc `getopt' environment variable is no longer put into
|
||||||
|
the environment on machines with small values of ARG_MAX.
|
||||||
|
|
||||||
|
i. The expansion of ${...} now follows the POSIX.2 rules for finding the
|
||||||
|
closing `}'.
|
||||||
|
|
||||||
|
j. The shell no longer displays spurious status messages for background
|
||||||
|
jobs in shell scripts that complete successfully when the script is
|
||||||
|
run from a terminal.
|
||||||
|
|
||||||
|
k. `shopt -o' now correctly updates $SHELLOPTS.
|
||||||
|
|
||||||
|
l. A bug that caused the $PATH searching code to return a non-executable
|
||||||
|
file even when an executable file with the same name appeared later in
|
||||||
|
$PATH was fixed.
|
||||||
|
|
||||||
|
m. The shell now does tilde expansions on unquoted `:~' in assignment
|
||||||
|
statements when not in posix mode.
|
||||||
|
|
||||||
|
n. Variable assignment errors when a command consists only of assignments
|
||||||
|
now cause non-interactive shells to exit when in posix mode.
|
||||||
|
|
||||||
|
o. If the variable in a `for' or `select' command is read-only, or not a
|
||||||
|
legal shell identifier, a variable assignment error occurs.
|
||||||
|
|
||||||
|
p. `test' now handles `-a' and `-o' as binary operators when three arguments
|
||||||
|
are supplied, and correctly parses `( word )' as equivalent to `word'.
|
||||||
|
|
||||||
|
q. `test' was fixed so that file names of the form /dev/fd/NN mean the same
|
||||||
|
thing on all systems, even Linux.
|
||||||
|
|
||||||
|
r. Fixed a bug in the globbing code that caused patterns with multiple
|
||||||
|
consecutive `*'s to not be matched correctly.
|
||||||
|
|
||||||
|
s. Fixed a bug that caused $PS2 to not be printed when an interactive shell
|
||||||
|
not using readline is reading a here document.
|
||||||
|
|
||||||
|
t. Fixed a bug that caused history expansion to be performed inappropriately
|
||||||
|
when a single-quoted string spanned more than one line.
|
||||||
|
|
||||||
|
u. `getopts' now checks that the variable name passed by the user as the
|
||||||
|
second argument is a legal shell identifier and that the variable is
|
||||||
|
not read-only.
|
||||||
|
|
||||||
|
v. Fixed `getopts' to obey POSIX.2 rules for setting $OPTIND when it
|
||||||
|
encounters an error.
|
||||||
|
|
||||||
|
w. Fixed `set' to display variable values in a form that can be re-read.
|
||||||
|
|
||||||
|
x. Fixed a bug in the code that keeps track of whether or not local variables
|
||||||
|
have been declared at the current level of function nesting.
|
||||||
|
|
||||||
|
y. Non-interactive shells in posix mode now exit if the name in a function
|
||||||
|
declaration is not a legal identifier.
|
||||||
|
|
||||||
|
z. The job control code now ignores stopped children when the shell is not
|
||||||
|
interactive.
|
||||||
|
|
||||||
|
aa. The `cd' builtin no longer attempts spelling correction on the directory
|
||||||
|
name if the shell is not interactive, regardless of the setting of the
|
||||||
|
`cdspell' option.
|
||||||
|
|
||||||
|
bb. Some OS-specific changes were made for SCO 3.2v[45] and AIX 4.2.
|
||||||
|
|
||||||
|
cc. `time' now prints its output to stderr, as POSIX.2 specifies.
|
||||||
|
|
||||||
|
2. Fixes to Readline
|
||||||
|
|
||||||
|
a. After printing possible completions, all lines of a multi-line prompt
|
||||||
|
are redisplayed.
|
||||||
|
|
||||||
|
b. Some changes were made to the terminal handling code in rltty.c to
|
||||||
|
work around AIX 4.2 bugs.
|
||||||
|
|
||||||
|
3. New Features in Bash
|
||||||
|
|
||||||
|
a. There is a new loadable builtin: sprintf, with calling syntax
|
||||||
|
sprintf var format [args]
|
||||||
|
This provides an easy way to simulate ksh left- and right-justified
|
||||||
|
variable values.
|
||||||
|
|
||||||
|
b. The expansions of \h and \H in prompt strings were swapped. \h now
|
||||||
|
expands to the hostname up to the first `.', as in bash-1.14.
|
||||||
|
|
||||||
|
4. New Features in Readline
|
||||||
|
|
||||||
|
a. The bash-1.14 behavior when ^M is typed while doing an incremental
|
||||||
|
search was restored. ^J may now be used to terminate the search without
|
||||||
|
accepting the line.
|
||||||
|
|
||||||
|
b. There is a new bindable variable: disable-completion. This inhibits
|
||||||
|
word completion and causes the completion character to be inserted as
|
||||||
|
if it had been bound to self-insert.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This document details the changes between this version, bash-2.0-alpha3,
|
||||||
|
and the previous version, bash-2.0-alpha2.
|
||||||
|
|
||||||
|
There is now a file `COMPAT' included in the distribution that lists the
|
||||||
|
user-visible incompatibilities between 1.14 and 2.0.
|
||||||
|
|
||||||
|
1. Changes to Bash
|
||||||
|
|
||||||
|
a. Some work was done so that word splitting of the rhs of assignment
|
||||||
|
statements conforms more closely to historical practice.
|
||||||
|
|
||||||
|
b. A couple of errant memory frees were fixed.
|
||||||
|
|
||||||
|
c. A fix was made to the test builtin so it recognizes `<' and `>' as
|
||||||
|
binary operators.
|
||||||
|
|
||||||
|
d. The GNU malloc in lib/malloc/malloc.c now scrambles memory as it's
|
||||||
|
allocated and freed. This is to catch callers that refer to freed
|
||||||
|
memory or assume something about newly-allocated memory.
|
||||||
|
|
||||||
|
e. Fixed a problem with conversion to 12-hour time in the prompt
|
||||||
|
expansion code.
|
||||||
|
|
||||||
|
f. Fixed a problem with configure's argument parsing order. Now you can
|
||||||
|
correctly turn on specific options after using --enable-minimal-config.
|
||||||
|
|
||||||
|
g. The configure script now automatically disables the use of GNU malloc
|
||||||
|
on systems where it's appropriate (better than having people read the
|
||||||
|
NOTES file and do it manually).
|
||||||
|
|
||||||
|
h. There are new prompt expansions (\v and \V) to insert version information
|
||||||
|
into the prompt strings.
|
||||||
|
|
||||||
|
i. The default prompt string now includes the version number.
|
||||||
|
|
||||||
|
j. Most of the builtins that take no options were changed to use the
|
||||||
|
internal getopt so they can produce proper error messages for -?
|
||||||
|
and incorrect options.
|
||||||
|
|
||||||
|
k. Some system-specific changes were made for SVR4.2 and Solaris 2.5.
|
||||||
|
|
||||||
|
l. Bash now uses PATH_MAX instead of MAXPATHLEN and NAME_MAX instead of
|
||||||
|
MAXNAMLEN.
|
||||||
|
|
||||||
|
m. A couple of problems caused by uninitialized variables were fixed.
|
||||||
|
|
||||||
|
n. There are a number of new loadable builtin examples: logname, basename,
|
||||||
|
dirname, tty, pathchk, tee, head, and rmdir. All of these conform to
|
||||||
|
POSIX.2.
|
||||||
|
|
||||||
|
o. Bash now notices changes in TZ and calls tzset() if present, so
|
||||||
|
changing TZ will alter the time printed by prompt expansions.
|
||||||
|
|
||||||
|
p. The source was reorganized a bit so I don't have to wait so long for
|
||||||
|
some files to compile, and to facilitate the creation of a `shell
|
||||||
|
library' at some future point.
|
||||||
|
|
||||||
|
q. Bash no longer turns off job control if called as `sh', since the
|
||||||
|
POSIX.2 spec includes job control as a standard feature.
|
||||||
|
|
||||||
|
r. `bash -o posix' now works as intended.
|
||||||
|
|
||||||
|
s. Fixed a problem with the completion code: when completing a filename
|
||||||
|
that contained globbing characters, if show-all-if-ambiguous was set,
|
||||||
|
the completion code would remove the user's text.
|
||||||
|
|
||||||
|
t. Fixed ulimit so that (hopefully) the full range of limits is available
|
||||||
|
on HPUX systems.
|
||||||
|
|
||||||
|
u. A new `shopt' option (`hostcomplete') enables and disables hostname
|
||||||
|
completion.
|
||||||
|
|
||||||
|
v. The shell no longer attempts to save the history on an abort(),
|
||||||
|
which is usually called by programming_error().
|
||||||
|
|
||||||
|
w. The `-s' option to `fc' was changed to echo the command to be executed
|
||||||
|
to stderr instead of stdout.
|
||||||
|
|
||||||
|
x. If the editor invoked by `fc -e' exits with a non-zero status, no
|
||||||
|
commands are executed.
|
||||||
|
|
||||||
|
y. Fixed a bug that made the shopt `histverify' option work incorrectly.
|
||||||
|
|
||||||
|
z. There is a new variable `MACHTYPE' whose value is the GNU-style
|
||||||
|
`cpu-company-system' system description as set by configure. (The
|
||||||
|
values of MACHTYPE and HOSTTYPE should really be swapped.)
|
||||||
|
|
||||||
|
aa. The `ulimit' builtin now allows the maximum virtual memory size to be
|
||||||
|
set via setrlimit(2) if RLIMIT_VMEM is defined.
|
||||||
|
|
||||||
|
bb. `bash -nc 'command'' no longer runs `command'.
|
||||||
|
|
||||||
|
2. Changes to Readline
|
||||||
|
|
||||||
|
a. Fixed a typo in the code that checked for FIONREAD in input.c.
|
||||||
|
|
||||||
|
b. Fixed a bug in the code that outputs keybindings, so things like C-\
|
||||||
|
are quoted properly.
|
||||||
|
|
||||||
|
c. Fixed a bug in the inputrc file parsing code to handle the problems
|
||||||
|
caused by inputrc files created from the output of `bind -p' in
|
||||||
|
previous versions of bash. The problem was due to the bug fixed
|
||||||
|
in item b above.
|
||||||
|
|
||||||
|
d. Readline no longer turns off the terminal's meta key, and turns it on
|
||||||
|
once the first time it's called.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This file documents the changes between this version, bash-2.0-alpha2,
|
||||||
|
and the previous version, bash-2.0-alpha.
|
||||||
|
|
||||||
|
1. Changes to Bash
|
||||||
|
|
||||||
|
a. The shell no longer thinks directories are executable.
|
||||||
|
|
||||||
|
b. `disown' has a new option, `h', which inhibits the resending of SIGHUP
|
||||||
|
but does not remove the job from the jobs table.
|
||||||
|
|
||||||
|
c. The varargs functions in error.c now use ANSI-C `stdarg' if available.
|
||||||
|
|
||||||
|
d. The build process now treats the `build version' in .build as local to
|
||||||
|
the build directory, so different versions built from the same source
|
||||||
|
tree have different `build versions'.
|
||||||
|
|
||||||
|
e. Some problems with the grammar have been fixed. (It used `list' in a few
|
||||||
|
productions where `compound_list' was needed. A `list' must be terminated
|
||||||
|
with a newline or semicolon; a `compound_list' need not be.)
|
||||||
|
|
||||||
|
f. A fix was made to keep `wait' from hanging when waiting for all background
|
||||||
|
jobs.
|
||||||
|
|
||||||
|
g. `bash --help' now writes its output to stdout, like the GNU Coding Standards
|
||||||
|
specify, and includes the machine type (the value of MACHTYPE).
|
||||||
|
|
||||||
|
h. `bash --version' now prints more information and exits successfully, like
|
||||||
|
the GNU Coding Standards specify.
|
||||||
|
|
||||||
|
i. The output of `time' and `times' now prints fractional seconds with three
|
||||||
|
places after the decimal point.
|
||||||
|
|
||||||
|
j. A bug that caused process substitutions to screw up the pipeline printed
|
||||||
|
by `jobs' was fixed.
|
||||||
|
|
||||||
|
k. Fixes were made to the code that implements $'...' and $"..." so they
|
||||||
|
work as documented.
|
||||||
|
|
||||||
|
l. The process substitution code now opens named pipes for reading with
|
||||||
|
O_NONBLOCK to avoid hanging.
|
||||||
|
|
||||||
|
m. Fixes were made to the trap code so the shell cleans up correctly if the
|
||||||
|
trap command contains a `return' and we're executing a function or
|
||||||
|
sourcing a script with `.'.
|
||||||
|
|
||||||
|
n. Fixes to doc/Makefile.in so that it doesn't try to remake all of the
|
||||||
|
documentation (ps, dvi, etc.) on a `make install'.
|
||||||
|
|
||||||
|
o. Fixed an auto-increment error that caused bash -c args to sometimes dump
|
||||||
|
core.
|
||||||
|
|
||||||
|
p. Fixed a bug that caused $HISTIGNORE to fail when the history line
|
||||||
|
contained globbing characters.
|
||||||
|
|
||||||
|
2. Changes to Readline
|
||||||
|
|
||||||
|
a. There is a new string variable, rl_library_version, available for use by
|
||||||
|
applications. The current value is "2.1".
|
||||||
|
|
||||||
|
b. A bug encountered when expand-tilde was enabled and file completion was
|
||||||
|
attempted on a word beginning with `~/' was fixed.
|
||||||
|
|
||||||
|
c. A slight change was made to the incremental search termination behavior.
|
||||||
|
ESC still terminates the search, but if input is pending or arrives
|
||||||
|
within 0.1 seconds (on systems with select(2)), it is used as a prefix
|
||||||
|
character. This is intented to allow users to terminate searches with
|
||||||
|
the arrow keys and get the behavior they expect.
|
||||||
78
COMPAT
Normal file
78
COMPAT
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
This document details the incompatibilites between this version of bash,
|
||||||
|
bash-2.0, and the previous version, bash-1.14. These were discovered
|
||||||
|
by alpha and beta testers, so they will likely be encountered by a
|
||||||
|
significant number of users.
|
||||||
|
|
||||||
|
1. Bash now uses a new quoting syntax, $"...", to do locale-specific
|
||||||
|
string translation. Users who have relied on the (undocumented)
|
||||||
|
behavior of bash-1.14 will have to change their scripts. For
|
||||||
|
instance, if you are doing something like this to get the value of
|
||||||
|
a variable whose name is the value of a second variable:
|
||||||
|
|
||||||
|
eval var2=$"$var1"
|
||||||
|
|
||||||
|
you will have to change to a different syntax.
|
||||||
|
|
||||||
|
This capability is directly supported by bash-2.0:
|
||||||
|
|
||||||
|
var2=${!var1}
|
||||||
|
|
||||||
|
This alternate syntax will work portably between bash-1.14 and bash-2.0:
|
||||||
|
|
||||||
|
eval var2=\$${var1}
|
||||||
|
|
||||||
|
2. One of the bugs fixed in the YACC grammar tightens up the rules
|
||||||
|
concerning group commands ( {...} ). The `list' that composes the
|
||||||
|
body of the group command must be terminated by a newline or
|
||||||
|
semicolon. That's because the braces are reserved words, and are
|
||||||
|
recognized as such only when a reserved word is legal. This means
|
||||||
|
that while bash-1.14 accepted shell function definitions like this:
|
||||||
|
|
||||||
|
foo() { : }
|
||||||
|
|
||||||
|
bash-2.0 requires this:
|
||||||
|
|
||||||
|
foo() { :; }
|
||||||
|
|
||||||
|
This is also an issue for commands like this:
|
||||||
|
|
||||||
|
mkdir dir || { echo 'could not mkdir' ; exit 1; }
|
||||||
|
|
||||||
|
The syntax required by bash-2.0 is also accepted by bash-1.14.
|
||||||
|
|
||||||
|
3. The options to `bind' have changed to make them more consistent with
|
||||||
|
the rest of the bash builtins. If you are using `bind -d' to list
|
||||||
|
the readline keybindings in a form that can be re-read, use `bind -p'
|
||||||
|
instead. If you were using `bind -v' to list the keybindings, use
|
||||||
|
`bind -P' instead.
|
||||||
|
|
||||||
|
4. The `long' invocation options must now be prefixed by `--' instead
|
||||||
|
of `-'. (The old form is still accepted, for the time being.)
|
||||||
|
|
||||||
|
5. There was a bug in the version of readline distributed with bash-1.14
|
||||||
|
that caused it to write badly-formatted key bindings when using
|
||||||
|
`bind -d'. The only key sequences that were affected are C-\ (which
|
||||||
|
should appear as \C-\\ in a key binding) and C-" (which should appear
|
||||||
|
as \C-\"). If these key sequences appear in your inputrc, as, for
|
||||||
|
example,
|
||||||
|
|
||||||
|
"\C-\": self-insert
|
||||||
|
|
||||||
|
they will need to be changed to something like the following:
|
||||||
|
|
||||||
|
"\C-\\": self-insert
|
||||||
|
|
||||||
|
6. A number of people complained above having to use ESC to terminate an
|
||||||
|
incremental search, and asked for an alternate mechanism. Bash-2.0
|
||||||
|
allows ^J to terminate the search without accepting the line. Use
|
||||||
|
^M to terminate the search and accept the line, as in bash-1.14.
|
||||||
|
|
||||||
|
7. Some variables have been removed: MAIL_WARNING, notify, history_control,
|
||||||
|
command_oriented_history, glob_dot_filenames, allow_null_glob_expansion,
|
||||||
|
nolinks, hostname_completion_file, noclobber, no_exit_on_failed_exec, and
|
||||||
|
cdable_vars. Most of them are now implemented with the new `shopt'
|
||||||
|
builtin; others were already implemented by `set'.
|
||||||
|
|
||||||
|
8. The `ulimit' builtins now sets both hard and soft limits and reports the
|
||||||
|
soft limit by default (when neither -H nor -S is specified). This is
|
||||||
|
compatible with versions of sh and ksh that implement `ulimit'.
|
||||||
330
COPYING
330
COPYING
@@ -1,9 +1,8 @@
|
|||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 1, February 1989
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
675 Mass Ave, Cambridge, MA 02139, USA
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
@@ -17,30 +16,33 @@ based primarily on Bash as opposed to other GNU software.
|
|||||||
|
|
||||||
Preamble
|
Preamble
|
||||||
|
|
||||||
The license agreements of most software companies try to keep users
|
The licenses for most software are designed to take away your
|
||||||
at the mercy of those companies. By contrast, our General Public
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
License is intended to guarantee your freedom to share and change free
|
License is intended to guarantee your freedom to share and change free
|
||||||
software--to make sure the software is free for all its users. The
|
software--to make sure the software is free for all its users. This
|
||||||
General Public License applies to the Free Software Foundation's
|
General Public License applies to most of the Free Software
|
||||||
software and to any other program whose authors commit to using it.
|
Foundation's software and to any other program whose authors commit to
|
||||||
You can use it for your programs, too.
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
When we speak of free software, we are referring to freedom, not
|
||||||
price. Specifically, the General Public License is designed to make
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
sure that you have the freedom to give away or sell copies of free
|
have the freedom to distribute copies of free software (and charge for
|
||||||
software, that you receive source code or can get it if you want it,
|
this service if you wish), that you receive source code or can get it
|
||||||
that you can change the software or use pieces of it in new free
|
if you want it, that you can change the software or use pieces of it
|
||||||
programs; and that you know you can do these things.
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
To protect your rights, we need to make restrictions that forbid
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
These restrictions translate to certain responsibilities for you if you
|
These restrictions translate to certain responsibilities for you if you
|
||||||
distribute copies of the software, or if you modify it.
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
For example, if you distribute copies of a such a program, whether
|
For example, if you distribute copies of such a program, whether
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
you have. You must make sure that they, too, receive or can get the
|
you have. You must make sure that they, too, receive or can get the
|
||||||
source code. And you must tell them their rights.
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
@@ -53,120 +55,207 @@ want its recipients to know that what they have is not the original, so
|
|||||||
that any problems introduced by others will not reflect on the original
|
that any problems introduced by others will not reflect on the original
|
||||||
authors' reputations.
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
The precise terms and conditions for copying, distribution and
|
||||||
modification follow.
|
modification follow.
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
0. This License Agreement applies to any program or other work which
|
0. This License applies to any program or other work which contains
|
||||||
contains a notice placed by the copyright holder saying it may be
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
distributed under the terms of this General Public License. The
|
under the terms of this General Public License. The "Program", below,
|
||||||
"Program", below, refers to any such program or work, and a "work based
|
refers to any such program or work, and a "work based on the Program"
|
||||||
on the Program" means either the Program or any work containing the
|
means either the Program or any derivative work under copyright law:
|
||||||
Program or a portion of it, either verbatim or with modifications. Each
|
that is to say, a work containing the Program or a portion of it,
|
||||||
licensee is addressed as "you".
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's source
|
Activities other than copying, distribution and modification are not
|
||||||
code as you receive it, in any medium, provided that you conspicuously and
|
covered by this License; they are outside its scope. The act of
|
||||||
appropriately publish on each copy an appropriate copyright notice and
|
running the Program is not restricted, and the output from the Program
|
||||||
disclaimer of warranty; keep intact all the notices that refer to this
|
is covered only if its contents constitute a work based on the
|
||||||
General Public License and to the absence of any warranty; and give any
|
Program (independent of having been made by running the Program).
|
||||||
other recipients of the Program a copy of this General Public License
|
Whether that is true depends on what the Program does.
|
||||||
along with the Program. You may charge a fee for the physical act of
|
|
||||||
transferring a copy.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion of
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
it, and copy and distribute such modifications under the terms of Paragraph
|
source code as you receive it, in any medium, provided that you
|
||||||
1 above, provided that you also do the following:
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
a) cause the modified files to carry prominent notices stating that
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
you changed the files and the date of any change; and
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
b) cause the whole of any work that you distribute or publish, that
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
in whole or in part contains the Program or any part thereof, either
|
of it, thus forming a work based on the Program, and copy and
|
||||||
with or without modifications, to be licensed at no charge to all
|
distribute such modifications or work under the terms of Section 1
|
||||||
third parties under the terms of this General Public License (except
|
above, provided that you also meet all of these conditions:
|
||||||
that you may choose to grant warranty protection to some or all
|
|
||||||
third parties, at your option).
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively when
|
a) You must cause the modified files to carry prominent notices
|
||||||
run, you must cause it, when started running for such interactive use
|
stating that you changed the files and the date of any change.
|
||||||
in the simplest and most usual way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a notice
|
|
||||||
that there is no warranty (or else, saying that you provide a
|
|
||||||
warranty) and that users may redistribute the program under these
|
|
||||||
conditions, and telling the user how to view a copy of this General
|
|
||||||
Public License.
|
|
||||||
|
|
||||||
d) You may charge a fee for the physical act of transferring a
|
b) You must cause any work that you distribute or publish, that in
|
||||||
copy, and you may at your option offer warranty protection in
|
whole or in part contains or is derived from the Program or any
|
||||||
exchange for a fee.
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
Mere aggregation of another independent work with the Program (or its
|
c) If the modified program normally reads commands interactively
|
||||||
derivative) on a volume of a storage or distribution medium does not bring
|
when run, you must cause it, when started running for such
|
||||||
the other work under the scope of these terms.
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a portion or derivative of
|
These requirements apply to the modified work as a whole. If
|
||||||
it, under Paragraph 2) in object code or executable form under the terms of
|
identifiable sections of that work are not derived from the Program,
|
||||||
Paragraphs 1 and 2 above provided that you also do one of the following:
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
a) accompany it with the complete corresponding machine-readable
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
source code, which must be distributed under the terms of
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
Paragraphs 1 and 2 above; or,
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
b) accompany it with a written offer, valid for at least three
|
In addition, mere aggregation of another work not based on the Program
|
||||||
years, to give any third party free (except for a nominal charge
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
for the cost of distribution) a complete machine-readable copy of the
|
a storage or distribution medium does not bring the other work under
|
||||||
corresponding source code, to be distributed under the terms of
|
the scope of this License.
|
||||||
Paragraphs 1 and 2 above; or,
|
|
||||||
|
|
||||||
c) accompany it with the information you received as to where the
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
corresponding source code may be obtained. (This alternative is
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
allowed only for noncommercial distribution and only if you
|
allowed only for noncommercial distribution and only if you
|
||||||
received the program in object code or executable form alone.)
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
Source code for a work means the preferred form of the work for making
|
The source code for a work means the preferred form of the work for
|
||||||
modifications to it. For an executable file, complete source code means
|
making modifications to it. For an executable work, complete source
|
||||||
all the source code for all modules it contains; but, as a special
|
code means all the source code for all modules it contains, plus any
|
||||||
exception, it need not include source code for modules which are standard
|
associated interface definition files, plus the scripts used to
|
||||||
libraries that accompany the operating system on which the executable
|
control compilation and installation of the executable. However, as a
|
||||||
file runs, or for standard header files or definitions files that
|
special exception, the source code distributed need not include
|
||||||
accompany that operating system.
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, distribute or transfer the
|
If distribution of executable or object code is made by offering
|
||||||
Program except as expressly provided under this General Public License.
|
access to copy from a designated place, then offering equivalent
|
||||||
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
|
access to copy the source code from the same place counts as
|
||||||
the Program is void, and will automatically terminate your rights to use
|
distribution of the source code, even though third parties are not
|
||||||
the Program under this License. However, parties who have received
|
compelled to copy the source along with the object code.
|
||||||
copies, or rights to use copies, from you under this General Public
|
|
||||||
License will not have their licenses terminated so long as such parties
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
remain in full compliance.
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
5. By copying, distributing or modifying the Program (or any work based
|
5. You are not required to accept this License, since you have not
|
||||||
on the Program) you indicate your acceptance of this license to do so,
|
signed it. However, nothing else grants you permission to modify or
|
||||||
and all its terms and conditions.
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
Program), the recipient automatically receives a license from the original
|
Program), the recipient automatically receives a license from the
|
||||||
licensor to copy, distribute or modify the Program subject to these
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
terms and conditions. You may not impose any further restrictions on the
|
these terms and conditions. You may not impose any further
|
||||||
recipients' exercise of the rights granted herein.
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
7. The Free Software Foundation may publish revised and/or new versions
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
of the General Public License from time to time. Such new versions will
|
of the General Public License from time to time. Such new versions will
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
address new problems or concerns.
|
address new problems or concerns.
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
Each version is given a distinguishing version number. If the Program
|
||||||
specifies a version number of the license which applies to it and "any
|
specifies a version number of this License which applies to it and "any
|
||||||
later version", you have the option of following the terms and conditions
|
later version", you have the option of following the terms and conditions
|
||||||
either of that version or of any later version published by the Free
|
either of that version or of any later version published by the Free
|
||||||
Software Foundation. If the Program does not specify a version number of
|
Software Foundation. If the Program does not specify a version number of
|
||||||
the license, you may choose any version ever published by the Free Software
|
this License, you may choose any version ever published by the Free Software
|
||||||
Foundation.
|
Foundation.
|
||||||
|
|
||||||
8. If you wish to incorporate parts of the Program into other free
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
programs whose distribution conditions are different, write to the author
|
programs whose distribution conditions are different, write to the author
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
@@ -176,7 +265,7 @@ of promoting the sharing and reuse of software generally.
|
|||||||
|
|
||||||
NO WARRANTY
|
NO WARRANTY
|
||||||
|
|
||||||
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
@@ -186,7 +275,7 @@ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
REPAIR OR CORRECTION.
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
@@ -201,22 +290,21 @@ POSSIBILITY OF SUCH DAMAGES.
|
|||||||
Appendix: How to Apply These Terms to Your New Programs
|
Appendix: How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
If you develop a new program, and you want it to be of the greatest
|
||||||
possible use to humanity, the best way to achieve this is to make it
|
possible use to the public, the best way to achieve this is to make it
|
||||||
free software which everyone can redistribute and change under these
|
free software which everyone can redistribute and change under these terms.
|
||||||
terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest to
|
To do so, attach the following notices to the program. It is safest
|
||||||
attach them to the start of each source file to most effectively convey
|
to attach them to the start of each source file to most effectively
|
||||||
the exclusion of warranty; and each file should have at least the
|
convey the exclusion of warranty; and each file should have at least
|
||||||
"copyright" line and a pointer to where the full notice is found.
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
Copyright (C) 19yy <name of author>
|
Copyright (C) 19yy <name of author>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 1, or (at your option)
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
@@ -225,33 +313,35 @@ the exclusion of warranty; and each file should have at least the
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
If the program is interactive, make it output a short notice like this
|
||||||
when it starts in an interactive mode:
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) 19xx name of author
|
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it
|
This is free software, and you are welcome to redistribute it
|
||||||
under certain conditions; type `show c' for details.
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
appropriate parts of the General Public License. Of course, the
|
parts of the General Public License. Of course, the commands you use may
|
||||||
commands you use may be called something other than `show w' and `show
|
be called something other than `show w' and `show c'; they could even be
|
||||||
c'; they could even be mouse-clicks or menu items--whatever suits your
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
program.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
You should also get your employer (if you work as a programmer) or your
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
necessary. Here a sample; alter the names:
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
program `Gnomovision' (a program to direct compilers to make passes
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
at assemblers) written by James Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1989
|
<signature of Ty Coon>, 1 April 1989
|
||||||
Ty Coon, President of Vice
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
That's all there is to it!
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|||||||
@@ -1,18 +1,28 @@
|
|||||||
The version of bash in this directory has been compiled on the
|
The version of bash in this directory has been compiled on the
|
||||||
following systems:
|
following systems:
|
||||||
|
|
||||||
Sun 690 SunOS 4.1.2
|
By chet:
|
||||||
Sparcstation SunOS 5.3
|
|
||||||
Sparcstation NetBSD 0.9a
|
SunOS 4.1.4
|
||||||
386 BSDI BSD/386 1.0, 1.1
|
SunOS 5.5
|
||||||
NeXTstation NeXT OS 2.1
|
BSDI BSD/OS 2.1
|
||||||
IBM RT IBM/4.3 (AOS)
|
Motorola SVR3.2
|
||||||
Motorola Delta 88K SVR3.2
|
FreeBSD 2.1.5
|
||||||
Decstation 3100 Ultrix 4.3
|
AIX 4.2
|
||||||
Dec 4000 Alpha AXP DEC OSF/1 V1.3
|
HP/UX 9.05, 10.01, 10.10, 10.20
|
||||||
386 ISC UNIX 3.0.1
|
|
||||||
386 FreeBSD 1.1
|
By other testers:
|
||||||
IBM RS/6000 AIX 3.2
|
|
||||||
Amiga Amiga UNIX 2.1
|
SCO ODT 2.0
|
||||||
Sony NEWS 841 NEWS OS
|
SCO 3.2v5.0, 3.2v4.2
|
||||||
HP 9000/834 HP/UX 7.0
|
SunOS 5.3
|
||||||
|
SunOS 5.5
|
||||||
|
BSD/OS 2.1
|
||||||
|
FreeBSD 2.2
|
||||||
|
SunOS 4.1.3
|
||||||
|
Irix 5.3
|
||||||
|
Irix 6.2
|
||||||
|
Linux 2.0 (unknown distribution)
|
||||||
|
Digital OSF/1 3.2
|
||||||
|
GNU Hurd 0.1
|
||||||
|
SVR4.2
|
||||||
|
|||||||
105
CWRU/POSIX.NOTES
105
CWRU/POSIX.NOTES
@@ -1,63 +1,86 @@
|
|||||||
Starting bash with the `-posix' command-line option or setting the variable
|
Bash POSIX Mode
|
||||||
POSIXLY_CORRECT while bash is running will cause bash to conform more
|
===============
|
||||||
closely to the Posix.2 standard by changing the behavior to match that
|
|
||||||
specified by Posix.2 in areas where the bash default differs.
|
|
||||||
|
|
||||||
The following list is what's changed when `posixly_correct' is enabled:
|
Starting Bash with the `--posix' command-line option or executing `set
|
||||||
|
-o posix' while Bash is running will cause Bash to conform more closely
|
||||||
|
to the POSIX.2 standard by changing the behavior to match that
|
||||||
|
specified by POSIX.2 in areas where the Bash default differs.
|
||||||
|
|
||||||
1. When a command in the hash table no longer exists, bash will re-search
|
The following list is what's changed when `POSIX mode' is in effect:
|
||||||
$PATH to find the new location.
|
|
||||||
|
|
||||||
2. The >& redirection does not redirect stdout and stderr.
|
1. When a command in the hash table no longer exists, Bash will
|
||||||
|
re-search `$PATH' to find the new location. This is also
|
||||||
|
available with `shopt -s checkhash'.
|
||||||
|
|
||||||
3. The message printed by the job control code and builtins when a job
|
2. The `>&' redirection does not redirect stdout and stderr.
|
||||||
|
|
||||||
|
3. The message printed by the job control code and builtins when a job
|
||||||
exits with a non-zero status is `Done(status)'.
|
exits with a non-zero status is `Done(status)'.
|
||||||
|
|
||||||
4. The <> redirection does not open a file for both stdin and stdout, but
|
4. Reserved words may not be aliased.
|
||||||
rather opens it for read-write on fd 0.
|
|
||||||
|
|
||||||
5. Reserved words may not be aliased.
|
5. The POSIX.2 `PS1' and `PS2' expansions of `!' to the history
|
||||||
|
number and `!!' to `!' are enabled, and parameter expansion is
|
||||||
|
performed on the value regardless of the setting of the
|
||||||
|
`promptvars' option.
|
||||||
|
|
||||||
6. The Posix.2 PS1 and PS2 expansions of `!' -> history number and `!!' -> `!'
|
6. Interactive comments are enabled by default. (Note that Bash has
|
||||||
are enabled.
|
|
||||||
|
|
||||||
7. Interactive comments are enabled by default. (Note that this version has
|
|
||||||
them on by default anyway.)
|
them on by default anyway.)
|
||||||
|
|
||||||
8. The Posix.2 startup files are executed ($ENV) rather than the normal bash
|
7. The POSIX.2 startup files are executed (`$ENV') rather than the
|
||||||
files.
|
normal Bash files.
|
||||||
|
|
||||||
9. Tilde expansion is only performed on assignments preceding a command name,
|
8. Tilde expansion is only performed on assignments preceding a
|
||||||
rather than on all assignment statements on the line.
|
command name, rather than on all assignment statements on the line.
|
||||||
|
|
||||||
10. The default history file is ~/.sh_history (default value of $HISTFILE).
|
9. The default history file is `~/.sh_history' (this is the default
|
||||||
|
value of `$HISTFILE').
|
||||||
|
|
||||||
11. The output of `kill -l' prints all the signal names on a single line,
|
10. The output of `kill -l' prints all the signal names on a single
|
||||||
separated by spaces.
|
line, separated by spaces.
|
||||||
|
|
||||||
12. Non-interactive shells exit if `file' in `. file' is not found.
|
11. Non-interactive shells exit if FILENAME in `.' FILENAME is not
|
||||||
|
found.
|
||||||
|
|
||||||
13. Redirection operators do not perform pathname expansion on the word
|
12. Redirection operators do not perform filename expansion on the word
|
||||||
in the redirection unless the shell is interactive
|
in the redirection unless the shell is interactive.
|
||||||
|
|
||||||
14. Function names must be valid shell identifiers. That is, they may not
|
13. Function names must be valid shell `name's. That is, they may not
|
||||||
contain characters other than letters, digits, and underscores, and
|
contain characters other than letters, digits, and underscores, and
|
||||||
may not start with a digit
|
may not start with a digit. Declaring a function with an illegal
|
||||||
|
name causes a fatal syntax error in non-interactive shells.
|
||||||
|
|
||||||
There is other Posix.2 behavior that bash does not implement. Specifically:
|
14. POSIX.2 `special' builtins are found before shell functions during
|
||||||
|
command lookup.
|
||||||
|
|
||||||
1. There are no `special builtins' and `regular builtins'. All builtins
|
15. If a POSIX.2 special builtin returns an error status, a
|
||||||
are equivalent. This means that:
|
non-interactive shell exits. The fatal errors are those listed in
|
||||||
|
the POSIX.2 standard, and include things like passing incorrect
|
||||||
|
options, redirection errors, variable assignment errors for
|
||||||
|
assignments preceding the command name, and so on.
|
||||||
|
|
||||||
o assignment statements affect the execution environment of all
|
16. If the `cd' builtin finds a directory to change to using
|
||||||
builtins, not just special ones
|
`$CDPATH', the value it assigns to the `PWD' variable does not
|
||||||
o temporary assignments do not persist after Posix.2 special
|
contain any symbolic links, as if `cd -P' had been executed.
|
||||||
builtins complete
|
|
||||||
o Functions are found before Posix.2 special builtins
|
|
||||||
o The shell does not exit upon errors while executing Posix.2
|
|
||||||
special builtins
|
|
||||||
|
|
||||||
2. $LINENO does not represent the line number of a command within a function
|
17. A non-interactive shell exits with an error status if a variable
|
||||||
|
assignment error occurs when no command name follows the assignment
|
||||||
|
statements. A variable assignment error occurs, for example, when
|
||||||
|
trying to assign a value to a read-only variable.
|
||||||
|
|
||||||
|
18. A non-interactive shell exits with an error status if the iteration
|
||||||
|
variable in a `for' statement or the selection variable in a
|
||||||
|
`select' statement is a read-only variable.
|
||||||
|
|
||||||
|
19. Process substitution is not available.
|
||||||
|
|
||||||
|
20. Assignment statements preceding POSIX.2 `special' builtins persist
|
||||||
|
in the shell environment after the builtin completes.
|
||||||
|
|
||||||
|
|
||||||
|
There is other POSIX.2 behavior that Bash does not implement.
|
||||||
|
Specifically:
|
||||||
|
|
||||||
|
1. Assignment statements affect the execution environment of all
|
||||||
|
builtins, not just special ones.
|
||||||
|
|
||||||
3. The arithmetic evaluator does not implement the `e ? e1 : e2' conditional
|
|
||||||
expression
|
|
||||||
|
|||||||
27
CWRU/README
27
CWRU/README
@@ -1,26 +1,17 @@
|
|||||||
Notes:
|
|
||||||
|
|
||||||
ISC 386 machines must compile test.c without -O. The resultant shell dumps
|
|
||||||
core when test is invoked.
|
|
||||||
|
|
||||||
There have been reports that SCO 3.2v4.2 requires -DPRGP_PIPE in SCO_CFLAGS,
|
|
||||||
and that it has too many -D defines for SCO's cc (rcc works).
|
|
||||||
|
|
||||||
Contents of this directory:
|
Contents of this directory:
|
||||||
|
|
||||||
CWRU.chlog - my change log since the last release
|
changelog - my change log since the last release
|
||||||
|
|
||||||
KSH.README - list of similarities with ksh. Slightly out of date
|
|
||||||
|
|
||||||
PLATFORMS.113 - list of platforms I have built this release on
|
|
||||||
|
|
||||||
POSIX.NOTES - list of what changes for `posix mode'
|
POSIX.NOTES - list of what changes for `posix mode'
|
||||||
|
|
||||||
README - this file
|
README - this file
|
||||||
|
|
||||||
RSH.README - explanation of the bash `restricted shell' mode
|
|
||||||
|
|
||||||
|
|
||||||
misc - directory with some useful tools
|
misc - directory with some useful tools
|
||||||
OS-BUGS - directory with messages detailing some OS bugs and
|
|
||||||
the bash workarounds
|
The following are distributed `as-is'. They will not apply without some
|
||||||
|
modification.
|
||||||
|
|
||||||
|
sh-redir-hack - diff to parse.y to get redirections before
|
||||||
|
compound commands
|
||||||
|
|
||||||
|
mh-folder-comp - diffs that reportedly add MH folder completion
|
||||||
|
|||||||
7617
CWRU/changelog
7617
CWRU/changelog
File diff suppressed because it is too large
Load Diff
449
CWRU/mh-folder-comp
Normal file
449
CWRU/mh-folder-comp
Normal file
@@ -0,0 +1,449 @@
|
|||||||
|
From jwe@che.utexas.edu Wed Sep 21 17:23:40 1994
|
||||||
|
Flags: 10
|
||||||
|
Return-Path: jwe@che.utexas.edu
|
||||||
|
Received: from po.CWRU.Edu (root@po.CWRU.Edu [129.22.4.2]) by odin.INS.CWRU.Edu with ESMTP (8.6.8.1+cwru/CWRU-2.1-ins)
|
||||||
|
id RAA04010; Wed, 21 Sep 1994 17:23:39 -0400 (from jwe@che.utexas.edu for <chet@odin.INS.CWRU.Edu>)
|
||||||
|
Received: from life.ai.mit.edu (life.ai.mit.edu [128.52.32.80]) by po.CWRU.Edu with SMTP (8.6.8.1+cwru/CWRU-2.2)
|
||||||
|
id RAA02121; Wed, 21 Sep 1994 17:23:28 -0400 (from jwe@che.utexas.edu for <chet@po.cwru.edu>)
|
||||||
|
Received: from schoch.che.utexas.edu by life.ai.mit.edu (4.1/AI-4.10) for chet@po.cwru.edu id AA09989; Wed, 21 Sep 94 17:23:17 EDT
|
||||||
|
Received: from localhost (jwe@localhost) by schoch.che.utexas.edu (8.6.8.1/8.6) with SMTP id QAA05737; Wed, 21 Sep 1994 16:22:01 -0500
|
||||||
|
Message-Id: <199409212122.QAA05737@schoch.che.utexas.edu>
|
||||||
|
To: march@tudor.com
|
||||||
|
Cc: bug-bash@prep.ai.mit.edu
|
||||||
|
Subject: Re: Completion feature possible?
|
||||||
|
In-Reply-To: Your message of 21 Sep 94 13:30:22 EDT
|
||||||
|
Date: Wed, 21 Sep 94 16:22:00 EDT
|
||||||
|
From: John Eaton <jwe@che.utexas.edu>
|
||||||
|
|
||||||
|
Gregory F. March <march@tudor.com> wrote:
|
||||||
|
|
||||||
|
: I was having a discussion about MH with one of my friends the other
|
||||||
|
: day and I got to thinking that the +folder/subfolder scheme for naming
|
||||||
|
: mail folders is a real pain because completion doesn't work on
|
||||||
|
: them. Someone then mentioned that zsh (I think) has the ability to
|
||||||
|
: specify how to complete (I guess where to look for the files) for
|
||||||
|
: different prefixes. Bash right now knows about '@', '~', and '$' (any
|
||||||
|
: others?). It would be really helpful if one could define something
|
||||||
|
: like:
|
||||||
|
:
|
||||||
|
: completion '+' "$HOME/Mail"
|
||||||
|
:
|
||||||
|
: in a config file someplace. Would this be easy? Is there a list of
|
||||||
|
: TODO item that someone might want to add this to?
|
||||||
|
|
||||||
|
It would be nice to have a general completion feature like this.
|
||||||
|
|
||||||
|
Until that happens, maybe you will find the following patch useful.
|
||||||
|
It makes MH folder name completion work with bash. The diffs are
|
||||||
|
relative to version 1.14.2.
|
||||||
|
|
||||||
|
I realize that changes to readline.c and and complete.c are not good
|
||||||
|
since they add some MH-specific stuff to the readline code and not to
|
||||||
|
bash, but when I first wrote this, I had no idea what else to do.
|
||||||
|
|
||||||
|
Chet, would you consider adding this if it were cleaned up a bit?
|
||||||
|
Made optional with cpp conditionals?
|
||||||
|
|
||||||
|
This feature has been very useful to me for the last several years
|
||||||
|
(since about 1.05 or 1.06, I think).
|
||||||
|
|
||||||
|
Thanks,
|
||||||
|
|
||||||
|
--
|
||||||
|
John W. Eaton | 4.3BSD is not perfect. -- Leffler, et al. (1989).
|
||||||
|
jwe@che.utexas.edu |
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------cut here-------------------------------
|
||||||
|
diff -rc bash-1.14.2/bashline.c bash-1.14.2.local/bashline.c
|
||||||
|
*** bash-1.14.2/bashline.c Wed Aug 3 09:32:45 1994
|
||||||
|
--- bash-1.14.2.local/bashline.c Wed Sep 21 15:39:04 1994
|
||||||
|
***************
|
||||||
|
*** 58,63 ****
|
||||||
|
--- 58,64 ----
|
||||||
|
static char *hostname_completion_function ();
|
||||||
|
static char *command_word_completion_function ();
|
||||||
|
static char *command_subst_completion_function ();
|
||||||
|
+ static char *mh_folder_completion_function ();
|
||||||
|
|
||||||
|
static void snarf_hosts_from_file (), add_host_name ();
|
||||||
|
static void sort_hostname_list ();
|
||||||
|
***************
|
||||||
|
*** 90,95 ****
|
||||||
|
--- 91,98 ----
|
||||||
|
bash_complete_username_internal (),
|
||||||
|
bash_complete_hostname (), bash_possible_hostname_completions (),
|
||||||
|
bash_complete_hostname_internal (),
|
||||||
|
+ bash_complete_mh_folder (), bash_possible_mh_folder_completions (),
|
||||||
|
+ bash_complete_mh_folder_internal (),
|
||||||
|
bash_complete_variable (), bash_possible_variable_completions (),
|
||||||
|
bash_complete_variable_internal (),
|
||||||
|
bash_complete_command (), bash_possible_command_completions (),
|
||||||
|
***************
|
||||||
|
*** 134,140 ****
|
||||||
|
rl_terminal_name = get_string_value ("TERM");
|
||||||
|
rl_instream = stdin;
|
||||||
|
rl_outstream = stderr;
|
||||||
|
! rl_special_prefixes = "$@";
|
||||||
|
|
||||||
|
/* Allow conditional parsing of the ~/.inputrc file. */
|
||||||
|
rl_readline_name = "Bash";
|
||||||
|
--- 137,143 ----
|
||||||
|
rl_terminal_name = get_string_value ("TERM");
|
||||||
|
rl_instream = stdin;
|
||||||
|
rl_outstream = stderr;
|
||||||
|
! rl_special_prefixes = "$@+";
|
||||||
|
|
||||||
|
/* Allow conditional parsing of the ~/.inputrc file. */
|
||||||
|
rl_readline_name = "Bash";
|
||||||
|
***************
|
||||||
|
*** 193,198 ****
|
||||||
|
--- 196,207 ----
|
||||||
|
rl_bind_key_in_map ('@', bash_possible_hostname_completions,
|
||||||
|
emacs_ctlx_keymap);
|
||||||
|
|
||||||
|
+ rl_add_defun ("complete-mh-folder", bash_complete_mh_folder, META('+'));
|
||||||
|
+ rl_add_defun ("possible-mh-folder-completions",
|
||||||
|
+ bash_possible_mh_folder_completions, -1);
|
||||||
|
+ rl_bind_key_in_map ('+', bash_possible_mh_folder_completions,
|
||||||
|
+ emacs_ctlx_keymap);
|
||||||
|
+
|
||||||
|
rl_add_defun ("complete-variable", bash_complete_variable, -1);
|
||||||
|
rl_bind_key_in_map ('$', bash_complete_variable, emacs_meta_keymap);
|
||||||
|
rl_add_defun ("possible-variable-completions",
|
||||||
|
***************
|
||||||
|
*** 656,661 ****
|
||||||
|
--- 665,677 ----
|
||||||
|
if (!matches && *text == '@')
|
||||||
|
matches = completion_matches (text, hostname_completion_function);
|
||||||
|
|
||||||
|
+ /* Another one. Why not? If the word starts in '+', then look for
|
||||||
|
+ matching mh folders for completion first. */
|
||||||
|
+ if (!matches && *text == '+')
|
||||||
|
+ {
|
||||||
|
+ matches = completion_matches (text, mh_folder_completion_function);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* 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. */
|
||||||
|
***************
|
||||||
|
*** 1077,1082 ****
|
||||||
|
--- 1093,1185 ----
|
||||||
|
return ((char *)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* How about a completion function for mh folders? */
|
||||||
|
+ static char *
|
||||||
|
+ mh_folder_completion_function (text, state)
|
||||||
|
+ int state;
|
||||||
|
+ char *text;
|
||||||
|
+ {
|
||||||
|
+ extern int rl_filename_completion_desired;
|
||||||
|
+
|
||||||
|
+ extern char *get_mh_path ();
|
||||||
|
+
|
||||||
|
+ static char *mh_path = (char *)NULL;
|
||||||
|
+ static int len;
|
||||||
|
+ static int istate;
|
||||||
|
+ static char *val;
|
||||||
|
+ char *hint;
|
||||||
|
+
|
||||||
|
+ static char *mh_folder_hint = (char *)NULL;
|
||||||
|
+
|
||||||
|
+ /* If we don't have any state, make some. */
|
||||||
|
+ if (!state)
|
||||||
|
+ {
|
||||||
|
+ val = (char *)NULL;
|
||||||
|
+
|
||||||
|
+ if (mh_path)
|
||||||
|
+ free (mh_path);
|
||||||
|
+
|
||||||
|
+ mh_path = get_mh_path ();
|
||||||
|
+ if (!mh_path && !(hint[1] == '/' || hint[1] == '.'))
|
||||||
|
+ return ((char *)NULL);
|
||||||
|
+
|
||||||
|
+ len = strlen (mh_path);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (mh_folder_hint)
|
||||||
|
+ free (mh_folder_hint);
|
||||||
|
+
|
||||||
|
+ hint = text;
|
||||||
|
+ if (*hint == '+')
|
||||||
|
+ hint++;
|
||||||
|
+
|
||||||
|
+ mh_folder_hint = (char *)xmalloc (2 + len + strlen (hint));
|
||||||
|
+ if (*hint == '/' || *hint == '.') {
|
||||||
|
+ len = -1;
|
||||||
|
+ sprintf (mh_folder_hint, "%s", hint);
|
||||||
|
+ } else
|
||||||
|
+ sprintf (mh_folder_hint, "%s/%s", mh_path, hint);
|
||||||
|
+
|
||||||
|
+ istate = (val != (char *)NULL);
|
||||||
|
+
|
||||||
|
+ again:
|
||||||
|
+ val = filename_completion_function (mh_folder_hint, istate);
|
||||||
|
+ istate = 1;
|
||||||
|
+
|
||||||
|
+ if (!val)
|
||||||
|
+ {
|
||||||
|
+ return ((char *)NULL);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ char *ptr = val + len + 1, *temp;
|
||||||
|
+ struct stat sb;
|
||||||
|
+ int status = stat (val, &sb);
|
||||||
|
+
|
||||||
|
+ if (status != 0)
|
||||||
|
+ return ((char *)NULL);
|
||||||
|
+
|
||||||
|
+ if ((sb.st_mode & S_IFDIR) == S_IFDIR)
|
||||||
|
+ {
|
||||||
|
+ temp = (char *)xmalloc (2 + strlen (ptr));
|
||||||
|
+ *temp = '+';
|
||||||
|
+ strcpy (temp + 1, ptr);
|
||||||
|
+
|
||||||
|
+ free (val);
|
||||||
|
+ val = "";
|
||||||
|
+
|
||||||
|
+ rl_filename_completion_desired = 1;
|
||||||
|
+
|
||||||
|
+ return (temp);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ free (val);
|
||||||
|
+ }
|
||||||
|
+ goto again;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* History and alias expand the line. */
|
||||||
|
static char *
|
||||||
|
history_expand_line_internal (line)
|
||||||
|
***************
|
||||||
|
*** 1628,1633 ****
|
||||||
|
--- 1731,1773 ----
|
||||||
|
{
|
||||||
|
bash_specific_completion
|
||||||
|
(what_to_do, (Function *)username_completion_function);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static void
|
||||||
|
+ bash_complete_mh_folder (ignore, ignore2)
|
||||||
|
+ int ignore, ignore2;
|
||||||
|
+ {
|
||||||
|
+ bash_complete_mh_folder_internal (TAB);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static void
|
||||||
|
+ bash_possible_mh_folder_completions (ignore, ignore2)
|
||||||
|
+ int ignore, ignore2;
|
||||||
|
+ {
|
||||||
|
+ bash_complete_mh_folder_internal ('?');
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static void
|
||||||
|
+ bash_complete_mh_folder_internal (what_to_do)
|
||||||
|
+ int what_to_do;
|
||||||
|
+ {
|
||||||
|
+ Function *orig_func;
|
||||||
|
+ CPPFunction *orig_attempt_func;
|
||||||
|
+ char *orig_rl_completer_word_break_characters;
|
||||||
|
+ extern char *rl_completer_word_break_characters;
|
||||||
|
+
|
||||||
|
+ orig_func = rl_completion_entry_function;
|
||||||
|
+ orig_attempt_func = rl_attempted_completion_function;
|
||||||
|
+ orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
|
||||||
|
+ rl_completion_entry_function = (Function *)mh_folder_completion_function;
|
||||||
|
+ rl_attempted_completion_function = (CPPFunction *)NULL;
|
||||||
|
+ rl_completer_word_break_characters = " \t\n\"\'";
|
||||||
|
+
|
||||||
|
+ rl_complete_internal (what_to_do);
|
||||||
|
+
|
||||||
|
+ rl_completion_entry_function = orig_func;
|
||||||
|
+ rl_attempted_completion_function = orig_attempt_func;
|
||||||
|
+ rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
Only in bash-1.14.2.local: bashline.c.orig
|
||||||
|
diff -rc bash-1.14.2/lib/readline/complete.c bash-1.14.2.local/lib/readline/complete.c
|
||||||
|
*** bash-1.14.2/lib/readline/complete.c Tue Jul 26 12:59:57 1994
|
||||||
|
--- bash-1.14.2.local/lib/readline/complete.c Wed Sep 21 15:41:19 1994
|
||||||
|
***************
|
||||||
|
*** 733,751 ****
|
||||||
|
if (rl_filename_completion_desired)
|
||||||
|
{
|
||||||
|
struct stat finfo;
|
||||||
|
! char *filename = tilde_expand (matches[0]);
|
||||||
|
|
||||||
|
! if ((stat (filename, &finfo) == 0) && S_ISDIR (finfo.st_mode))
|
||||||
|
{
|
||||||
|
! if (rl_line_buffer[rl_point] != '/')
|
||||||
|
! rl_insert_text ("/");
|
||||||
|
}
|
||||||
|
! else
|
||||||
|
{
|
||||||
|
! if (rl_point == rl_end)
|
||||||
|
! rl_insert_text (temp_string);
|
||||||
|
}
|
||||||
|
- free (filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--- 733,768 ----
|
||||||
|
if (rl_filename_completion_desired)
|
||||||
|
{
|
||||||
|
struct stat finfo;
|
||||||
|
! char *tilde_expand ();
|
||||||
|
! char *plus_expand ();
|
||||||
|
! char *filename = (char *) NULL;
|
||||||
|
|
||||||
|
! switch (*matches[0])
|
||||||
|
{
|
||||||
|
! case '+':
|
||||||
|
! filename = plus_expand (matches[0]);
|
||||||
|
! break;
|
||||||
|
! case '~':
|
||||||
|
! default:
|
||||||
|
! filename = tilde_expand (matches[0]);
|
||||||
|
! break;
|
||||||
|
}
|
||||||
|
!
|
||||||
|
! if (filename)
|
||||||
|
{
|
||||||
|
! if ((stat (filename, &finfo) == 0)
|
||||||
|
! && S_ISDIR (finfo.st_mode))
|
||||||
|
! {
|
||||||
|
! if (rl_line_buffer[rl_point] != '/')
|
||||||
|
! rl_insert_text ("/");
|
||||||
|
! }
|
||||||
|
! else
|
||||||
|
! {
|
||||||
|
! if (rl_point == rl_end)
|
||||||
|
! rl_insert_text (temp_string);
|
||||||
|
! }
|
||||||
|
! free (filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Only in bash-1.14.2.local/lib/readline: diffs
|
||||||
|
diff -rc bash-1.14.2/lib/readline/readline.c bash-1.14.2.local/lib/readline/readline.c
|
||||||
|
*** bash-1.14.2/lib/readline/readline.c Fri Aug 12 12:47:46 1994
|
||||||
|
--- bash-1.14.2.local/lib/readline/readline.c Wed Sep 21 15:36:07 1994
|
||||||
|
***************
|
||||||
|
*** 23,28 ****
|
||||||
|
--- 23,29 ----
|
||||||
|
#define READLINE_LIBRARY
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
+ #include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#if !defined (NO_SYS_FILE)
|
||||||
|
***************
|
||||||
|
*** 3518,3523 ****
|
||||||
|
--- 3519,3616 ----
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TEST */
|
||||||
|
+
|
||||||
|
+ #define cr_whitespace(c) ((c) == '\r' || (c) == '\n' || whitespace(c))
|
||||||
|
+
|
||||||
|
+ char *
|
||||||
|
+ get_mh_path ()
|
||||||
|
+ {
|
||||||
|
+ static FILE *fp = (FILE *)NULL;
|
||||||
|
+ char buf[512]; /* XXX */
|
||||||
|
+ char profile[512]; /* XXX */
|
||||||
|
+ char *bp;
|
||||||
|
+ char *temp_home;
|
||||||
|
+ char *temp_path;
|
||||||
|
+
|
||||||
|
+ temp_home = (char *)getenv ("HOME");
|
||||||
|
+ if (!temp_home)
|
||||||
|
+ return ((char *)NULL);
|
||||||
|
+
|
||||||
|
+ strcpy (profile, temp_home);
|
||||||
|
+ strcat (profile, "/.mh_profile");
|
||||||
|
+
|
||||||
|
+ if (fp)
|
||||||
|
+ fclose (fp);
|
||||||
|
+
|
||||||
|
+ fp = fopen (profile, "r");
|
||||||
|
+ if (fp == (FILE *)NULL)
|
||||||
|
+ return ((char *)NULL);
|
||||||
|
+
|
||||||
|
+ while (fgets (buf, 512, fp) != (char *)NULL) /* XXX */
|
||||||
|
+ {
|
||||||
|
+ if ((bp = strstr (buf, "Path:")) != (char *)NULL)
|
||||||
|
+ {
|
||||||
|
+ bp += 5;
|
||||||
|
+ while (whitespace (*bp))
|
||||||
|
+ bp++;
|
||||||
|
+
|
||||||
|
+ if (*bp == '\0')
|
||||||
|
+ return ((char *)NULL);
|
||||||
|
+
|
||||||
|
+ temp_path = (char *)xmalloc (3 + strlen (bp) + strlen (temp_home));
|
||||||
|
+
|
||||||
|
+ strcpy (temp_path, temp_home);
|
||||||
|
+ strcat (temp_path, "/");
|
||||||
|
+ strcat (temp_path, bp);
|
||||||
|
+
|
||||||
|
+ bp = temp_path;
|
||||||
|
+
|
||||||
|
+ while (!(cr_whitespace (*bp)))
|
||||||
|
+ bp++;
|
||||||
|
+
|
||||||
|
+ *bp = '\0';
|
||||||
|
+
|
||||||
|
+ return temp_path;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ((char *)NULL);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Expand FILENAME if it begins with a plus. This always returns
|
||||||
|
+ a new string. */
|
||||||
|
+ char *
|
||||||
|
+ plus_expand (filename)
|
||||||
|
+ char *filename;
|
||||||
|
+ {
|
||||||
|
+ static char *dirname = (char *)NULL;
|
||||||
|
+
|
||||||
|
+ if (filename && *filename == '+')
|
||||||
|
+ {
|
||||||
|
+ char *mh_path = get_mh_path ();
|
||||||
|
+
|
||||||
|
+ if (filename[1] == '/' || filename[1] == '.')
|
||||||
|
+ {
|
||||||
|
+ dirname = (char *)xmalloc (1 + strlen (filename));
|
||||||
|
+
|
||||||
|
+ strcpy(dirname, filename+1);
|
||||||
|
+
|
||||||
|
+ return dirname;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (mh_path)
|
||||||
|
+ {
|
||||||
|
+ dirname = (char *)xmalloc (1 + strlen (filename) + strlen (mh_path));
|
||||||
|
+
|
||||||
|
+ strcpy (dirname, mh_path);
|
||||||
|
+ strcat (dirname, "/");
|
||||||
|
+ strcat (dirname, filename+1);
|
||||||
|
+
|
||||||
|
+ return dirname;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return (char *)NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/* ************************ */
|
|
||||||
/* */
|
|
||||||
/* A/UX 3.0 System */
|
|
||||||
/* */
|
|
||||||
/* ************************ */
|
|
||||||
#if defined (mc68k32) && !defined (M_MACHINE)
|
|
||||||
# define M_MACHINE "Macintosh"
|
|
||||||
# define M_OS "AUX"
|
|
||||||
# define SYSDEP_CFLAGS -ZP -DUSG -DHAVE_BCOPY -DHAVE_UID_T -DNSIG=32 \
|
|
||||||
-DHAVE_GETDTABLESIZE
|
|
||||||
# define SYSDEP_LDFLAGS -ZP
|
|
||||||
# define HAVE_DIRENT
|
|
||||||
# define HAVE_POSIX_SIGNALS
|
|
||||||
# define HAVE_VFPRINTF
|
|
||||||
# define VOID_SIGHANDLER
|
|
||||||
# define HAVE_GETGROUPS
|
|
||||||
# undef HAVE_RESOURCE
|
|
||||||
# undef HAVE_ALLOCA
|
|
||||||
# define REQUIRED_LIBRARIES -lc_s
|
|
||||||
#endif /* A/UX */
|
|
||||||
374
INSTALL
374
INSTALL
@@ -1,212 +1,288 @@
|
|||||||
File: bash.info, Node: Install, Next: Invoke, Prev: Built-in, Up: Top
|
Basic Installation
|
||||||
|
==================
|
||||||
|
|
||||||
Installing BASH
|
These are generic installation instructions for Bash.
|
||||||
***************
|
|
||||||
|
|
||||||
To install BASH you simply type `make'. The BASH `Makefile' tries
|
The `configure' shell script attempts to guess correct values for
|
||||||
to dynamically figure out what kind of machine and operating system
|
various system-dependent variables used during compilation. It uses
|
||||||
you are using. It makes an educated guess based on the information
|
those values to create a `Makefile' in each directory of the package
|
||||||
it finds.
|
(the top directory, the `builtins' and `doc' directories, and the each
|
||||||
|
directory under `lib'). It also creates a `config.h' file containing
|
||||||
|
system-dependent definitions. Finally, it creates a shell script named
|
||||||
|
`config.status' that you can run in the future to recreate the current
|
||||||
|
configuration, a file `config.cache' that saves the results of its
|
||||||
|
tests to speed up reconfiguring, and a file `config.log' containing
|
||||||
|
compiler output (useful mainly for debugging `configure'). If at some
|
||||||
|
point `config.cache' contains results you don't want to keep, you may
|
||||||
|
remove or edit it.
|
||||||
|
|
||||||
During the `make' process, a message is displayed describing what
|
If you need to do unusual things to compile the package, please try to
|
||||||
machine and operating system has been chosen for you. This
|
figure out how `configure' could check whether or not to do them, and
|
||||||
information is also saved in the file `.machine' so you can look at
|
mail diffs or instructions to `bash-maintainers@prep.ai.mit.edu' so
|
||||||
it later.
|
they can be considered for the next release.
|
||||||
|
|
||||||
Therefore, for most machines, simply follow this simple checklist
|
The file `configure.in' is used to create `configure' by a program
|
||||||
to install BASH:
|
called Autoconf. You only need `configure.in' if you want to change it
|
||||||
|
or regenerate `configure' using a newer version of Autoconf. If you do
|
||||||
|
this, make sure you are using Autoconf version 2.9 or newer.
|
||||||
|
|
||||||
1. Type `make'. If you want to use GCC to compile bash, type
|
The simplest way to compile Bash is:
|
||||||
`make CC=gcc CPPNAME='$(CC) -E''.
|
|
||||||
|
|
||||||
2. Wait for the compilation to finish.
|
1. `cd' to the directory containing the source code and type
|
||||||
|
`./configure' to configure Bash for your system. If you're using
|
||||||
|
`csh' on an old version of System V, you might need to type `sh
|
||||||
|
./configure' instead to prevent `csh' from trying to execute
|
||||||
|
`configure' itself.
|
||||||
|
|
||||||
3. Type `./bash' to see if the compile worked.
|
Running `configure' takes awhile. While running, it prints some
|
||||||
|
messages telling which features it is checking for.
|
||||||
|
|
||||||
4. Type `make install prefix=/usr/gnu/' (or the appropriate root
|
2. Type `make' to compile Bash and build the `bashbug' bug reporting
|
||||||
of your local GNU software installation tree) to copy bash to
|
script.
|
||||||
your binaries directory, assumed to be ${prefix}/bin. This will
|
|
||||||
also attempt to install the manual pages under ${prefix}/man
|
|
||||||
and the info file under ${prefix}/info.
|
|
||||||
|
|
||||||
* Menu:
|
3. Optionally, type `make tests' to run the Bash test suite.
|
||||||
|
|
||||||
* Problems:: What to do if BASH doesn't install quite so easily.
|
4. Type `make install' to install `bash' and `bashbug'. This will
|
||||||
|
also install the manual pages and Info file.
|
||||||
|
|
||||||
* Files:: Files used in the `make' process.
|
You can remove the program binaries and object files from the source
|
||||||
|
code directory by typing `make clean'. To also remove the files that
|
||||||
|
`configure' created (so you can compile Bash for a different kind of
|
||||||
|
computer), type `make distclean'.
|
||||||
|
|
||||||
* Porting:: Porting BASH to a new machine.
|
Compilers and Options
|
||||||
|
=====================
|
||||||
|
|
||||||
* Bugs:: What to do if you Discover Bugs in BASH.
|
Some systems require unusual options for compilation or linking that
|
||||||
|
the `configure' script does not know about. You can give `configure'
|
||||||
|
initial values for variables by setting them in the environment. Using
|
||||||
|
a Bourne-compatible shell, you can do that on the command line like
|
||||||
|
this:
|
||||||
|
|
||||||
|
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||||
|
|
||||||
File: bash.info, Node: Problems, Next: Files, Prev: Install, Up: Install
|
On systems that have the `env' program, you can do it like this:
|
||||||
|
|
||||||
What if it Doesn't Install so Easily?
|
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||||
=====================================
|
|
||||||
|
|
||||||
Sometimes BASH gets confused and will make the wrong assumptions
|
The configuration process uses GCC to build Bash if it is available.
|
||||||
about your machine or operating system. If the displayed
|
|
||||||
information (also found in `.machine') is incorrect, you will have
|
|
||||||
to edit the file `machines.h' and provide the appropriate
|
|
||||||
information so that BASH can be installed correctly. The complete
|
|
||||||
instructions for doing this are located in the `machines.h' file.
|
|
||||||
|
|
||||||
However, if BASH says that your machine type is an
|
Compiling For Multiple Architectures
|
||||||
"UNKNOWN_MACHINE", or BASH thought it knew something about your
|
====================================
|
||||||
machine but was wrong, then reading the next few sections could
|
|
||||||
be of use to you (*note Files::., and *note Porting::., for more
|
|
||||||
information).
|
|
||||||
|
|
||||||
On the MIPSEB with the BSD universe, you must:
|
You can compile Bash for more than one kind of computer at the same
|
||||||
|
time, by placing the object files for each architecture in their own
|
||||||
|
directory. To do this, you must use a version of `make' that supports
|
||||||
|
the `VPATH' variable, such as GNU `make'. `cd' to the directory where
|
||||||
|
you want the object files and executables to go and run the `configure'
|
||||||
|
script from the source directory. You may need to supply the
|
||||||
|
`--srcdir=PATH' argument to tell `configure' where the source files
|
||||||
|
are. `configure' automatically checks for the source code in the
|
||||||
|
directory that `configure' is in and in `..'.
|
||||||
|
|
||||||
1) Place /bsd43/bin in your PATH before /bin
|
If you have to use a `make' that does not supports the `VPATH'
|
||||||
2) Use $(CC) -E instead of /lib/cpp to build cpp-Makefile.
|
variable, you can compile Bash for one architecture at a time in the
|
||||||
|
source code directory. After you have installed Bash for one
|
||||||
|
architecture, use `make distclean' before reconfiguring for another
|
||||||
|
architecture.
|
||||||
|
|
||||||
On SCO Xenix 386, you must:
|
Alternatively, if your system supports symbolic links, you can use the
|
||||||
|
`support/mkclone' script to create a build tree which has symbolic
|
||||||
|
links back to each file in the source directory. Here's an example
|
||||||
|
that creates a build directory in the current directory from a source
|
||||||
|
directory `/usr/gnu/src/bash-2.0':
|
||||||
|
|
||||||
1) Use $(CC) -E instead of /lib/cpp to build cpp-Makefile.
|
bash /usr/gnu/src/bash-2.0/support/mkclone -s /usr/gnu/src/bash-2.0 .
|
||||||
|
|
||||||
On Interactive Unix version 3 or 4, you must:
|
The `mkclone' script requires Bash, so you must have already built Bash
|
||||||
|
for at least one architecture before you can create build directories
|
||||||
|
for other architectures.
|
||||||
|
|
||||||
1) Edit cpp-Makefile to remove either -O or -g from DEBUG_FLAGS
|
Installation Names
|
||||||
|
==================
|
||||||
|
|
||||||
File: bash.info, Node: Files, Next: Porting, Prev: Problems, Up: Install
|
By default, `make install' will install into `/usr/local/bin',
|
||||||
|
`/usr/local/man', etc. You can specify an installation prefix other
|
||||||
|
than `/usr/local' by giving `configure' the option `--prefix=PATH'.
|
||||||
|
|
||||||
Files Used in the `make' Process.
|
You can specify separate installation prefixes for
|
||||||
=================================
|
architecture-specific files and architecture-independent files. If you
|
||||||
|
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||||
|
`PATH' as the prefix for installing programs and libraries.
|
||||||
|
Documentation and other data files will still use the regular prefix.
|
||||||
|
|
||||||
The following files are used during the installation of BASH, in
|
Specifying the System Type
|
||||||
the `make' process:
|
==========================
|
||||||
|
|
||||||
`Makefile'
|
There may be some features `configure' can not figure out
|
||||||
This is responsible for making the actual `Makefile' that is
|
automatically, but needs to determine by the type of host the package
|
||||||
used to create Bash. It runs the C preprocessor (usually
|
will run on. Usually `configure' can figure that out, but if it prints
|
||||||
located in `/lib/cpp') on the file `cpp-Makefile', producing
|
a message saying it can not guess the host type, give it the
|
||||||
the output file `bash-Makefile'.
|
`--host=TYPE' option. `TYPE' can either be a short name for the system
|
||||||
|
type, such as `sun4', or a canonical name with three fields:
|
||||||
|
`CPU-COMPANY-SYSTEM' (e.g., `sparc-sun-sunos4.1.2').
|
||||||
|
|
||||||
`cpp-Makefile'
|
See the file `support/config.sub' for the possible values of each field.
|
||||||
This is a file of C comments and text. It contains a
|
|
||||||
reasonable number of `ifdefs' which control what files get
|
|
||||||
compiled and which flags are passed to the various C files
|
|
||||||
comprising BASH. It includes files named `machines.h',
|
|
||||||
`sysdefs.h', and `config.h'.
|
|
||||||
|
|
||||||
`machines.h'
|
Sharing Defaults
|
||||||
This file contains the basic compilation parameters for all of
|
================
|
||||||
the machines to which BASH has been ported. This file
|
|
||||||
consists of a series of conditional blocks, one per machine
|
|
||||||
type.
|
|
||||||
|
|
||||||
These conditional blocks are depend upon the unique identifier
|
If you want to set default values for `configure' scripts to share, you
|
||||||
that `cpp' has predefined for this machine. In some cases,
|
can create a site shell script called `config.site' that gives default
|
||||||
additional information can be passed from `Makefile'. It is
|
values for variables like `CC', `cache_file', and `prefix'. `configure'
|
||||||
possible to pass information such as whether or not a
|
looks for `PREFIX/share/config.site' if it exists, then
|
||||||
particular file is available on this system, and so on.
|
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||||
|
`CONFIG_SITE' environment variable to the location of the site script.
|
||||||
|
A warning: the Bash `configure' looks for a site script, but not all
|
||||||
|
`configure' scripts do.
|
||||||
|
|
||||||
`sysdefs.h'
|
Operation Controls
|
||||||
This file is dynamically made at build time by running the shell
|
==================
|
||||||
script `support/mksydefs'. If there appears to be something wrong
|
|
||||||
in this file, then edit the `mksysdefs' script, and mail the
|
|
||||||
changes that you make to bash-maintainers@prep.ai.mit.edu.
|
|
||||||
|
|
||||||
`bash-Makefile'
|
`configure' recognizes the following options to control how it operates.
|
||||||
This is the output from the initial stage of `make'. It is a
|
|
||||||
stripped down version of `cpp-Makefile' which is tailor-made
|
|
||||||
for your machine and operating system. All subsequent `makes'
|
|
||||||
use this file.
|
|
||||||
|
|
||||||
|
`--cache-file=FILE'
|
||||||
|
Use and save the results of the tests in FILE instead of
|
||||||
|
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||||
|
debugging `configure'.
|
||||||
|
|
||||||
File: bash.info, Node: Porting, Next: Bugs, Prev: Files, Up: Install
|
`--help'
|
||||||
|
Print a summary of the options to `configure', and exit.
|
||||||
|
|
||||||
What if You Have to Port to a New Machine?
|
`--quiet'
|
||||||
==========================================
|
`--silent'
|
||||||
|
`-q'
|
||||||
|
Do not print messages saying which checks are being made.
|
||||||
|
|
||||||
Sometimes you may want to port BASH to a new, previously
|
`--srcdir=DIR'
|
||||||
unsupported machine. To do so you need to create a block in
|
Look for the Bash source code in directory DIR. Usually
|
||||||
`machines.h' which is conditional based on a unique identifier
|
`configure' can determine that directory automatically.
|
||||||
present in your version of the C preprocessor.
|
|
||||||
|
|
||||||
If you don't know what that symbol is, you might try the following
|
`--version'
|
||||||
simple test:
|
Print the version of Autoconf used to generate the `configure'
|
||||||
|
script, and exit.
|
||||||
|
|
||||||
echo "main () { }" > foo.c
|
`configure' also accepts some other, not widely used, boilerplate
|
||||||
cc -v foo.c
|
options.
|
||||||
|
|
||||||
You are looking for `-DMACHINE', where `MACHINE' is an identifier
|
Optional Features
|
||||||
for your machine. If you are very unlucky and your machine's C
|
=================
|
||||||
preprocessor doesn't have a unique identifier, you will have to
|
|
||||||
define the identifier in Makefile manually.
|
|
||||||
|
|
||||||
Let's say you have a machine from Yoyodyne Industries, called the
|
The Bash `configure' has a number of `--enable-FEATURE' options, where
|
||||||
YoYo. It runs a version of BSD, so it is reasonably compatible.
|
FEATURE indicates an optional part of the package. There are also
|
||||||
However, the `cpp' on this YoYo machine doesn't define any unique
|
several `--with-PACKAGE' options, where PACKAGE is something like
|
||||||
identifiers. You should change the `Makefile' line for `CPPFLAGS'
|
`gnu-malloc' or `purify' (for the Purify memory allocation checker). To
|
||||||
to:
|
turn off the default use of a package, use `--without-PACKAGE'. To
|
||||||
|
configure Bash without a feature that is enabled by default, use
|
||||||
|
`--disable-FEATURE'.
|
||||||
|
|
||||||
CPPFLAGS = -P -DYoYo
|
Here is a complete list of the `--enable-' and `--with-' options that
|
||||||
|
the Bash `configure' recognizes.
|
||||||
|
|
||||||
Then, in `machines.h', you copy the block for `UNKNOWN_MACHINE',
|
`--with-gnu-malloc'
|
||||||
and change the conditional to;
|
Use the GNU version of `malloc' in `lib/malloc/malloc.c'. This is
|
||||||
|
not the same `malloc' that appears in GNU libc, but an older
|
||||||
|
version derived from the 4.2 BSD `malloc'. This `malloc' is very
|
||||||
|
fast, but wastes a lot of space. This option is enabled by
|
||||||
|
default. The `NOTES' file contains a list of systems for which
|
||||||
|
this should be turned off.
|
||||||
|
|
||||||
#if defined (YoYo)
|
`--with-glibc-malloc'
|
||||||
|
Use the GNU libc version of `malloc' in `lib/malloc/gmalloc.c'.
|
||||||
|
This is somewhat slower than the default `malloc', but wastes
|
||||||
|
considerably less space.
|
||||||
|
|
||||||
Inside of the YoYo block you define `M_MACHINE="YoYo"', and
|
`--with-afs'
|
||||||
`M_OS=Bsd'. You also modify the existing defines to match your
|
Define if you are using the Andrew File System from Transarc.
|
||||||
machine's software.
|
|
||||||
|
|
||||||
If BASH still won't compile, perhaps because of missing code that
|
`--with-purify'
|
||||||
is required for your YoYo machine, you will have to write that code
|
Define this to use the Purify memory allocation checker from Pure
|
||||||
and place it within a conditional block based on YoYo.
|
Software.
|
||||||
|
|
||||||
Most machines aren't that difficult; simply redefining a few of the
|
`--enable-minimal-config'
|
||||||
default values is sufficient. If you do run across a difficult
|
This produces a shell with minimal features, close to the
|
||||||
machine, please send all fixes and changes to
|
historical Bourne shell.
|
||||||
bash-maintainers@prep.ai.mit.edu in the form of context diffs:
|
|
||||||
|
|
||||||
diff -c orig-machines.h machines.h >machines.diffs
|
The `minimal-config' option can be used to disable all of the following
|
||||||
|
options, but it is processed first, so individual options may be
|
||||||
|
enabled using `enable-FEATURE'.
|
||||||
|
|
||||||
Please include information about which version of the shell you have.
|
All of the following options except for `disabled-builtins' and
|
||||||
|
`usg-echo-default' are enabled by default, unless the operating system
|
||||||
|
does not provide the necessary support.
|
||||||
|
|
||||||
For those machines which prove more difficult, or if you are not
|
`--enable-job-control'
|
||||||
sure about where to start, the scripts in the `portbash' directory
|
This enables job control features, if the OS supports them.
|
||||||
may prove helpful.
|
|
||||||
|
|
||||||
File: bash.info, Node: Bugs, Prev: Porting, Up: Install
|
`--enable-alias'
|
||||||
|
Allow alias expansion and include the `alias' and `unalias'
|
||||||
|
builtins.
|
||||||
|
|
||||||
Reporting Bugs
|
`--enable-readline'
|
||||||
==============
|
Include support for command-line editing and history with the Bash
|
||||||
|
version of the Readline library.
|
||||||
|
|
||||||
If you find a bug in bash, you should report it. But first you
|
`--enable-history'
|
||||||
should make sure that it really is a bug and that it appears in the
|
Include command history and the `fc' and `history' builtin
|
||||||
latest version of BASH that is available.
|
commands.
|
||||||
|
|
||||||
Once you have ascertained that a bug really exists, you are welcome
|
`--enable-bang-history'
|
||||||
to mail in a bug report. If you have a fix, please mail that too!
|
Include support for `csh'-like history substitution.
|
||||||
The program `bashbug' is used to submit bug reports.
|
|
||||||
|
|
||||||
Suggestions and "philosophical" bug reports should be mailed to
|
`--enable-directory-stack'
|
||||||
bug-bash@ai.mit.edu. Genuine bug reports should be mailed to the
|
Include support for a `csh'-like directory stack and the `pushd',
|
||||||
same place, or to bash-maintainers@prep.ai.mit.edu. The `bashbug'
|
`popd', and `dirs' builtins.
|
||||||
script sends its messages to bug-bash@prep.ai.mit.edu.
|
|
||||||
|
|
||||||
*All* bug reports should include:
|
`--enable-restricted'
|
||||||
|
Include support for a "restricted shell". If this is enabled,
|
||||||
|
Bash, when called as `rbash', enters a restricted mode. See *Note
|
||||||
|
The Restricted Shell::, for a description of restricted mode.
|
||||||
|
|
||||||
* The version number of BASH.
|
`--enable-process-substitution'
|
||||||
|
This enables process substitution (*note Process Substitution::.)
|
||||||
|
if the OS provides the necessary support.
|
||||||
|
|
||||||
* The hardware and operating system used.
|
`--enable-prompt-string-decoding'
|
||||||
|
Turn on the interpretation of a number of backslash-escaped
|
||||||
|
characters in the `$PS1', `$PS2', `$PS3', and `$PS4' prompt
|
||||||
|
strings.
|
||||||
|
|
||||||
* The compiler used to compile BASH.
|
`--enable-select'
|
||||||
|
Include the `ksh' `select' builtin, which allows the generation of
|
||||||
|
simple menus.
|
||||||
|
|
||||||
* A description of the bug's behavior.
|
`--enable-help-builtin'
|
||||||
|
Include the `help' builtin, which displays help on shell builtins
|
||||||
|
and variables.
|
||||||
|
|
||||||
* A short script or "recipe" which demonstrates the bug.
|
`--enable-array-variables'
|
||||||
|
Include support for one-dimensional array shell variables.
|
||||||
|
|
||||||
The `bashbug' program includes much of this information
|
`--enable-dparen-arithmetic'
|
||||||
automatically. Without this information, it is generally not
|
Include support for the `ksh' `((...))' command.
|
||||||
possible to successfully debug BASH. Usually, without this
|
|
||||||
information, the bug won't manifest itself!
|
|
||||||
|
|
||||||
Discussion and questions about BASH in general (including
|
`--enable-brace-expansion'
|
||||||
questions about this documentation) can be sent to
|
Include `csh'-like brace expansion ( `b{a,b}c' ==> `bac bbc' ).
|
||||||
bash-maintainers@prep.ai.mit.edu.
|
|
||||||
|
`--enable-disabled-builtins'
|
||||||
|
Allow builtin commands to be invoked via `builtin xxx' even after
|
||||||
|
`xxx' has been disabled using `enable -n xxx'. See *Note Bash
|
||||||
|
Builtins::, for details of the `builtin' and `enable' builtin
|
||||||
|
commands.
|
||||||
|
|
||||||
|
`--enable-command-timing'
|
||||||
|
Include support for recognizing `time' as a reserved word and for
|
||||||
|
displaying timing statistics for the pipeline following `time'.
|
||||||
|
This allows pipelines as well as shell builtins and functions to
|
||||||
|
be timed.
|
||||||
|
|
||||||
|
`--enable-usg-echo-default'
|
||||||
|
Make the `echo' builtin expand backslash-escaped characters by
|
||||||
|
default, without requiring the `-e' option. This makes the Bash
|
||||||
|
`echo' behave more like the System V version.
|
||||||
|
|
||||||
|
The file `config.h.top' contains C Preprocessor `#define' statements
|
||||||
|
for options which are not settable from `configure'. Some of these are
|
||||||
|
not meant to be changed; beware of the consequences if you do. Read
|
||||||
|
the comments associated with each definition for more information about
|
||||||
|
its effect.
|
||||||
|
|||||||
358
MANIFEST
358
MANIFEST
@@ -7,17 +7,20 @@
|
|||||||
CWRU d
|
CWRU d
|
||||||
CWRU/misc d
|
CWRU/misc d
|
||||||
builtins d
|
builtins d
|
||||||
documentation d
|
doc d
|
||||||
examples d
|
examples d
|
||||||
|
examples/bashdb d
|
||||||
examples/functions d
|
examples/functions d
|
||||||
examples/scripts d
|
examples/scripts d
|
||||||
|
examples/scripts.v2 d
|
||||||
|
examples/scripts.noah d
|
||||||
examples/startup-files d
|
examples/startup-files d
|
||||||
|
examples/misc d
|
||||||
|
examples/loadables d
|
||||||
lib d
|
lib d
|
||||||
lib/doc-support d
|
|
||||||
lib/glob d
|
lib/glob d
|
||||||
lib/glob/doc d
|
lib/glob/doc d
|
||||||
lib/malloc d
|
lib/malloc d
|
||||||
lib/malloclib d
|
|
||||||
lib/posixheaders d
|
lib/posixheaders d
|
||||||
lib/readline d
|
lib/readline d
|
||||||
lib/readline/doc d
|
lib/readline/doc d
|
||||||
@@ -26,20 +29,32 @@ lib/termcap d
|
|||||||
lib/termcap/grot d
|
lib/termcap/grot d
|
||||||
lib/tilde d
|
lib/tilde d
|
||||||
lib/tilde/doc d
|
lib/tilde/doc d
|
||||||
portbash d
|
|
||||||
support d
|
support d
|
||||||
tests d
|
tests d
|
||||||
tests/misc d
|
tests/misc d
|
||||||
README f
|
CHANGES f
|
||||||
RELEASE f
|
COMPAT f
|
||||||
INSTALL f
|
|
||||||
COPYING f
|
COPYING f
|
||||||
|
INSTALL f
|
||||||
MANIFEST f
|
MANIFEST f
|
||||||
|
NEWS f
|
||||||
|
NOTES f
|
||||||
|
README f
|
||||||
|
configure.in f
|
||||||
configure f
|
configure f
|
||||||
Makefile f
|
Makefile.in f
|
||||||
cpp-Makefile f
|
config.h.top f
|
||||||
|
config.h.bot f
|
||||||
|
config.h.in f
|
||||||
|
aclocal.m4 f
|
||||||
|
array.c f
|
||||||
|
eval.c f
|
||||||
print_cmd.c f
|
print_cmd.c f
|
||||||
general.c f
|
general.c f
|
||||||
|
list.c f
|
||||||
|
locale.c f
|
||||||
|
stringlib.c f
|
||||||
|
oslib.c f
|
||||||
variables.c f
|
variables.c f
|
||||||
make_cmd.c f
|
make_cmd.c f
|
||||||
copy_cmd.c f
|
copy_cmd.c f
|
||||||
@@ -47,16 +62,17 @@ unwind_prot.c f
|
|||||||
dispose_cmd.c f
|
dispose_cmd.c f
|
||||||
getcwd.c f
|
getcwd.c f
|
||||||
bashhist.c f
|
bashhist.c f
|
||||||
hash.c f
|
hashlib.c f
|
||||||
parse.y f
|
parse.y f
|
||||||
|
pathexp.c f
|
||||||
subst.c f
|
subst.c f
|
||||||
shell.c f
|
shell.c f
|
||||||
trap.c f
|
trap.c f
|
||||||
|
sig.c f
|
||||||
siglist.c f
|
siglist.c f
|
||||||
version.c f
|
version.c f
|
||||||
flags.c f
|
flags.c f
|
||||||
jobs.c f
|
jobs.c f
|
||||||
newversion.c f
|
|
||||||
input.c f
|
input.c f
|
||||||
mailcheck.c f
|
mailcheck.c f
|
||||||
test.c f
|
test.c f
|
||||||
@@ -69,22 +85,23 @@ bracecomp.c f
|
|||||||
nojobs.c f
|
nojobs.c f
|
||||||
vprint.c f
|
vprint.c f
|
||||||
error.c f
|
error.c f
|
||||||
signames.c f
|
xmalloc.c f
|
||||||
endian.c f
|
|
||||||
alias.h f
|
alias.h f
|
||||||
config.h f
|
|
||||||
config.h.mini f
|
|
||||||
builtins.h f
|
builtins.h f
|
||||||
parser.h f
|
bashhist.h f
|
||||||
|
bashline.h f
|
||||||
variables.h f
|
variables.h f
|
||||||
machines.h f
|
array.h f
|
||||||
jobs.h f
|
jobs.h f
|
||||||
maxpath.h f
|
maxpath.h f
|
||||||
filecntl.h f
|
filecntl.h f
|
||||||
hash.h f
|
hashlib.h f
|
||||||
quit.h f
|
quit.h f
|
||||||
flags.h f
|
flags.h f
|
||||||
shell.h f
|
shell.h f
|
||||||
|
pathexp.h f
|
||||||
|
parser.h f
|
||||||
|
sig.h f
|
||||||
trap.h f
|
trap.h f
|
||||||
general.h f
|
general.h f
|
||||||
unwind_prot.h f
|
unwind_prot.h f
|
||||||
@@ -96,19 +113,25 @@ siglist.h f
|
|||||||
subst.h f
|
subst.h f
|
||||||
dispose_cmd.h f
|
dispose_cmd.h f
|
||||||
bashansi.h f
|
bashansi.h f
|
||||||
|
bashtty.h f
|
||||||
|
bashjmp.h f
|
||||||
|
bashwait.h f
|
||||||
|
bashintl.h f
|
||||||
make_cmd.h f
|
make_cmd.h f
|
||||||
bashhist.h f
|
|
||||||
execute_cmd.h f
|
execute_cmd.h f
|
||||||
bashtypes.h f
|
bashtypes.h f
|
||||||
|
mailcheck.h f
|
||||||
|
pathnames.h f
|
||||||
y.tab.c f
|
y.tab.c f
|
||||||
y.tab.h f
|
y.tab.h f
|
||||||
|
posixdir.h f
|
||||||
posixstat.h f
|
posixstat.h f
|
||||||
stdc.h f
|
stdc.h f
|
||||||
ansi_stdlib.h f
|
ansi_stdlib.h f
|
||||||
memalloc.h f
|
memalloc.h f
|
||||||
parser-built f
|
parser-built f
|
||||||
builtins/ChangeLog f
|
builtins/ChangeLog f
|
||||||
builtins/Makefile f
|
builtins/Makefile.in f
|
||||||
builtins/alias.def f
|
builtins/alias.def f
|
||||||
builtins/bind.def f
|
builtins/bind.def f
|
||||||
builtins/break.def f
|
builtins/break.def f
|
||||||
@@ -121,6 +144,8 @@ builtins/declare.def f
|
|||||||
builtins/echo.def f
|
builtins/echo.def f
|
||||||
builtins/enable.def f
|
builtins/enable.def f
|
||||||
builtins/eval.def f
|
builtins/eval.def f
|
||||||
|
builtins/evalfile.c f
|
||||||
|
builtins/evalstring.c f
|
||||||
builtins/exec.def f
|
builtins/exec.def f
|
||||||
builtins/exit.def f
|
builtins/exit.def f
|
||||||
builtins/fc.def f
|
builtins/fc.def f
|
||||||
@@ -136,12 +161,14 @@ builtins/history.def f
|
|||||||
builtins/jobs.def f
|
builtins/jobs.def f
|
||||||
builtins/kill.def f
|
builtins/kill.def f
|
||||||
builtins/mkbuiltins.c f
|
builtins/mkbuiltins.c f
|
||||||
|
builtins/pushd.def f
|
||||||
builtins/read.def f
|
builtins/read.def f
|
||||||
builtins/reserved.def f
|
builtins/reserved.def f
|
||||||
builtins/return.def f
|
builtins/return.def f
|
||||||
builtins/set.def f
|
builtins/set.def f
|
||||||
builtins/setattr.def f
|
builtins/setattr.def f
|
||||||
builtins/shift.def f
|
builtins/shift.def f
|
||||||
|
builtins/shopt.def f
|
||||||
builtins/source.def f
|
builtins/source.def f
|
||||||
builtins/suspend.def f
|
builtins/suspend.def f
|
||||||
builtins/test.def f
|
builtins/test.def f
|
||||||
@@ -157,63 +184,76 @@ builtins/inlib.def f
|
|||||||
builtins/bashgetopt.c f
|
builtins/bashgetopt.c f
|
||||||
builtins/common.h f
|
builtins/common.h f
|
||||||
builtins/bashgetopt.h f
|
builtins/bashgetopt.h f
|
||||||
lib/doc-support/texindex.c f
|
|
||||||
lib/doc-support/getopt.h f
|
|
||||||
lib/doc-support/Makefile f
|
|
||||||
lib/glob/ChangeLog f
|
lib/glob/ChangeLog f
|
||||||
lib/glob/Makefile f
|
lib/glob/Makefile.in f
|
||||||
lib/glob/fnmatch.c f
|
lib/glob/fnmatch.c f
|
||||||
lib/glob/fnmatch.h f
|
lib/glob/fnmatch.h f
|
||||||
lib/glob/glob.c f
|
lib/glob/glob.c f
|
||||||
|
lib/glob/glob.h f
|
||||||
lib/glob/doc/Makefile f
|
lib/glob/doc/Makefile f
|
||||||
lib/glob/doc/glob.texi f
|
lib/glob/doc/glob.texi f
|
||||||
lib/glob/ndir.h f
|
lib/glob/ndir.h f
|
||||||
lib/malloc/Makefile f
|
lib/malloc/Makefile.in f
|
||||||
lib/malloc/alloca.c f
|
|
||||||
lib/malloc/getpagesize.h f
|
lib/malloc/getpagesize.h f
|
||||||
lib/malloc/i386-alloca.s f
|
lib/malloc/alloca.c f
|
||||||
lib/malloc/malloc.c f
|
lib/malloc/malloc.c f
|
||||||
lib/malloc/x386-alloca.s f
|
lib/malloc/gmalloc.c f
|
||||||
lib/malloc/xmalloc.c f
|
lib/malloc/xmalloc.c f
|
||||||
lib/malloclib/Makefile f
|
lib/malloc/stub.c f
|
||||||
lib/malloclib/alloca.c f
|
lib/malloc/i386-alloca.s f
|
||||||
lib/malloclib/i386-alloca.s f
|
lib/malloc/x386-alloca.s f
|
||||||
lib/malloclib/calloc.c f
|
lib/posixheaders/posixdir.h f
|
||||||
lib/malloclib/cfree.c f
|
|
||||||
lib/malloclib/x386-alloca.s f
|
|
||||||
lib/malloclib/morecore.c f
|
|
||||||
lib/malloclib/free.c f
|
|
||||||
lib/malloclib/getpagesize.h f
|
|
||||||
lib/malloclib/malloc.c f
|
|
||||||
lib/malloclib/malloc.h f
|
|
||||||
lib/malloclib/xmalloc.c f
|
|
||||||
lib/malloclib/mcheck.c f
|
|
||||||
lib/malloclib/memalign.c f
|
|
||||||
lib/malloclib/mstats.c f
|
|
||||||
lib/malloclib/mtrace.awk f
|
|
||||||
lib/malloclib/mtrace.c f
|
|
||||||
lib/malloclib/realloc.c f
|
|
||||||
lib/malloclib/valloc.c f
|
|
||||||
lib/posixheaders/posixstat.h f
|
lib/posixheaders/posixstat.h f
|
||||||
lib/posixheaders/ansi_stdlib.h f
|
lib/posixheaders/ansi_stdlib.h f
|
||||||
lib/posixheaders/stdc.h f
|
lib/posixheaders/stdc.h f
|
||||||
lib/posixheaders/memalloc.h f
|
lib/posixheaders/memalloc.h f
|
||||||
lib/posixheaders/filecntl.h f
|
lib/posixheaders/filecntl.h f
|
||||||
lib/readline/COPYING f
|
lib/readline/COPYING f
|
||||||
lib/readline/readline.c f
|
lib/readline/Makefile.in f
|
||||||
lib/readline/readline.h f
|
|
||||||
lib/readline/ChangeLog f
|
lib/readline/ChangeLog f
|
||||||
|
lib/readline/README f
|
||||||
|
lib/readline/STANDALONE f
|
||||||
|
lib/readline/readline.c f
|
||||||
lib/readline/vi_mode.c f
|
lib/readline/vi_mode.c f
|
||||||
lib/readline/history.h f
|
|
||||||
lib/readline/Makefile f
|
|
||||||
lib/readline/chardefs.h f
|
|
||||||
lib/readline/emacs_keymap.c f
|
lib/readline/emacs_keymap.c f
|
||||||
lib/readline/keymaps.h f
|
|
||||||
lib/readline/vi_keymap.c f
|
lib/readline/vi_keymap.c f
|
||||||
lib/readline/history.c f
|
lib/readline/history.c f
|
||||||
|
lib/readline/histexpand.c f
|
||||||
|
lib/readline/histsearch.c f
|
||||||
|
lib/readline/histfile.c f
|
||||||
lib/readline/funmap.c f
|
lib/readline/funmap.c f
|
||||||
lib/readline/keymaps.c f
|
lib/readline/keymaps.c f
|
||||||
|
lib/readline/util.c f
|
||||||
|
lib/readline/terminal.c f
|
||||||
lib/readline/xmalloc.c f
|
lib/readline/xmalloc.c f
|
||||||
|
lib/readline/search.c f
|
||||||
|
lib/readline/isearch.c f
|
||||||
|
lib/readline/parens.c f
|
||||||
|
lib/readline/rltty.c f
|
||||||
|
lib/readline/complete.c f
|
||||||
|
lib/readline/bind.c f
|
||||||
|
lib/readline/display.c f
|
||||||
|
lib/readline/signals.c f
|
||||||
|
lib/readline/kill.c f
|
||||||
|
lib/readline/undo.c f
|
||||||
|
lib/readline/macro.c f
|
||||||
|
lib/readline/input.c f
|
||||||
|
lib/readline/callback.c f
|
||||||
|
lib/readline/nls.c f
|
||||||
|
lib/readline/tilde.c f
|
||||||
|
lib/readline/tilde.h f
|
||||||
|
lib/readline/rldefs.h f
|
||||||
|
lib/readline/rlconf.h f
|
||||||
|
lib/readline/rltty.h f
|
||||||
|
lib/readline/readline.h f
|
||||||
|
lib/readline/tcap.h f
|
||||||
|
lib/readline/keymaps.h f
|
||||||
|
lib/readline/history.h f
|
||||||
|
lib/readline/histlib.h f
|
||||||
|
lib/readline/chardefs.h f
|
||||||
|
lib/readline/posixdir.h f
|
||||||
|
lib/readline/posixstat.h f
|
||||||
|
lib/readline/ansi_stdlib.h f
|
||||||
lib/readline/doc/Makefile f
|
lib/readline/doc/Makefile f
|
||||||
lib/readline/doc/rlman.texinfo f
|
lib/readline/doc/rlman.texinfo f
|
||||||
lib/readline/doc/rltech.texinfo f
|
lib/readline/doc/rltech.texinfo f
|
||||||
@@ -225,26 +265,9 @@ lib/readline/examples/Makefile f
|
|||||||
lib/readline/examples/fileman.c f
|
lib/readline/examples/fileman.c f
|
||||||
lib/readline/examples/manexamp.c f
|
lib/readline/examples/manexamp.c f
|
||||||
lib/readline/examples/histexamp.c f
|
lib/readline/examples/histexamp.c f
|
||||||
|
lib/readline/examples/rltest.c f
|
||||||
lib/readline/examples/Inputrc f
|
lib/readline/examples/Inputrc f
|
||||||
lib/readline/README f
|
lib/termcap/Makefile.in f
|
||||||
lib/readline/STANDALONE f
|
|
||||||
lib/readline/search.c f
|
|
||||||
lib/readline/isearch.c f
|
|
||||||
lib/readline/rldefs.h f
|
|
||||||
lib/readline/rlconf.h f
|
|
||||||
lib/readline/parens.c f
|
|
||||||
lib/readline/rltty.c f
|
|
||||||
lib/readline/complete.c f
|
|
||||||
lib/readline/bind.c f
|
|
||||||
lib/readline/display.c f
|
|
||||||
lib/readline/signals.c f
|
|
||||||
lib/readline/doc/texindex.c f
|
|
||||||
lib/readline/tilde.c f
|
|
||||||
lib/readline/tilde.h f
|
|
||||||
lib/readline/posixstat.h f
|
|
||||||
lib/readline/ansi_stdlib.h f
|
|
||||||
lib/readline/memalloc.h f
|
|
||||||
lib/termcap/Makefile f
|
|
||||||
lib/termcap/termcap.c f
|
lib/termcap/termcap.c f
|
||||||
lib/termcap/termcap.h f
|
lib/termcap/termcap.h f
|
||||||
lib/termcap/tparam.c f
|
lib/termcap/tparam.c f
|
||||||
@@ -265,62 +288,80 @@ lib/termcap/grot/configure.in f
|
|||||||
lib/termcap/grot/COPYING f
|
lib/termcap/grot/COPYING f
|
||||||
lib/termcap/grot/README f
|
lib/termcap/grot/README f
|
||||||
lib/tilde/ChangeLog f
|
lib/tilde/ChangeLog f
|
||||||
lib/tilde/Makefile f
|
lib/tilde/Makefile.in f
|
||||||
lib/tilde/doc/tilde.texi f
|
lib/tilde/doc/tilde.texi f
|
||||||
lib/tilde/doc/Makefile f
|
lib/tilde/doc/Makefile f
|
||||||
lib/tilde/tilde.c f
|
lib/tilde/tilde.c f
|
||||||
lib/tilde/tilde.h f
|
lib/tilde/tilde.h f
|
||||||
lib/tilde/memalloc.h f
|
|
||||||
CWRU/misc/open-files.c f
|
CWRU/misc/open-files.c f
|
||||||
CWRU/misc/sigs.c f
|
CWRU/misc/sigs.c f
|
||||||
CWRU/misc/pid.c f
|
CWRU/misc/pid.c f
|
||||||
CWRU/misc/sigstat.c f
|
CWRU/misc/sigstat.c f
|
||||||
CWRU/misc/bison f
|
CWRU/misc/bison f
|
||||||
CWRU/misc/aux-mach-desc f
|
|
||||||
CWRU/PLATFORMS f
|
CWRU/PLATFORMS f
|
||||||
CWRU/README f
|
CWRU/README f
|
||||||
CWRU/POSIX.NOTES f
|
CWRU/POSIX.NOTES f
|
||||||
CWRU/changelog f
|
CWRU/changelog f
|
||||||
CWRU/sh-redirection-hack f
|
CWRU/sh-redir-hack f
|
||||||
documentation/Makefile f
|
CWRU/mh-folder-comp f
|
||||||
documentation/bash.1 f
|
doc/FAQ f
|
||||||
documentation/bash.ps f
|
doc/Makefile.in f
|
||||||
documentation/bash.txt f
|
doc/bash.1 f
|
||||||
documentation/README f
|
doc/bashbug.1 f
|
||||||
documentation/readline.3 f
|
doc/README f
|
||||||
documentation/readline.ps f
|
doc/INTRO f
|
||||||
documentation/readline.txt f
|
doc/readline.3 f
|
||||||
documentation/texinfo.tex f
|
doc/texinfo.tex f
|
||||||
documentation/features.texi f
|
doc/bashref.texi f
|
||||||
documentation/features.info f
|
doc/bashref.info f
|
||||||
documentation/features.dvi f
|
doc/builtins.1 f
|
||||||
documentation/features.ps f
|
doc/article.ms f
|
||||||
documentation/builtins.1 f
|
support/config.guess f
|
||||||
documentation/builtins.ps f
|
support/config.sub f
|
||||||
documentation/builtins.txt f
|
support/printenv f 755
|
||||||
documentation/article.ms f
|
|
||||||
documentation/article.ps f
|
|
||||||
documentation/article.txt f
|
|
||||||
support/cat-s f
|
|
||||||
support/mksysdefs f
|
|
||||||
support/printenv f
|
|
||||||
support/getcppsyms.c f
|
|
||||||
support/cppmagic f
|
|
||||||
support/bash.xbm f
|
support/bash.xbm f
|
||||||
support/FAQ f
|
support/mkclone f 755
|
||||||
support/PORTING f
|
support/mkdirs f 755
|
||||||
support/mklinks f
|
support/mkversion.c f
|
||||||
support/mkdirs f
|
support/mksignames.c f
|
||||||
support/clone-bash f
|
|
||||||
support/bashbug.sh f
|
support/bashbug.sh f
|
||||||
support/mkmachtype f
|
|
||||||
support/recho.c f
|
support/recho.c f
|
||||||
support/srcdir f
|
support/zecho.c f
|
||||||
support/SYMLINKS f
|
support/SYMLINKS f
|
||||||
support/fixlinks f
|
support/fixlinks f 755
|
||||||
|
support/install.sh f 755
|
||||||
|
support/texi2dvi f
|
||||||
|
support/texi2html f
|
||||||
|
examples/bashdb/PERMISSION f
|
||||||
|
examples/bashdb/README f
|
||||||
|
examples/bashdb/bashdb f
|
||||||
|
examples/bashdb/bashdb.fns f
|
||||||
|
examples/bashdb/bashdb.pre f
|
||||||
|
examples/loadables/README f
|
||||||
|
examples/loadables/Makefile f
|
||||||
|
examples/loadables/necho.c f
|
||||||
|
examples/loadables/hello.c f
|
||||||
|
examples/loadables/printf.c f
|
||||||
|
examples/loadables/print.c f
|
||||||
|
examples/loadables/sprintf.c f
|
||||||
|
examples/loadables/sleep.c f
|
||||||
|
examples/loadables/truefalse.c f
|
||||||
|
examples/loadables/getconf.c f
|
||||||
|
examples/loadables/pushd.c f
|
||||||
|
examples/loadables/finfo.c f
|
||||||
|
examples/loadables/cat.c f
|
||||||
|
examples/loadables/logname.c f
|
||||||
|
examples/loadables/basename.c f
|
||||||
|
examples/loadables/dirname.c f
|
||||||
|
examples/loadables/tty.c f
|
||||||
|
examples/loadables/pathchk.c f
|
||||||
|
examples/loadables/tee.c f
|
||||||
|
examples/loadables/rmdir.c f
|
||||||
|
examples/loadables/head.c f
|
||||||
examples/functions/substr f
|
examples/functions/substr f
|
||||||
examples/functions/kshenv f
|
examples/functions/kshenv f
|
||||||
examples/functions/autoload f
|
examples/functions/autoload f
|
||||||
|
examples/functions/autoload.v2 f
|
||||||
examples/functions/csh-compat f
|
examples/functions/csh-compat f
|
||||||
examples/functions/shcat f
|
examples/functions/shcat f
|
||||||
examples/functions/substr2 f
|
examples/functions/substr2 f
|
||||||
@@ -338,18 +379,39 @@ examples/functions/manpage f
|
|||||||
examples/functions/fstty f
|
examples/functions/fstty f
|
||||||
examples/functions/jj.bash f
|
examples/functions/jj.bash f
|
||||||
examples/functions/notify.bash f
|
examples/functions/notify.bash f
|
||||||
|
examples/functions/inpath f
|
||||||
|
examples/functions/login f
|
||||||
|
examples/functions/keep f
|
||||||
|
examples/functions/seq f
|
||||||
|
examples/functions/mhfold f
|
||||||
|
examples/functions/repeat2 f
|
||||||
|
examples/functions/lowercase f
|
||||||
examples/scripts/shprompt f
|
examples/scripts/shprompt f
|
||||||
examples/scripts/adventure.sh f
|
examples/scripts/adventure.sh f
|
||||||
examples/scripts/precedence f
|
examples/scripts/precedence f
|
||||||
examples/scripts/bcsh.sh f
|
examples/scripts/bcsh.sh f
|
||||||
|
examples/scripts/inpath f
|
||||||
|
examples/scripts/nohup.bash f
|
||||||
|
examples/scripts/vtree2 f
|
||||||
|
examples/scripts/scrollbar f
|
||||||
|
examples/scripts/zprintf f
|
||||||
|
examples/startup-files/README f
|
||||||
examples/startup-files/Bashrc f
|
examples/startup-files/Bashrc f
|
||||||
examples/startup-files/Bash_aliases f
|
examples/startup-files/Bash_aliases f
|
||||||
examples/startup-files/Bash_profile f
|
examples/startup-files/Bash_profile f
|
||||||
examples/startup-files/bash-profile f
|
examples/startup-files/bash-profile f
|
||||||
examples/startup-files/bashrc f
|
examples/startup-files/bashrc f
|
||||||
examples/suncmd.termcap f
|
examples/misc/suncmd.termcap f
|
||||||
examples/alias-conv.sh f
|
examples/misc/alias-conv.sh f
|
||||||
|
examples/misc/alias-conv.bash f
|
||||||
|
examples/misc/cshtobash f
|
||||||
tests/README f
|
tests/README f
|
||||||
|
tests/arith.tests f
|
||||||
|
tests/arith.right f
|
||||||
|
tests/array.tests f
|
||||||
|
tests/array.right f
|
||||||
|
tests/braces-tests f
|
||||||
|
tests/braces.right f
|
||||||
tests/dollar-at.sh f
|
tests/dollar-at.sh f
|
||||||
tests/dollar-star.sh f
|
tests/dollar-star.sh f
|
||||||
tests/dollar.right f
|
tests/dollar.right f
|
||||||
@@ -357,6 +419,8 @@ tests/exp-tests f
|
|||||||
tests/exp.right f
|
tests/exp.right f
|
||||||
tests/glob-test f
|
tests/glob-test f
|
||||||
tests/glob.right f
|
tests/glob.right f
|
||||||
|
tests/heredoc.tests f
|
||||||
|
tests/heredoc.right f
|
||||||
tests/ifs-test-1.sh f
|
tests/ifs-test-1.sh f
|
||||||
tests/ifs-test-2.sh f
|
tests/ifs-test-2.sh f
|
||||||
tests/ifs-test-3.sh f
|
tests/ifs-test-3.sh f
|
||||||
@@ -368,26 +432,52 @@ tests/input-line.sub f
|
|||||||
tests/input.right f
|
tests/input.right f
|
||||||
tests/minus-e f
|
tests/minus-e f
|
||||||
tests/minus-e.right f
|
tests/minus-e.right f
|
||||||
|
tests/more-exp.tests f
|
||||||
|
tests/more-exp.right f
|
||||||
tests/new-exp.tests f
|
tests/new-exp.tests f
|
||||||
tests/new-exp.right f
|
tests/new-exp.right f
|
||||||
|
tests/nquote.tests f
|
||||||
|
tests/nquote.right f
|
||||||
|
tests/posix2.tests f
|
||||||
|
tests/posix2.right f
|
||||||
tests/prec.right f
|
tests/prec.right f
|
||||||
tests/precedence f
|
tests/precedence f
|
||||||
|
tests/quote.tests f
|
||||||
|
tests/quote.right f
|
||||||
|
tests/read.tests f
|
||||||
|
tests/read.right f
|
||||||
|
tests/rhs-exp.tests f
|
||||||
|
tests/rhs-exp.right f
|
||||||
tests/run-all f
|
tests/run-all f
|
||||||
|
tests/run-arith f
|
||||||
|
tests/run-array f
|
||||||
|
tests/run-braces f
|
||||||
tests/run-dollars f
|
tests/run-dollars f
|
||||||
tests/run-exp-tests f
|
tests/run-exp-tests f
|
||||||
tests/run-glob-test f
|
tests/run-glob-test f
|
||||||
|
tests/run-heredoc f
|
||||||
tests/run-ifs-tests f
|
tests/run-ifs-tests f
|
||||||
tests/run-input-test f
|
tests/run-input-test f
|
||||||
tests/run-minus-e f
|
tests/run-minus-e f
|
||||||
|
tests/run-more-exp f
|
||||||
tests/run-new-exp f
|
tests/run-new-exp f
|
||||||
|
tests/run-nquote f
|
||||||
|
tests/run-posix2 f
|
||||||
tests/run-precedence f
|
tests/run-precedence f
|
||||||
|
tests/run-quote f
|
||||||
|
tests/run-read f
|
||||||
|
tests/run-rhs-exp f
|
||||||
tests/run-set-e-test f
|
tests/run-set-e-test f
|
||||||
tests/run-strip f
|
tests/run-strip f
|
||||||
|
tests/run-test f
|
||||||
|
tests/run-tilde f
|
||||||
tests/run-varenv f
|
tests/run-varenv f
|
||||||
tests/set-e-test f
|
tests/set-e-test f
|
||||||
tests/set-e.right f
|
tests/set-e.right f
|
||||||
tests/strip.tests f
|
tests/strip.tests f
|
||||||
tests/strip.right f
|
tests/strip.right f
|
||||||
|
tests/test-tests f
|
||||||
|
tests/test.right f
|
||||||
tests/tilde-tests f
|
tests/tilde-tests f
|
||||||
tests/tilde.right f
|
tests/tilde.right f
|
||||||
tests/varenv.right f
|
tests/varenv.right f
|
||||||
@@ -411,11 +501,43 @@ tests/misc/sigint.t3.sh f
|
|||||||
tests/misc/sigint.t4.sh f
|
tests/misc/sigint.t4.sh f
|
||||||
tests/misc/test-minus-e.1 f
|
tests/misc/test-minus-e.1 f
|
||||||
tests/misc/test-minus-e.2 f
|
tests/misc/test-minus-e.2 f
|
||||||
portbash/signals.sh f
|
examples/scripts.v2/PERMISSION f
|
||||||
portbash/stdio.sh f
|
examples/scripts.v2/README f
|
||||||
portbash/libc.sh f
|
examples/scripts.v2/arc2tarz f
|
||||||
portbash/mkdesc.sh f
|
examples/scripts.v2/bashrand f
|
||||||
portbash/README f
|
examples/scripts.v2/cdhist.bash f
|
||||||
portbash/strings.sh f
|
examples/scripts.v2/corename f
|
||||||
portbash/syscalls.sh f
|
examples/scripts.v2/fman f
|
||||||
portbash/pgrp.c f
|
examples/scripts.v2/frcp f
|
||||||
|
examples/scripts.v2/lowercase f
|
||||||
|
examples/scripts.v2/ncp f
|
||||||
|
examples/scripts.v2/newext f
|
||||||
|
examples/scripts.v2/nmv f
|
||||||
|
examples/scripts.v2/pages f
|
||||||
|
examples/scripts.v2/pf f
|
||||||
|
examples/scripts.v2/rename f
|
||||||
|
examples/scripts.v2/repeat f
|
||||||
|
examples/scripts.v2/untar f
|
||||||
|
examples/scripts.v2/uudec f
|
||||||
|
examples/scripts.v2/uuenc f
|
||||||
|
examples/scripts.v2/vtree f
|
||||||
|
examples/scripts.v2/where f
|
||||||
|
examples/scripts.v2/pmtop f
|
||||||
|
examples/scripts.v2/shprof f
|
||||||
|
examples/scripts.noah/PERMISSION f
|
||||||
|
examples/scripts.noah/README f
|
||||||
|
examples/scripts.noah/aref.bash f
|
||||||
|
examples/scripts.noah/bash.sub.bash f
|
||||||
|
examples/scripts.noah/bash_version.bash f
|
||||||
|
examples/scripts.noah/meta.bash f
|
||||||
|
examples/scripts.noah/mktmp.bash f
|
||||||
|
examples/scripts.noah/number.bash f
|
||||||
|
examples/scripts.noah/prompt.bash f
|
||||||
|
examples/scripts.noah/remap_keys.bash f
|
||||||
|
examples/scripts.noah/require.bash f
|
||||||
|
examples/scripts.noah/send_mail.bash f
|
||||||
|
examples/scripts.noah/shcat.bash f
|
||||||
|
examples/scripts.noah/source.bash f
|
||||||
|
examples/scripts.noah/string.bash f
|
||||||
|
examples/scripts.noah/stty.bash f
|
||||||
|
examples/scripts.noah/y_or_n_p.bash f
|
||||||
|
|||||||
115
Makefile
115
Makefile
@@ -1,115 +0,0 @@
|
|||||||
# Hey Emacs, this Makefile is in -*- makefile -*- mode!
|
|
||||||
#
|
|
||||||
# Makefile for Bash.
|
|
||||||
# If your cpp doesn't like -P, just get rid of it (the -P, not cpp).
|
|
||||||
# If you wish to use Gcc, then type `make CC=gcc CPPNAME='$(CC) -E''.
|
|
||||||
# If you wish to use GNU's Make, then change `MAKE'.
|
|
||||||
# If you don't like the destination, then change `bindir'.
|
|
||||||
# The file that you most likely want to look at is cpp-Makefile.
|
|
||||||
#
|
|
||||||
# If you haven't read README, now might be a good time.
|
|
||||||
|
|
||||||
# Include some boilerplate Gnu makefile definitions.
|
|
||||||
prefix = /usr/local
|
|
||||||
exec_prefix = $(prefix)
|
|
||||||
bindir = $(exec_prefix)/bin
|
|
||||||
srcdir = .
|
|
||||||
VPATH = $(srcdir)
|
|
||||||
|
|
||||||
# MAKE = make
|
|
||||||
RM = rm -f
|
|
||||||
SHELL = /bin/sh
|
|
||||||
GAWK = awk
|
|
||||||
# GAWK = gawk
|
|
||||||
|
|
||||||
# Force CPPNAME to be the name of your C preprocesor if Bash can't
|
|
||||||
# find it. For instance, `CPPNAME=/usr/libexec/cpp' on 4.4 BSD.
|
|
||||||
# If all else fails, set CPPNAME=$(CC) -E
|
|
||||||
CPPNAME =
|
|
||||||
CPP = `$(SHELL) $(CPPMAGIC) $(GETCPPSYMS) "$(CPPNAME)"` -P
|
|
||||||
|
|
||||||
CPP_MAKEFILE = $(srcdir)/cpp-Makefile
|
|
||||||
ANSI_MAKEFILE = ansi-Makefile
|
|
||||||
|
|
||||||
# CPPFLAGS = $(SYSTEM) $(CPP_DEFINES)
|
|
||||||
CPPFLAGS = $(CPP_DEFINES) -I. -I$(srcdir)
|
|
||||||
CPP_ARGS = -DCPP_CC="$(CC)"
|
|
||||||
|
|
||||||
SUPPORTDIR = ./support/
|
|
||||||
SUPPORTSRC = $(srcdir)/support/
|
|
||||||
|
|
||||||
MKSYSDEFS = $(SUPPORTSRC)mksysdefs
|
|
||||||
CPPMAGIC = $(SUPPORTSRC)cppmagic
|
|
||||||
CAT_S = $(SUPPORTSRC)cat-s
|
|
||||||
GETCPPSYMS = $(SUPPORTDIR)getcppsyms
|
|
||||||
GETCPPSYMS_SRC = $(SUPPORTSRC)getcppsyms.c
|
|
||||||
|
|
||||||
# Here is a command which compresses runs of multiple blank lines to a
|
|
||||||
# single blank line. "cat -s" works for BSD systems, but not for USG
|
|
||||||
# systems. You can use an awk script if you like. If you have too
|
|
||||||
# much trouble with this, just forget it. It is for making
|
|
||||||
# bash-Makefile pretty and readable; something that isn't strictly
|
|
||||||
# necessary.
|
|
||||||
# SQUASH_BLANKS = cat -s
|
|
||||||
#
|
|
||||||
SQUASH_BLANKS = $(GAWK) -f $(CAT_S)
|
|
||||||
|
|
||||||
all: .notified bash-Makefile
|
|
||||||
$(MAKE) -f bash-Makefile $(MFLAGS) $(MAKEARGS) srcdir=$(srcdir)
|
|
||||||
|
|
||||||
bash-Makefile: $(CPP_MAKEFILE) Makefile machines.h sysdefs.h config.h
|
|
||||||
@-if [ -f ansi-Makefile ]; then \
|
|
||||||
echo "cp ansi-Makefile tmp-Makefile.c"; \
|
|
||||||
cp ansi-Makefile tmp-Makefile.c; else \
|
|
||||||
echo "cp $(CPP_MAKEFILE) tmp-Makefile.c"; \
|
|
||||||
cp $(CPP_MAKEFILE) tmp-Makefile.c; \
|
|
||||||
fi
|
|
||||||
$(RM) $(GETCPPSYMS)
|
|
||||||
$(SHELL) $(SUPPORTSRC)mkdirs support
|
|
||||||
$(CC) -o $(GETCPPSYMS) $(GETCPPSYMS_SRC)
|
|
||||||
rm -f bash-Makefile
|
|
||||||
@$(SHELL) -c 'echo $(CPP) $(CPPFLAGS) $(CPP_ARGS) tmp-Makefile.c \| $(SQUASH_BLANKS) \> bash-Makefile'
|
|
||||||
@$(SHELL) -c '$(CPP) $(CPPFLAGS) $(CPP_ARGS) tmp-Makefile.c | $(SQUASH_BLANKS) >bash-Makefile'
|
|
||||||
rm -f tmp-Makefile.c
|
|
||||||
@test -s bash-Makefile || { rm -f bash-Makefile ; exit 1; }
|
|
||||||
|
|
||||||
sysdefs.h: $(MKSYSDEFS)
|
|
||||||
$(SHELL) $(MKSYSDEFS) -s $(srcdir)
|
|
||||||
|
|
||||||
# This is also performed by support/mksysdefs, but there's no way to change
|
|
||||||
# it if cpp-Makefile is changed without changing anything else, since there
|
|
||||||
# are no dependencies. This lets you run `make ansi-Makefile'.
|
|
||||||
ansi-Makefile: $(CPP_MAKEFILE)
|
|
||||||
grep -v '/\*\*/' $(CPP_MAKEFILE) > $@
|
|
||||||
|
|
||||||
# Subsequent lines contain targets that are correctly handled by an
|
|
||||||
# existing bash-Makefile.
|
|
||||||
|
|
||||||
install uninstall newversion architecture: bash-Makefile
|
|
||||||
$(MAKE) -f bash-Makefile $(MFLAGS) $(MAKEARGS) bindir=$(bindir) \
|
|
||||||
prefix=$(prefix) $@
|
|
||||||
|
|
||||||
tests DEFINES tags documentation: bash-Makefile directory-frob
|
|
||||||
$(MAKE) -f bash-Makefile $(MFLAGS) $(MAKEARGS) $@
|
|
||||||
|
|
||||||
clean distclean realclean mostlyclean maintainer-clean: bash-Makefile directory-frob
|
|
||||||
rm -f .notified
|
|
||||||
$(MAKE) -f bash-Makefile $(MFLAGS) $(MAKEARGS) $@
|
|
||||||
|
|
||||||
directory-frob:
|
|
||||||
|
|
||||||
.NOEXPORT:
|
|
||||||
|
|
||||||
.notified:
|
|
||||||
@echo ""
|
|
||||||
@echo " You are about to make this version of GNU Bash for"
|
|
||||||
@echo " this architecture for the first time. If you haven't"
|
|
||||||
@echo " yet read the README file, you may want to do so. If"
|
|
||||||
@echo " you wish to report a bug in Bash, or in the installation"
|
|
||||||
@echo " procedure, please run the bashbug script and include:"
|
|
||||||
@echo ""
|
|
||||||
@echo " * a description of the bug,"
|
|
||||||
@echo " * a recipe for recreating the bug reliably,"
|
|
||||||
@echo " * a fix for the bug if you have one!"
|
|
||||||
@echo ""
|
|
||||||
@touch .notified
|
|
||||||
941
Makefile.in
Normal file
941
Makefile.in
Normal file
@@ -0,0 +1,941 @@
|
|||||||
|
# Make sure the first target in the makefile is the right one
|
||||||
|
all: .made
|
||||||
|
|
||||||
|
# Include some boilerplate Gnu makefile definitions.
|
||||||
|
prefix = @prefix@
|
||||||
|
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
bindir = @bindir@
|
||||||
|
libdir = @libdir@
|
||||||
|
infodir = @infodir@
|
||||||
|
includedir = @includedir@
|
||||||
|
|
||||||
|
mandir = @mandir@
|
||||||
|
manpfx = man
|
||||||
|
|
||||||
|
man1ext = 1
|
||||||
|
man1dir = $(mandir)/$(manpfx)$(man1ext)
|
||||||
|
man3ext = 3
|
||||||
|
man3dir = $(mandir)/$(manpfx)$(man3ext)
|
||||||
|
|
||||||
|
topdir = @top_srcdir@
|
||||||
|
BUILD_DIR = @BUILD_DIR@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = .:@srcdir@
|
||||||
|
|
||||||
|
@SET_MAKE@
|
||||||
|
CC = @CC@
|
||||||
|
YACC = @YACC@
|
||||||
|
SHELL=/bin/sh
|
||||||
|
CP = cp
|
||||||
|
RM = rm -f
|
||||||
|
AR = @AR@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
|
||||||
|
COMPRESS = gzip
|
||||||
|
COMPRESS_EXT = .gz
|
||||||
|
|
||||||
|
#If you have purify, and want to use it, uncomment this definition or
|
||||||
|
# run the make as `make PURIFY=purify'
|
||||||
|
# or run configure with the --with-purify argument.
|
||||||
|
PURIFY = @PURIFY@
|
||||||
|
|
||||||
|
# Here is a rule for making .o files from .c files that does not
|
||||||
|
# force the type of the machine (like -M_MACHINE) into the flags.
|
||||||
|
.c.o:
|
||||||
|
$(RM) $@
|
||||||
|
$(CC) $(CCFLAGS) -c $<
|
||||||
|
|
||||||
|
# The name of this program.
|
||||||
|
Program = bash
|
||||||
|
Machine = @host_cpu@
|
||||||
|
OS = @host_os@
|
||||||
|
MACHTYPE = @host@
|
||||||
|
|
||||||
|
RELSTATUS = release
|
||||||
|
|
||||||
|
THIS_SH = $(BUILD_DIR)/$(Program)
|
||||||
|
|
||||||
|
# PROFILE_FLAGS is either -pg, to generate profiling info for use
|
||||||
|
# with gprof, or nothing (the default).
|
||||||
|
PROFILE_FLAGS=
|
||||||
|
|
||||||
|
# set to alloca.o if we are using the C alloca in lib/malloc
|
||||||
|
ALLOCA = @ALLOCA@
|
||||||
|
ALLOCA_SOURCE = @ALLOCA_SOURCE@
|
||||||
|
ALLOCA_OBJECT = @ALLOCA_OBJECT@
|
||||||
|
|
||||||
|
# The GNU coding standards don't recognize the possibility that
|
||||||
|
# other information besides optimization and debugging might be
|
||||||
|
# passed to cc. A different name should have been used.
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
LOCAL_CFLAGS = @LOCAL_CFLAGS@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
LOCAL_LIBS = @LOCAL_LIBS@
|
||||||
|
LIBS = $(BUILTINS_LIB) $(LIBRARIES) $(LOCAL_LIBS) @LIBS@
|
||||||
|
LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(PROFILE_FLAGS) $(CFLAGS)
|
||||||
|
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
|
||||||
|
|
||||||
|
SYSTEM_FLAGS = -DPROGRAM='"$(Program)"' -DHOSTTYPE='"$(Machine)"' -DOSTYPE='"$(OS)"' -DMACHTYPE='"$(MACHTYPE)"'
|
||||||
|
|
||||||
|
CCFLAGS = $(PROFILE_FLAGS) $(SYSTEM_FLAGS) -DSHELL \
|
||||||
|
$(DEFS) $(LOCAL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(CFLAGS)
|
||||||
|
|
||||||
|
INCLUDES = -I. -I$(srcdir) -I$(LIBSRC)
|
||||||
|
|
||||||
|
GCC_LINT_FLAGS = -ansi -Wall -Wshadow -Wpointer-arith -Wcast-qual \
|
||||||
|
-Wwrite-strings -Werror -Wstrict-prototypes \
|
||||||
|
-Wmissing-prototypes
|
||||||
|
GCC_LINT_CFLAGS = $(CCFLAGS) $(GCC_LINT_FLAGS)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Support libraries
|
||||||
|
#
|
||||||
|
|
||||||
|
dot = .
|
||||||
|
|
||||||
|
LIBSUBDIR = lib
|
||||||
|
LIBSRC = $(srcdir)/$(LIBSUBDIR)
|
||||||
|
|
||||||
|
SUBDIR_INCLUDES = -I. -I$(topdir) -I$(topdir)/$(LIBSUBDIR) -I$(includedir)
|
||||||
|
|
||||||
|
# we assume for now that readline source is being shipped with bash
|
||||||
|
RL_LIBSRC = $(LIBSRC)/readline
|
||||||
|
RL_LIBDOC = $(RL_LIBSRC)/doc
|
||||||
|
RL_LIBDIR = $(dot)/$(LIBSUBDIR)/readline
|
||||||
|
RL_ABSSRC = ${topdir}/$(RL_LIBDIR)
|
||||||
|
|
||||||
|
READLINE_LIB = @READLINE_LIB@
|
||||||
|
READLINE_LIBRARY = $(RL_LIBDIR)/libreadline.a
|
||||||
|
READLINE_LDFLAGS = -L${RL_LIBDIR}
|
||||||
|
READLINE_DEP = @READLINE_DEP@
|
||||||
|
|
||||||
|
# The source, object and documentation of the GNU Readline library.
|
||||||
|
READLINE_SOURCE = $(RL_LIBSRC)/rldefs.h $(RL_LIBSRC)/rlconf.h \
|
||||||
|
$(RL_LIBSRC)/readline.h $(RL_LIBSRC)/tcap.h \
|
||||||
|
$(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/keymaps.h \
|
||||||
|
$(RL_LIBSRC)/history.h $(RL_LIBSRC)/histlib.h \
|
||||||
|
$(RL_LIBSRC)/posixstat.h $(RL_LIBSRC)/tilde.h \
|
||||||
|
$(RL_LIBSRC)/funmap.c $(RL_LIBSRC)/emacs_keymap.c \
|
||||||
|
$(RL_LIBSRC)/search.c $(RL_LIBSRC)/vi_keymap.c \
|
||||||
|
$(RL_LIBSRC)/keymaps.c $(RL_LIBSRC)/parens.c \
|
||||||
|
$(RL_LIBSRC)/vi_mode.c $(RL_LIBSRC)/callback.c \
|
||||||
|
$(RL_LIBSRC)/readline.c $(RL_LIBSRC)/tilde.c \
|
||||||
|
$(RL_LIBSRC)/rltty.c $(RL_LIBSRC)/complete.c \
|
||||||
|
$(RL_LIBSRC)/bind.c $(RL_LIBSRC)/isearch.c \
|
||||||
|
$(RL_LIBSRC)/display.c $(RL_LIBSRC)/signals.c \
|
||||||
|
$(RL_LIBSRC)/util.c $(RL_LIBSRC)/kill.c \
|
||||||
|
$(RL_LIBSRC)/undo.c $(RL_LIBSRC)/macro.c \
|
||||||
|
$(RL_LIBSRC)/terminal.c $(RL_LIBSRC)/nls.c \
|
||||||
|
$(RL_LIBSRC)/input.c $(RL_LIBSRC)/xmalloc.c \
|
||||||
|
$(RL_LIBSRC)/histexpand.c $(RL_LIBSRC)/history.c \
|
||||||
|
$(RL_LIBSRC)/histsearch.c $(RL_LIBSRC)/histfile.c
|
||||||
|
|
||||||
|
READLINE_OBJ = $(RL_LIBDIR)/readline.o $(RL_LIBDIR)/funmap.o \
|
||||||
|
$(RL_LIBDIR)/parens.o $(RL_LIBDIR)/search.o \
|
||||||
|
$(RL_LIBDIR)/keymaps.o $(RL_LIBDIR)/xmalloc.o \
|
||||||
|
$(RL_LIBDIR)/rltty.o $(RL_LIBDIR)/complete.o \
|
||||||
|
$(RL_LIBDIR)/bind.o $(RL_LIBDIR)/isearch.o \
|
||||||
|
$(RL_LIBDIR)/display.o $(RL_LIBDIR)/signals.o \
|
||||||
|
$(RL_LIBDIR)/tilde.o $(RL_LIBDIR)/util.o \
|
||||||
|
$(RL_LIBDIR)/kill.o $(RL_LIBDIR)/undo.o $(RL_LIBDIR)/nls.o \
|
||||||
|
$(RL_LIBDIR)/macro.o $(RL_LIBDIR)/input.o \
|
||||||
|
$(RL_LIBDIR)/terminal.o $(RL_LIBDIR)/callback.o \
|
||||||
|
$(RL_LIBDIR)/history.o $(RL_LIBDIR)/histexpand.o \
|
||||||
|
$(RL_LIBDIR)/histsearch.o $(RL_LIBDIR)/histfile.o
|
||||||
|
|
||||||
|
HIST_LIBSRC = $(LIBSRC)/readline
|
||||||
|
HIST_LIBDIR = $(dot)/$(LIBSUBDIR)/readline
|
||||||
|
HIST_ABSSRC = ${topdir}/$(HIST_LIBDIR)
|
||||||
|
|
||||||
|
HISTORY_LIB = @HISTORY_LIB@
|
||||||
|
HISTORY_LIBRARY = $(HIST_LIBDIR)/libhistory.a
|
||||||
|
HISTORY_LDFLAGS = -L$(HIST_LIBDIR)
|
||||||
|
HISTORY_DEP = @HISTORY_DEP@
|
||||||
|
|
||||||
|
# The source, object and documentation of the history library.
|
||||||
|
HISTORY_SOURCE = $(HIST_LIBSRC)/history.c $(HIST_LIBSRC)/histexpand.c \
|
||||||
|
$(HIST_LIBSRC)/histsearch.c $(HIST_LIBSRC)/histfile.c \
|
||||||
|
$(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/histlib.h
|
||||||
|
HISTORY_OBJ = $(HIST_LIBDIR)/history.o $(HIST_LIBDIR)/histexpand.o \
|
||||||
|
$(HIST_LIBDIR)/histsearch.o $(HIST_LIBDIR)/histfile.o
|
||||||
|
|
||||||
|
# You only need termcap (or curses) if you are linking with GNU Readline.
|
||||||
|
TERM_LIBSRC = $(LIBSRC)/termcap
|
||||||
|
TERM_LIBDIR = $(dot)/$(LIBSUBDIR)/termcap
|
||||||
|
TERM_ABSSRC = ${topdir}/$(TERM_LIBDIR)
|
||||||
|
|
||||||
|
TERMCAP_LIB = @TERMCAP_LIB@
|
||||||
|
TERMCAP_LIBRARY = $(TERM_LIBDIR)/libtermcap.a
|
||||||
|
TERMCAP_LDFLAGS = -L$(TERM_LIBDIR)
|
||||||
|
TERMCAP_DEP = @TERMCAP_DEP@
|
||||||
|
|
||||||
|
TERMCAP_SOURCE = $(TERM_LIBSRC)/termcap.c $(TERM_LIBSRC)/tparam.c
|
||||||
|
TERMCAP_OBJ = $(TERM_LIBDIR)/termcap.o $(TERM_LIBDIR)/tparam.o
|
||||||
|
|
||||||
|
GLOB_LIBSRC = $(LIBSRC)/glob
|
||||||
|
GLOB_LIBDIR = $(dot)/$(LIBSUBDIR)/glob
|
||||||
|
GLOB_ABSSRC = ${topdir}/$(GLOB_LIBDIR)
|
||||||
|
|
||||||
|
GLOB_LIB = -lglob
|
||||||
|
GLOB_LIBRARY = $(GLOB_LIBDIR)/libglob.a
|
||||||
|
GLOB_LDFLAGS = -L$(GLOB_LIBDIR)
|
||||||
|
GLOB_DEP = $(GLOB_LIBRARY)
|
||||||
|
|
||||||
|
GLOB_SOURCE = $(GLOB_LIBSRC)/glob.c $(GLOB_LIBSRC)/fnmatch.c \
|
||||||
|
$(GLOB_LIBSRC)/glob.h $(GLOB_LIBSRC)/fnmatch.h
|
||||||
|
GLOB_OBJ = $(GLOB_LIBDIR)/glob.o $(GLOB_LIBDIR)/fnmatch.o
|
||||||
|
|
||||||
|
# The source, object and documentation for the GNU Tilde library.
|
||||||
|
TILDE_LIBSRC = $(LIBSRC)/tilde
|
||||||
|
TILDE_LIBDIR = $(dot)/$(LIBSUBDIR)/tilde
|
||||||
|
TILDE_ABSSRC = ${topdir}/$(TILDE_LIBDIR)
|
||||||
|
|
||||||
|
TILDE_LIB = -ltilde
|
||||||
|
TILDE_LIBRARY = $(TILDE_LIBDIR)/libtilde.a
|
||||||
|
TILDE_LDFLAGS = -L$(TILDE_LIBDIR)
|
||||||
|
TILDE_DEP = $(TILDE_LIBRARY)
|
||||||
|
|
||||||
|
TILDE_SOURCE = $(TILDE_LIBSRC)/tilde.c $(TILDE_LIBSRC)/tilde.h
|
||||||
|
TILDE_OBJ = $(TILDE_LIBDIR)/tilde.o
|
||||||
|
|
||||||
|
# Our malloc.
|
||||||
|
ALLOC_LIBSRC = $(LIBSRC)/malloc
|
||||||
|
ALLOC_LIBDIR = $(dot)/$(LIBSUBDIR)/malloc
|
||||||
|
ALLOC_ABSSRC = ${topdir}/$(ALLOC_LIBDIR)
|
||||||
|
|
||||||
|
ALLOCA_DEP = $(ALLOC_LIBDIR)/@ALLOCA@
|
||||||
|
|
||||||
|
MALLOC_OBJ = $(ALLOC_LIBDIR)/@MALLOC@
|
||||||
|
MALLOC_SRC = @MALLOC_SRC@
|
||||||
|
MALLOC_CFLAGS = -Drcheck -Dbotch=programming_error
|
||||||
|
|
||||||
|
MALLOC_LIB = -lmalloc
|
||||||
|
MALLOC_LIBRARY = $(ALLOC_LIBDIR)/libmalloc.a
|
||||||
|
MALLOC_LDFLAGS = -L$(ALLOC_LIBDIR)
|
||||||
|
MALLOC_DEP = $(MALLOC_LIBRARY)
|
||||||
|
|
||||||
|
ALLOC_HEADERS = $(ALLOC_LIBSRC)/getpagesize.h
|
||||||
|
|
||||||
|
$(MALLOC_LIBRARY): $(MALLOC_SRC)
|
||||||
|
@$(RM) $@
|
||||||
|
@(cd $(ALLOC_LIBDIR) && \
|
||||||
|
$(MAKE) $(MFLAGS) \
|
||||||
|
MALLOC_CFLAGS="$(MALLOC_CFLAGS)" libmalloc.a ) || exit 1
|
||||||
|
|
||||||
|
BASHPOSIX_LIB = $(LIBSRC)/posixheaders
|
||||||
|
BASHPOSIX_SUPPORT = $(BASHPOSIX_LIB)/posixstat.h $(BASHPOSIX_LIB)/ansi_stdlib.h \
|
||||||
|
$(BASHPOSIX_LIB)/memalloc.h $(BASHPOSIX_LIB)/stdc.h
|
||||||
|
|
||||||
|
LIBRARIES = $(READLINE_LIB) $(HISTORY_LIB) $(TERMCAP_LIB) $(GLOB_LIB) \
|
||||||
|
$(TILDE_LIB) $(MALLOC_LIB) $(LOCAL_LIBS)
|
||||||
|
|
||||||
|
LIBDEP = $(READLINE_DEP) $(TERMCAP_DEP) $(GLOB_DEP) $(HISTORY_DEP) \
|
||||||
|
$(TILDE_DEP) $(MALLOC_DEP)
|
||||||
|
|
||||||
|
LIBRARY_LDFLAGS = $(READLINE_LDFLAGS) $(HISTORY_LDFLAGS) $(TILDE_LDFLAGS) \
|
||||||
|
$(GLOB_LDFLAGS) $(MALLOC_LDFLAGS)
|
||||||
|
|
||||||
|
#
|
||||||
|
# The shell itself
|
||||||
|
#
|
||||||
|
|
||||||
|
# The main source code for the Bourne Again SHell.
|
||||||
|
CSOURCES = shell.c eval.c parse.y general.c make_cmd.c print_cmd.c y.tab.c \
|
||||||
|
dispose_cmd.c execute_cmd.c variables.c $(GLOBC) version.c \
|
||||||
|
expr.c copy_cmd.c flags.c subst.c hashlib.c mailcheck.c \
|
||||||
|
test.c trap.c jobs.c nojobs.c $(ALLOC_FILES) braces.c \
|
||||||
|
vprint.c input.c bashhist.c array.c sig.c pathexp.c oslib.c \
|
||||||
|
unwind_prot.c siglist.c getcwd.c $(RL_SUPPORT_SRC) error.c \
|
||||||
|
list.c stringlib.c locale.c xmalloc.c
|
||||||
|
|
||||||
|
HSOURCES = shell.h flags.h trap.h hashlib.h jobs.h builtins.h alias.c y.tab.h \
|
||||||
|
general.h variables.h config.h $(ALLOC_HEADERS) alias.h maxpath.h \
|
||||||
|
quit.h posixstat.h filecntl.h unwind_prot.h \
|
||||||
|
command.h input.h error.h bashansi.h dispose_cmd.h make_cmd.h \
|
||||||
|
subst.h externs.h siglist.h bashhist.h bashline.h bashtypes.h \
|
||||||
|
array.h sig.h mailcheck.h bashtty.h
|
||||||
|
|
||||||
|
SOURCES = $(CSOURCES) $(HSOURCES) $(BUILTIN_DEFS)
|
||||||
|
|
||||||
|
# object files chosen based on running of configure
|
||||||
|
JOBS_O = @JOBS_O@
|
||||||
|
|
||||||
|
# Matching object files.
|
||||||
|
OBJECTS = shell.o eval.o y.tab.o general.o make_cmd.o print_cmd.o $(GLOBO) \
|
||||||
|
dispose_cmd.o execute_cmd.o variables.o copy_cmd.o error.o \
|
||||||
|
expr.o flags.o $(JOBS_O) subst.o hashlib.o mailcheck.o test.o \
|
||||||
|
trap.o input.o unwind_prot.o pathexp.o sig.o version.o \
|
||||||
|
alias.o array.o braces.o bracecomp.o bashhist.o bashline.o \
|
||||||
|
getcwd.o siglist.o vprint.o oslib.o list.o stringlib.o \
|
||||||
|
locale.o xmalloc.o
|
||||||
|
|
||||||
|
# Where the source code of the shell builtins resides.
|
||||||
|
BUILTIN_SRCDIR=$(srcdir)/builtins
|
||||||
|
DEFSRC=$(BUILTIN_SRCDIR)
|
||||||
|
BUILTIN_ABSSRC=${topdir}/builtins
|
||||||
|
DEFDIR = $(dot)/builtins
|
||||||
|
|
||||||
|
BUILTIN_DEFS = $(DEFSRC)/alias.def $(DEFSRC)/bind.def $(DEFSRC)/break.def \
|
||||||
|
$(DEFSRC)/builtin.def $(DEFSRC)/cd.def $(DEFSRC)/colon.def \
|
||||||
|
$(DEFSRC)/command.def $(DEFSRC)/declare.def \
|
||||||
|
$(DEFSRC)/echo.def $(DEFSRC)/enable.def $(DEFSRC)/eval.def \
|
||||||
|
$(DEFSRC)/exec.def $(DEFSRC)/exit.def $(DEFSRC)/fc.def \
|
||||||
|
$(DEFSRC)/fg_bg.def $(DEFSRC)/hash.def $(DEFSRC)/help.def \
|
||||||
|
$(DEFSRC)/history.def $(DEFSRC)/jobs.def $(DEFSRC)/kill.def \
|
||||||
|
$(DEFSRC)/let.def $(DEFSRC)/read.def $(DEFSRC)/return.def \
|
||||||
|
$(DEFSRC)/set.def $(DEFSRC)/setattr.def $(DEFSRC)/shift.def \
|
||||||
|
$(DEFSRC)/source.def $(DEFSRC)/suspend.def $(DEFSRC)/test.def \
|
||||||
|
$(DEFSRC)/times.def $(DEFSRC)/trap.def $(DEFSRC)/type.def \
|
||||||
|
$(DEFSRC)/ulimit.def $(DEFSRC)/umask.def $(DEFSRC)/wait.def \
|
||||||
|
$(DEFSRC)/getopts.def $(DEFSRC)/reserved.def \
|
||||||
|
$(DEFSRC)/pushd.def $(DEFSRC)/shopt.def
|
||||||
|
BUILTIN_C_SRC = $(DEFSRC)/mkbuiltins.c $(DEFSRC)/common.c \
|
||||||
|
$(DEFSRC)/evalstring.c $(DEFSRC)/evalfile.c \
|
||||||
|
$(DEFSRC)/bashgetopt.c $(GETOPT_SOURCE) \
|
||||||
|
$(DEFSRC)/hashcom.h
|
||||||
|
BUILTIN_C_OBJ = $(DEFDIR)/common.o $(DEFDIR)/evalstring.o \
|
||||||
|
$(DEFDIR)/evalfile.o $(DEFDIR)/bashgetopt.o
|
||||||
|
BUILTIN_OBJS = $(DEFDIR)/alias.o $(DEFDIR)/bind.o $(DEFDIR)/break.o \
|
||||||
|
$(DEFDIR)/builtin.o $(DEFDIR)/cd.o $(DEFDIR)/colon.o \
|
||||||
|
$(DEFDIR)/command.o $(DEFDIR)/declare.o \
|
||||||
|
$(DEFDIR)/echo.o $(DEFDIR)/enable.o $(DEFDIR)/eval.o \
|
||||||
|
$(DEFDIR)/exec.o $(DEFDIR)/exit.o $(DEFDIR)/fc.o \
|
||||||
|
$(DEFDIR)/fg_bg.o $(DEFDIR)/hash.o $(DEFDIR)/help.o \
|
||||||
|
$(DEFDIR)/history.o $(DEFDIR)/jobs.o $(DEFDIR)/kill.o \
|
||||||
|
$(DEFDIR)/let.o $(DEFDIR)/pushd.o $(DEFDIR)/read.o \
|
||||||
|
$(DEFDIR)/return.o $(DEFDIR)/shopt.o \
|
||||||
|
$(DEFDIR)/set.o $(DEFDIR)/setattr.o $(DEFDIR)/shift.o \
|
||||||
|
$(DEFDIR)/source.o $(DEFDIR)/suspend.o $(DEFDIR)/test.o \
|
||||||
|
$(DEFDIR)/times.o $(DEFDIR)/trap.o $(DEFDIR)/type.o \
|
||||||
|
$(DEFDIR)/ulimit.o $(DEFDIR)/umask.o $(DEFDIR)/wait.o \
|
||||||
|
$(DEFDIR)/getopts.o $(BUILTIN_C_OBJ)
|
||||||
|
GETOPT_SOURCE = $(DEFSRC)/getopt.c $(DEFSRC)/getopt.h
|
||||||
|
PSIZE_SOURCE = $(DEFSRC)/psize.sh $(DEFSRC)/psize.c
|
||||||
|
|
||||||
|
BUILTINS_LIBRARY = builtins/libbuiltins.a
|
||||||
|
BUILTINS_LIB = -lbuiltins
|
||||||
|
BUILTINS_LDFLAGS = -L$(DEFDIR)
|
||||||
|
BUILTINS_DEP = $(BUILTINS_LIBRARY)
|
||||||
|
|
||||||
|
# Documentation for the shell.
|
||||||
|
DOCSRC = $(srcdir)/doc
|
||||||
|
DOCDIR = ./doc
|
||||||
|
|
||||||
|
SIGNAMES_SUPPORT = $(SUPPORT_SRC)mksignames.c
|
||||||
|
|
||||||
|
SUPPORT_SRC = $(srcdir)/support/
|
||||||
|
SDIR = ./support/
|
||||||
|
|
||||||
|
CREATED_SUPPORT = signames.h recho zecho tests/recho tests/zecho \
|
||||||
|
tests/printenv mksignames mkversion
|
||||||
|
CREATED_CONFIGURE = config.h config.cache config.status config.log \
|
||||||
|
stamp-h
|
||||||
|
CREATED_MAKEFILES = Makefile builtins/Makefile doc/Makefile \
|
||||||
|
lib/readline/Makefile lib/glob/Makefile \
|
||||||
|
lib/tilde/Makefile lib/malloc/Makefile \
|
||||||
|
lib/termcap/Makefile
|
||||||
|
|
||||||
|
# Keep GNU Make from exporting the entire environment for small machines.
|
||||||
|
.NOEXPORT:
|
||||||
|
|
||||||
|
.made: $(Program) bashbug
|
||||||
|
cp .machine .made
|
||||||
|
|
||||||
|
$(Program): .build $(OBJECTS) $(BUILTINS_DEP) $(LIBDEP) $(srcdir)/.distribution
|
||||||
|
$(RM) $@
|
||||||
|
$(PURIFY) $(CC) $(LDFLAGS) $(BUILTINS_LDFLAGS) $(LIBRARY_LDFLAGS) -o $(Program) $(OBJECTS) $(LIBS)
|
||||||
|
ls -l $(Program)
|
||||||
|
size $(Program)
|
||||||
|
|
||||||
|
.build: $(SOURCES) config.h Makefile mkversion version.h .machine
|
||||||
|
@echo
|
||||||
|
@echo " ***********************************************************"
|
||||||
|
@echo " * *"
|
||||||
|
@echo " * Making Bash-`cat $(srcdir)/.distribution`.`cat $(srcdir)/.patchlevel`-$(RELSTATUS) for a $(Machine) running $(OS)"
|
||||||
|
@echo " * *"
|
||||||
|
@echo " ***********************************************************"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
.machine: $(SOURCES) config.h Makefile mkversion version.h
|
||||||
|
@echo "$(Program) last made for a $(Machine) running $(OS)" >.machine
|
||||||
|
|
||||||
|
bashbug: $(SUPPORT_SRC)bashbug.sh mkversion config.h Makefile
|
||||||
|
@sed -e "s:!MACHINE!:$(Machine):" -e "s:!OS!:$(OS):" \
|
||||||
|
-e "s:!CFLAGS!:$(CCFLAGS):" -e "s:!CC!:$(CC):" \
|
||||||
|
-e "s:!RELEASE!:`cat $(srcdir)/.distribution`:" \
|
||||||
|
-e "s:!PATCHLEVEL!:`cat $(srcdir)/.patchlevel`:" \
|
||||||
|
-e "s:!MACHTYPE!:$(MACHTYPE):" -e "s:!RELSTATUS!:$(RELSTATUS):" \
|
||||||
|
$(SUPPORT_SRC)bashbug.sh > $@
|
||||||
|
@chmod a+rx bashbug
|
||||||
|
|
||||||
|
strip: $(Program) .made
|
||||||
|
strip $(Program)
|
||||||
|
ls -l $(Program)
|
||||||
|
size $(Program)
|
||||||
|
|
||||||
|
version.h: $(SOURCES) config.h Makefile mkversion .patchlevel .distribution
|
||||||
|
if ./mkversion -dir $(srcdir) -build -status $(RELSTATUS); then mv -f newversion.h version.h; fi
|
||||||
|
|
||||||
|
# old rules
|
||||||
|
y.tab.o: y.tab.c parser-built
|
||||||
|
y.tab.c: parser-built
|
||||||
|
y.tab.h: parser-built
|
||||||
|
parser-built: parse.y command.h stdc.h input.h
|
||||||
|
$(RM) $@
|
||||||
|
-if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi
|
||||||
|
$(YACC) -d $(srcdir)/parse.y
|
||||||
|
-if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; fi
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
# experimental new rules - work with GNU make but not BSD (or OSF) make
|
||||||
|
#y.tab.o: y.tab.c y.tab.h
|
||||||
|
#y.tab.c y.tab.h: parse.y command.h stdc.h input.h
|
||||||
|
# -if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi
|
||||||
|
# $(YACC) -d $(srcdir)/parse.y
|
||||||
|
# -if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; fi
|
||||||
|
|
||||||
|
$(READLINE_LIBRARY): config.h $(READLINE_SOURCE)
|
||||||
|
@echo making $@ in ${RL_LIBDIR}
|
||||||
|
@(cd ${RL_LIBDIR} && \
|
||||||
|
$(MAKE) $(MFLAGS) APP_CFLAGS=-DSHELL libreadline.a) || exit 1
|
||||||
|
|
||||||
|
$(HISTORY_LIBRARY): config.h $(HISTORY_SOURCE)
|
||||||
|
@echo making $@ in ${HIST_LIBDIR}
|
||||||
|
@(cd ${HIST_LIBDIR} && \
|
||||||
|
$(MAKE) $(MFLAGS) libhistory.a) || exit 1
|
||||||
|
|
||||||
|
$(GLOB_LIBRARY): config.h $(GLOB_SOURCE)
|
||||||
|
@echo making $@ in ${GLOB_LIBDIR}
|
||||||
|
@(cd ${GLOB_LIBDIR} && \
|
||||||
|
$(MAKE) $(MFLAGS) libglob.a) || exit 1
|
||||||
|
|
||||||
|
$(TILDE_LIBRARY): config.h $(TILDE_SOURCE)
|
||||||
|
@echo making $@ in ${TILDE_LIBDIR}
|
||||||
|
@(cd ${TILDE_LIBDIR} && \
|
||||||
|
$(MAKE) $(MFLAGS) libtilde.a) || exit 1
|
||||||
|
|
||||||
|
$(TERMCAP_LIBRARY): config.h ${TERMCAP_SOURCE}
|
||||||
|
@echo making $@ in ${TERMCAP_LIBDIR}
|
||||||
|
@(cd ${TERMCAP_LIBDIR} && \
|
||||||
|
$(MAKE) $(MFLAGS) libtermcap.a) || exit 1
|
||||||
|
|
||||||
|
mksignames: $(SUPPORT_SRC)mksignames.c
|
||||||
|
$(CC) $(CCFLAGS) $(CPPFLAGS) -o $@ $(SUPPORT_SRC)mksignames.c
|
||||||
|
|
||||||
|
signames.h: mksignames
|
||||||
|
$(RM) $@
|
||||||
|
./mksignames $@
|
||||||
|
|
||||||
|
$(BUILTINS_LIBRARY): $(BUILTIN_DEFS) $(BUILTIN_C_SRC) config.h memalloc.h
|
||||||
|
@(cd $(DEFDIR) && $(MAKE) $(MFLAGS) libbuiltins.a ) || exit 1
|
||||||
|
|
||||||
|
# these require special rules to circumvent make builtin rules
|
||||||
|
builtins/common.o: $(BUILTIN_SRCDIR)/common.c
|
||||||
|
@(cd $(DEFDIR) && $(MAKE) $(MFLAGS) common.o) || exit 1
|
||||||
|
|
||||||
|
builtins/bashgetopt.o: $(BUILTIN_SRCDIR)/bashgetopt.c
|
||||||
|
@(cd $(DEFDIR) && $(MAKE) $(MFLAGS) bashgetopt.o) || exit 1
|
||||||
|
|
||||||
|
builtins/builtext.h: $(BUILTIN_DEFS)
|
||||||
|
@(cd $(DEFDIR) && $(MAKE) $(MFLAGS) builtext.h ) || exit 1
|
||||||
|
|
||||||
|
# For the justification of the following Makefile rules, see node
|
||||||
|
# `Automatic Remaking' in GNU Autoconf documentation.
|
||||||
|
|
||||||
|
Makefile: config.status $(srcdir)/Makefile.in
|
||||||
|
CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||||
|
|
||||||
|
Makefiles makefiles: config.status $(srcdir)/Makefile.in
|
||||||
|
@for mf in $(CREATED_MAKEFILES); do \
|
||||||
|
CONFIG_FILES=$$mf CONFIG_HEADERS= $(SHELL) ./config.status ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
config.h: stamp-h
|
||||||
|
|
||||||
|
stamp-h: config.status $(srcdir)/config.h.in $(srcdir)/config.h.top $(srcdir)/config.h.bot
|
||||||
|
CONFIG_FILES= CONFIG_HEADERS=config.h $(SHELL) ./config.status
|
||||||
|
|
||||||
|
config.status: $(srcdir)/configure
|
||||||
|
$(SHELL) ./config.status --recheck
|
||||||
|
|
||||||
|
# comment out for distribution
|
||||||
|
#$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4
|
||||||
|
# cd $(srcdir) && autoconf
|
||||||
|
|
||||||
|
mkversion: $(SUPPORT_SRC)mkversion.c
|
||||||
|
$(CC) $(CCFLAGS) -I.. -o $@ $(SUPPORT_SRC)mkversion.c
|
||||||
|
|
||||||
|
newversion: mkversion
|
||||||
|
$(RM) .build
|
||||||
|
./mkversion -dir $(srcdir) -dist
|
||||||
|
mv -f newversion.h version.h
|
||||||
|
$(MAKE) -f $(srcdir)/Makefile $(MFLAGS) srcdir=$(srcdir)
|
||||||
|
|
||||||
|
doc documentation: force
|
||||||
|
@(cd $(DOCDIR) ; $(MAKE) $(MFLAGS) )
|
||||||
|
|
||||||
|
info dvi ps: force
|
||||||
|
@(cd $(DOCDIR) ; $(MAKE) $(MFLAGS) CFLAGS='$(CCFLAGS)' $@ )
|
||||||
|
|
||||||
|
force:
|
||||||
|
|
||||||
|
tags: $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE)
|
||||||
|
etags $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE)
|
||||||
|
|
||||||
|
TAGS: $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE)
|
||||||
|
ctags -x $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE) > $@
|
||||||
|
|
||||||
|
# Targets that actually do things not part of the build
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
@${SHELL} $(SUPPORT_SRC)mkdirs $(bindir)
|
||||||
|
@${SHELL} $(SUPPORT_SRC)mkdirs $(man1dir) $(man3dir)
|
||||||
|
@${SHELL} $(SUPPORT_SRC)mkdirs $(infodir)
|
||||||
|
|
||||||
|
install: .made installdirs
|
||||||
|
$(INSTALL_PROGRAM) $(Program) $(bindir)/$(Program)
|
||||||
|
$(INSTALL_PROGRAM) bashbug $(bindir)/bashbug
|
||||||
|
-( cd $(DOCDIR) ; $(MAKE) $(MFLAGS) \
|
||||||
|
man1dir=$(man1dir) man1ext=$(man1ext) \
|
||||||
|
man3dir=$(man3dir) man3ext=$(man3ext) \
|
||||||
|
infodir=$(infodir) $@ )
|
||||||
|
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(MFLAGS) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \
|
||||||
|
prefix=${prefix} exec_prefix=${exec_prefix} install
|
||||||
|
|
||||||
|
uninstall: .made
|
||||||
|
$(RM) $(bindir)/$(Program) $(bindir)/bashbug
|
||||||
|
-( cd $(DOCDIR) ; $(MAKE) $(MFLAGS) \
|
||||||
|
man1dir=$(man1dir) man1ext=$(man1ext) \
|
||||||
|
man3dir=$(man3dir) man3ext=$(man3ext) \
|
||||||
|
infodir=$(infodir) $@ )
|
||||||
|
|
||||||
|
.PHONY: basic-clean clean realclean maintainer-clean distclean mostlyclean
|
||||||
|
basic-clean:
|
||||||
|
$(RM) $(OBJECTS) $(Program) bashbug
|
||||||
|
$(RM) .build .made .machine version.h
|
||||||
|
|
||||||
|
clean: basic-clean
|
||||||
|
( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ )
|
||||||
|
( cd builtins && $(MAKE) $(MFLAGS) $@ )
|
||||||
|
-(cd $(RL_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(HIST_LIBDIR) && test -f Makefile && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(TERM_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(GLOB_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(TILDE_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(ALLOC_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
$(RM) $(CREATED_SUPPORT)
|
||||||
|
|
||||||
|
mostlyclean: basic-clean
|
||||||
|
( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ )
|
||||||
|
( cd builtins && $(MAKE) $(MFLAGS) $@ )
|
||||||
|
-(cd $(RL_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(HIST_LIBDIR) && test -f Makefile && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(TERM_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(GLOB_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(TILDE_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(ALLOC_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
|
||||||
|
distclean: basic-clean
|
||||||
|
( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ )
|
||||||
|
( cd builtins && $(MAKE) $(MFLAGS) $@ )
|
||||||
|
-(cd $(RL_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(HIST_LIBDIR) && test -f Makefile && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(TERM_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(GLOB_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(TILDE_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(ALLOC_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
$(RM) $(CREATED_CONFIGURE) tags TAGS
|
||||||
|
$(RM) $(CREATED_SUPPORT) Makefile $(CREATED_MAKEFILES)
|
||||||
|
|
||||||
|
maintainer-clean: basic-clean
|
||||||
|
@echo This command is intended for maintainers to use.
|
||||||
|
@echo It deletes files that may require special tools to rebuild.
|
||||||
|
$(RM) y.tab.c y.tab.h parser-built tags TAGS
|
||||||
|
( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ )
|
||||||
|
( cd builtins && $(MAKE) $(MFLAGS) $@ )
|
||||||
|
-(cd $(RL_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(HIST_LIBDIR) && test -f Makefile && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(TERM_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(GLOB_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(TILDE_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
-(cd $(ALLOC_LIBDIR) && $(MAKE) $(MFLAGS) $@)
|
||||||
|
$(RM) $(CREATED_CONFIGURE) $(CREATED_MAKEFILES)
|
||||||
|
$(RM) $(CREATED_SUPPORT) Makefile
|
||||||
|
|
||||||
|
recho: $(SUPPORT_SRC)recho.c
|
||||||
|
@$(CC) -o $@ $(SUPPORT_SRC)recho.c
|
||||||
|
|
||||||
|
zecho: $(SUPPORT_SRC)zecho.c
|
||||||
|
@$(CC) -o $@ $(SUPPORT_SRC)zecho.c
|
||||||
|
|
||||||
|
tests check: force $(Program) recho zecho
|
||||||
|
@-test -d tests || mkdir tests
|
||||||
|
@cp recho zecho $(SUPPORT_SRC)printenv tests
|
||||||
|
@( cd $(srcdir)/tests && \
|
||||||
|
PATH=$$PATH:$(BUILD_DIR)/tests THIS_SH=$(THIS_SH) sh run-all )
|
||||||
|
|
||||||
|
symlinks:
|
||||||
|
$(SHELL) $(SUPPORT_SRC)fixlinks -s $(srcdir)
|
||||||
|
|
||||||
|
dist: force
|
||||||
|
@echo Bash distributions are created using $(srcdir)/support/mkdist.
|
||||||
|
@echo Here is a sample of the necessary commands:
|
||||||
|
@echo $(Program) $(srcdir)/support/mkdist -m $(srcdir)/MANIFEST -s $(srcdir) -r ${Program} `cat $(srcdir)/.distribution`
|
||||||
|
@echo tar cf $(Program)-`cat $(srcdir)/.distribution`.tar ${Program}-`cat $(srcdir)/.distribution`
|
||||||
|
@echo gzip $(Program)-`cat $(srcdir)/.distribution`.tar
|
||||||
|
|
||||||
|
############################ DEPENDENCIES ###############################
|
||||||
|
|
||||||
|
# Files that depend on the definitions in config.h.top, which are not meant
|
||||||
|
# to be changed
|
||||||
|
shell.o: config.h.top
|
||||||
|
input.o: config.h.top
|
||||||
|
y.tab.o: config.h.top
|
||||||
|
jobs.o: config.h.top
|
||||||
|
nojobs.o: config.h.top
|
||||||
|
execute_cmd.o: config.h.top
|
||||||
|
builtins/break.o: config.h.top
|
||||||
|
builtins/common.o: config.h.top
|
||||||
|
builtins/echo.o: config.h.top
|
||||||
|
variables.o: config.h.top
|
||||||
|
builtins/command.o: config.h.top
|
||||||
|
|
||||||
|
copy_cmd.o: shell.h bashjmp.h sig.h command.h stdc.h hashlib.h
|
||||||
|
copy_cmd.o: general.h variables.h config.h memalloc.h quit.h
|
||||||
|
copy_cmd.o: dispose_cmd.h make_cmd.h subst.h externs.h
|
||||||
|
dispose_cmd.o: shell.h bashjmp.h sig.h command.h stdc.h
|
||||||
|
dispose_cmd.o: general.h variables.h config.h memalloc.h quit.h
|
||||||
|
dispose_cmd.o: dispose_cmd.h make_cmd.h subst.h externs.h
|
||||||
|
error.o: error.h
|
||||||
|
execute_cmd.o: shell.h bashjmp.h sig.h command.h stdc.h y.tab.h posixstat.h
|
||||||
|
execute_cmd.o: general.h variables.h config.h memalloc.h quit.h hashlib.h jobs.h
|
||||||
|
execute_cmd.o: unwind_prot.h siglist.h builtins/builtext.h config.h flags.h
|
||||||
|
execute_cmd.o: dispose_cmd.h make_cmd.h subst.h externs.h bashtypes.h
|
||||||
|
execute_cmd.o: pathexp.h
|
||||||
|
expr.o: shell.h bashjmp.h sig.h command.h stdc.h hashlib.h
|
||||||
|
expr.o: general.h variables.h config.h memalloc.h quit.h
|
||||||
|
expr.o: dispose_cmd.h make_cmd.h subst.h externs.h
|
||||||
|
flags.o: flags.h stdc.h config.h memalloc.h general.h quit.h
|
||||||
|
general.o: shell.h bashjmp.h sig.h command.h stdc.h maxpath.h
|
||||||
|
general.o: general.h variables.h config.h memalloc.h quit.h unwind_prot.h
|
||||||
|
general.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
getcwd.o: config.h config.h.bot bashtypes.h maxpath.h posixstat.h
|
||||||
|
hashlib.o: shell.h bashjmp.h sig.h command.h stdc.h hashlib.h
|
||||||
|
hashlib.o: general.h variables.h config.h memalloc.h quit.h
|
||||||
|
hashlib.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
jobs.o: shell.h bashjmp.h sig.h command.h stdc.h hashlib.h trap.h jobs.h
|
||||||
|
jobs.o: general.h variables.h config.h memalloc.h quit.h bashtty.h siglist.h
|
||||||
|
jobs.o: dispose_cmd.h make_cmd.h subst.h externs.h builtins/builtext.h
|
||||||
|
jobs.o: unwind_prot.h
|
||||||
|
mailcheck.o: posixstat.h maxpath.h variables.h
|
||||||
|
mailcheck.o: hashlib.h quit.h mailcheck.h
|
||||||
|
make_cmd.o: shell.h bashjmp.h sig.h command.h stdc.h flags.h input.h
|
||||||
|
make_cmd.o: general.h variables.h config.h memalloc.h quit.h bashtypes.h
|
||||||
|
make_cmd.o: dispose_cmd.h make_cmd.h subst.h externs.h
|
||||||
|
y.tab.o: shell.h bashjmp.h sig.h command.h stdc.h flags.h maxpath.h alias.h
|
||||||
|
y.tab.o: general.h variables.h config.h memalloc.h quit.h mailcheck.h parser.h
|
||||||
|
y.tab.o: dispose_cmd.h make_cmd.h subst.h externs.h bashtypes.h bashline.h
|
||||||
|
y.tab.o: builtins/builtext.h
|
||||||
|
print_cmd.o: shell.h bashjmp.h sig.h command.h stdc.h y.tab.h
|
||||||
|
print_cmd.o: general.h variables.h config.h memalloc.h quit.h
|
||||||
|
print_cmd.o: dispose_cmd.h make_cmd.h subst.h externs.h unwind_prot.h
|
||||||
|
shell.o: shell.h bashjmp.h sig.h command.h stdc.h flags.h stdc.h
|
||||||
|
shell.o: general.h variables.h config.h memalloc.h quit.h
|
||||||
|
shell.o: dispose_cmd.h make_cmd.h subst.h externs.h mailcheck.h
|
||||||
|
shell.o: posixstat.h filecntl.h jobs.h input.h
|
||||||
|
subst.o: shell.h bashjmp.h sig.h command.h stdc.h flags.h jobs.h siglist.h
|
||||||
|
subst.o: general.h variables.h config.h memalloc.h quit.h bashtypes.h
|
||||||
|
subst.o: dispose_cmd.h make_cmd.h subst.h externs.h execute_cmd.h
|
||||||
|
subst.o: ${DEFSRC}/getopt.h pathexp.h bashline.h
|
||||||
|
pathexp.o: config.h shell.h bashjmp.h command.h stdc.h general.h
|
||||||
|
pathexp.o: error.h variables.h quit.h maxpath.h unwind_prot.h dispose_cmd.h
|
||||||
|
pathexp.o: make_cmd.h subst.h sig.h pathnames.h externs.h
|
||||||
|
pathexp.o: $(GLOB_LIBSRC)/glob.h $(GLOB_LIBSRC)/fnmatch.h
|
||||||
|
test.o: posixstat.h
|
||||||
|
trap.o: trap.h shell.h bashjmp.h sig.h command.h stdc.h hashlib.h unwind_prot.h
|
||||||
|
trap.o: general.h variables.h config.h memalloc.h quit.h signames.h
|
||||||
|
trap.o: dispose_cmd.h make_cmd.h subst.h externs.h
|
||||||
|
unwind_prot.o: config.h memalloc.h general.h unwind_prot.h sig.h
|
||||||
|
variables.o: shell.h bashjmp.h sig.h command.h stdc.h hashlib.h flags.h
|
||||||
|
variables.o: config.h memalloc.h general.h variables.h quit.h mailcheck.h
|
||||||
|
variables.o: execute_cmd.h dispose_cmd.h make_cmd.h subst.h externs.h
|
||||||
|
sig.o: shell.h bashjmp.h sig.h command.h stdc.h hashlib.h flags.h
|
||||||
|
sig.o: config.h memalloc.h general.h variables.h quit.h
|
||||||
|
sig.o: bashtypes.h jobs.h bashline.h unwind_prot.h
|
||||||
|
version.o: version.h .build
|
||||||
|
oslib.o: config.h bashtypes.h posixstat.h filecntl.h bashansi.h maxpath.h
|
||||||
|
oslib.o: shell.h bashjmp.h sig.h command.h stdc.h mailcheck.h
|
||||||
|
oslib.o: general.h error.h variables.h quit.h unwind_prot.h dispose_cmd.h
|
||||||
|
oslib.o: make_cmd.h subst.h pathnames.h externs.h
|
||||||
|
xmalloc.o: config.h ansi_stdlib.h general.h error.h
|
||||||
|
|
||||||
|
eval.o: config.h bashansi.h shell.h trap.h flags.h builtins/common.h
|
||||||
|
eval.o: input.h execute_cmd.h
|
||||||
|
eval.o: bashjmp.h command.h general.h error.h variables.h quit.h
|
||||||
|
eval.o: maxpath.h unwind_prot.h dispose_cmd.h make_cmd.h subst.h
|
||||||
|
eval.o: sig.h pathnames.h externs.h
|
||||||
|
|
||||||
|
locale.o: bashintl.h bashansi.h config.h bashtypes.h shell.h
|
||||||
|
locale.o: bashjmp.h command.h general.h error.h variables.h quit.h
|
||||||
|
locale.o: maxpath.h unwind_prot.h dispose_cmd.h make_cmd.h subst.h
|
||||||
|
locale.o: sig.h pathnames.h externs.h
|
||||||
|
|
||||||
|
|
||||||
|
alias.o: ansi_stdlib.h
|
||||||
|
bashline.o: ansi_stdlib.h
|
||||||
|
variables.o: ansi_stdlib.h
|
||||||
|
shell.o: ansi_stdlib.h
|
||||||
|
error.o: ansi_stdlib.h
|
||||||
|
hash.o: ansi_stdlib.h
|
||||||
|
signames.o: ansi_stdlib.h
|
||||||
|
expr.o: ansi_stdlib.h
|
||||||
|
general.o: ansi_stdlib.h
|
||||||
|
input.o: ansi_stdlib.h
|
||||||
|
|
||||||
|
jobs.o: jobs.c
|
||||||
|
nojobs.o: nojobs.c
|
||||||
|
|
||||||
|
array.o: general.h shell.h bashjmp.h sig.h variables.h quit.h config.h
|
||||||
|
array.o: command.h error.h maxpath.h unwind_prot.h dispose_cmd.h memalloc.h
|
||||||
|
array.o: make_cmd.h subst.h externs.h
|
||||||
|
array.o: array.h stdc.h $(DEFSRC)/common.h
|
||||||
|
|
||||||
|
braces.o: general.h shell.h bashjmp.h sig.h variables.h quit.h config.h
|
||||||
|
braces.o: dispose_cmd.h make_cmd.h subst.h externs.h memalloc.h
|
||||||
|
braces.o: maxpath.h unwind_prot.h command.h stdc.h
|
||||||
|
|
||||||
|
bracecomp.o: bracecomp.c
|
||||||
|
bracecomp.o: shell.h bashjmp.h sig.h command.h hashlib.h builtins.h general.h
|
||||||
|
bracecomp.o: quit.h alias.h config.h variables.h
|
||||||
|
bracecomp.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
bracecomp.o: $(RL_LIBSRC)/readline.h
|
||||||
|
|
||||||
|
bashline.o: shell.h bashjmp.h sig.h command.h stdc.h hashlib.h builtins.h
|
||||||
|
bashline.o: general.h variables.h config.h memalloc.h quit.h alias.h
|
||||||
|
bashline.o: dispose_cmd.h make_cmd.h subst.h externs.h config.h bashline.h
|
||||||
|
bashline.o: $(GLOB_LIBSRC)/glob.h pathexp.h execute_cmd.h
|
||||||
|
|
||||||
|
bashhist.o: config.h bashansi.h posixstat.h filecntl.h parser.h
|
||||||
|
bashhist.o: shell.h bashjmp.h sig.h command.h stdc.h hashlib.h builtins.h
|
||||||
|
bashhist.o: general.h variables.h memalloc.h quit.h alias.h execute_cmd.h
|
||||||
|
bashhist.o: dispose_cmd.h make_cmd.h subst.h externs.h flags.h
|
||||||
|
|
||||||
|
bashline.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h
|
||||||
|
bashline.o: $(RL_LIBSRC)/keymaps.h
|
||||||
|
y.tab.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/chardefs.h
|
||||||
|
y.tab.o: $(RL_LIBSRC)/readline.h
|
||||||
|
|
||||||
|
subst.o: $(HIST_LIBSRC)/history.h
|
||||||
|
bashline.o: $(HIST_LIBSRC)/history.h
|
||||||
|
bashhist.o: $(HIST_LIBSRC)/history.h
|
||||||
|
y.tab.o: $(HIST_LIBSRC)/history.h
|
||||||
|
|
||||||
|
subst.o: $(GLOB_LIBSRC)/fnmatch.h
|
||||||
|
execute_cmd.o: $(GLOB_LIBSRC)/fnmatch.h
|
||||||
|
bashhist.o: $(GLOB_LIBSRC)/fnmatch.h
|
||||||
|
|
||||||
|
execute_cmd.o: $(TILDE_LIBSRC)/tilde.h
|
||||||
|
general.o: $(TILDE_LIBSRC)/tilde.h
|
||||||
|
mailcheck.o: $(TILDE_LIBSRC)/tilde.h
|
||||||
|
shell.o: $(TILDE_LIBSRC)/tilde.h
|
||||||
|
subst.o: $(TILDE_LIBSRC)/tilde.h
|
||||||
|
variables.o: $(TILDE_LIBSRC)/tilde.h
|
||||||
|
|
||||||
|
builtins/common.o: shell.h bashjmp.h sig.h command.h config.h memalloc.h
|
||||||
|
builtins/common.o: variables.h input.h $(DEFSRC)/hashcom.h siglist.h
|
||||||
|
builtins/common.o: quit.h unwind_prot.h maxpath.h jobs.h builtins.h
|
||||||
|
builtins/common.o: dispose_cmd.h make_cmd.h subst.h externs.h bashhist.h
|
||||||
|
builtins/common.o: execute_cmd.h stdc.h general.h error.h unwind_prot.h
|
||||||
|
builtins/alias.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/alias.o: quit.h $(DEFSRC)/common.h
|
||||||
|
builtins/alias.o: shell.h bashjmp.h sig.h command.h stdc.h unwind_prot.h
|
||||||
|
builtins/alias.o: dispose_cmd.h make_cmd.h subst.h externs.h variables.h
|
||||||
|
builtins/bind.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/bind.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/bind.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/bind.o: $(DEFSRC)/bashgetopt.h
|
||||||
|
builtins/break.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/break.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/break.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/builtin.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/builtin.o: quit.h $(DEFSRC)/common.h
|
||||||
|
builtins/builtin.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/builtin.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/cd.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/cd.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/cd.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/cd.o: $(DEFSRC)/common.h quit.h
|
||||||
|
builtins/command.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/command.o: quit.h $(DEFSRC)/bashgetopt.h
|
||||||
|
builtins/command.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/command.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/declare.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/declare.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/declare.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/echo.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/echo.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/echo.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/enable.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/enable.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/enable.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/eval.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/eval.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/eval.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/exec.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/exec.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/exec.o: dispose_cmd.h make_cmd.h subst.h externs.h execute_cmd.h
|
||||||
|
builtins/exec.o: flags.h quit.h $(DEFSRC)/common.h stdc.h
|
||||||
|
builtins/exit.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/exit.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/exit.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/fc.o: builtins.h command.h stdc.h
|
||||||
|
builtins/fc.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/fc.o: flags.h unwind_prot.h variables.h shell.h bashjmp.h sig.h
|
||||||
|
builtins/fc.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h quit.h
|
||||||
|
builtins/fc.o: $(DEFSRC)/bashgetopt.h bashhist.h
|
||||||
|
builtins/fg_bg.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/fg_bg.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/fg_bg.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/getopts.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/getopts.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/getopts.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/hash.o: builtins.h command.h execute_cmd.h stdc.h $(DEFSRC)/common.h
|
||||||
|
builtins/hash.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/hash.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/help.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/help.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/help.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/help.o: $(GLOB_LIBSRC)/glob.h
|
||||||
|
builtins/history.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/history.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/history.o: filecntl.h shell.h bashjmp.h sig.h unwind_prot.h
|
||||||
|
builtins/history.o: bashhist.h variables.h
|
||||||
|
builtins/inlib.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/inlib.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h quit.h
|
||||||
|
builtins/inlib.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/jobs.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/jobs.o: quit.h $(DEFSRC)/bashgetopt.h
|
||||||
|
builtins/jobs.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/jobs.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/kill.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/kill.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/kill.o: shell.h bashjmp.h sig.h trap.h unwind_prot.h variables.h
|
||||||
|
builtins/let.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/let.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/let.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/pushd.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/pushd.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/pushd.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/pushd.o: $(DEFSRC)/common.h
|
||||||
|
builtins/read.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/read.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/read.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/return.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/return.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/return.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/set.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/set.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/set.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h flags.h
|
||||||
|
builtins/setattr.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/setattr.o: quit.h $(DEFSRC)/common.h $(DEFSRC)/bashgetopt.h
|
||||||
|
builtins/setattr.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/setattr.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/shift.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/shift.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/shift.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/shift.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/source.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/source.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/source.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/suspend.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/suspend.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/suspend.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/test.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/test.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/test.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/times.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/times.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/times.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/trap.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/trap.o: quit.h $(DEFSRC)/common.h
|
||||||
|
builtins/trap.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/trap.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/type.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/type.o: quit.h $(DEFSRC)/common.h execute_cmd.h
|
||||||
|
builtins/type.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/type.o: dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/ulimit.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/ulimit.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/ulimit.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/umask.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/umask.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/umask.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/wait.o: command.h config.h memalloc.h error.h general.h maxpath.h
|
||||||
|
builtins/wait.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h stdc.h
|
||||||
|
builtins/wait.o: shell.h bashjmp.h sig.h unwind_prot.h variables.h
|
||||||
|
builtins/shopt.o: command.h config.h memalloc.h error.h general.h
|
||||||
|
builtins/shopt.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h
|
||||||
|
builtins/shopt.o: shell.h bashjmp.h unwind_prot.h variables.h maxpath.h
|
||||||
|
builtins/shopt.o: $(DEFSRC)/common.h $(DEFSRC)/bashgetopt.h
|
||||||
|
|
||||||
|
builtins/bashgetopt.o: bashansi.h ansi_stdlib.h
|
||||||
|
builtins/mkbuiltins.o: bashansi.h ansi_stdlib.h
|
||||||
|
builtins/fc.o: bashansi.h ansi_stdlib.h
|
||||||
|
|
||||||
|
builtins/bind.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h
|
||||||
|
builtins/bind.o: $(RL_LIBSRC)/keymaps.h
|
||||||
|
|
||||||
|
builtins/bind.o: $(HIST_LIBSRC)/history.h
|
||||||
|
builtins/fc.o: $(HIST_LIBSRC)/history.h
|
||||||
|
builtins/history.o: $(HIST_LIBSRC)/history.h
|
||||||
|
|
||||||
|
builtins/common.o: $(TILDE_LIBSRC)/tilde.h
|
||||||
|
builtins/cd.o: $(TILDE_LIBSRC)/tilde.h
|
||||||
|
|
||||||
|
builtins/alias.o: $(DEFSRC)/alias.def
|
||||||
|
builtins/bind.o: $(DEFSRC)/bind.def
|
||||||
|
builtins/break.o: $(DEFSRC)/break.def
|
||||||
|
builtins/builtin.o: $(DEFSRC)/builtin.def
|
||||||
|
builtins/cd.o: $(DEFSRC)/cd.def
|
||||||
|
builtins/colon.o: $(DEFSRC)/colon.def
|
||||||
|
builtins/command.o: $(DEFSRC)/command.def
|
||||||
|
builtins/declare.o: $(DEFSRC)/declare.def
|
||||||
|
builtins/echo.o: $(DEFSRC)/echo.def
|
||||||
|
builtins/enable.o: $(DEFSRC)/enable.def
|
||||||
|
builtins/eval.o: $(DEFSRC)/eval.def
|
||||||
|
builtins/exec.o: $(DEFSRC)/exec.def
|
||||||
|
builtins/exit.o: $(DEFSRC)/exit.def
|
||||||
|
builtins/fc.o: $(DEFSRC)/fc.def
|
||||||
|
builtins/fg_bg.o: $(DEFSRC)/fg_bg.def
|
||||||
|
builtins/getopts.o: $(DEFSRC)/getopts.def
|
||||||
|
builtins/hash.o: $(DEFSRC)/hash.def
|
||||||
|
builtins/help.o: $(DEFSRC)/help.def
|
||||||
|
builtins/history.o: $(DEFSRC)/history.def
|
||||||
|
builtins/inlib.o: $(DEFSRC)/inlib.def
|
||||||
|
builtins/jobs.o: $(DEFSRC)/jobs.def
|
||||||
|
builtins/kill.o: $(DEFSRC)/kill.def
|
||||||
|
builtins/let.o: $(DEFSRC)/let.def
|
||||||
|
builtins/pushd.o: $(DEFSRC)/pushd.def
|
||||||
|
builtins/read.o: $(DEFSRC)/read.def
|
||||||
|
builtins/reserved.o: $(DEFSRC)/reserved.def
|
||||||
|
builtins/return.o: $(DEFSRC)/return.def
|
||||||
|
builtins/set.o: $(DEFSRC)/set.def
|
||||||
|
builtins/setattr.o: $(DEFSRC)/setattr.def
|
||||||
|
builtins/shift.o: $(DEFSRC)/shift.def
|
||||||
|
builtins/shopt.o: $(DEFSRC)/shopt.def
|
||||||
|
builtins/source.o: $(DEFSRC)/source.def
|
||||||
|
builtins/suspend.o: $(DEFSRC)/suspend.def
|
||||||
|
builtins/test.o: $(DEFSRC)/test.def
|
||||||
|
builtins/times.o: $(DEFSRC)/times.def
|
||||||
|
builtins/trap.o: $(DEFSRC)/trap.def
|
||||||
|
builtins/type.o: $(DEFSRC)/type.def
|
||||||
|
builtins/ulimit.o: $(DEFSRC)/ulimit.def
|
||||||
|
builtins/umask.o: $(DEFSRC)/umask.def
|
||||||
|
builtins/wait.o: $(DEFSRC)/wait.def
|
||||||
284
NEWS
284
NEWS
@@ -1,10 +1,280 @@
|
|||||||
This file documents the bugs fixed between this release, bash-1.14.7,
|
This is a terse description of the new features added to bash-2.0 since
|
||||||
and the last public bash release, 1.14.6.
|
the release of bash-1.14.7. As always, the manual page (doc/bash.1) is
|
||||||
|
the place to look for complete descriptions.
|
||||||
|
|
||||||
1. Bugs fixed in Bash
|
1. New Features in Bash
|
||||||
|
|
||||||
a. A memory leak that caused long-running scripts to eventually consume
|
a. There is a new invocation option, -D, that dumps translatable strings
|
||||||
all available memory was fixed.
|
in a script.
|
||||||
|
|
||||||
b. A sign-extension bug that caused a security hole for non-interactive
|
b. The `long' invocation options must now be prefixed with `--'.
|
||||||
shells was fixed.
|
|
||||||
|
c. New long invocation options: --dump-strings, --help, --verbose
|
||||||
|
|
||||||
|
d. The `nolineediting' invocation option was renamed to `noediting'.
|
||||||
|
|
||||||
|
e. The `nobraceexpansion' and `quiet' long invocation options were removed.
|
||||||
|
|
||||||
|
f. The `--help' and `--version' long options now work as the GNU coding
|
||||||
|
standards specify.
|
||||||
|
|
||||||
|
g. If invoked as `sh', bash now enters posix mode after reading the
|
||||||
|
startup files, and reads and executes commands from the file named
|
||||||
|
by $ENV if interactive (as POSIX.2 specifies). A login shell invoked
|
||||||
|
as `sh' reads $ENV after /etc/profile and ~/.profile.
|
||||||
|
|
||||||
|
h. There is a new reserved word, `time', for timing pipelines, builtin
|
||||||
|
commands, and shell functions. It uses the value of the TIMEFORMAT
|
||||||
|
variable as a format string describing how to print the timing
|
||||||
|
statistics.
|
||||||
|
|
||||||
|
i. The $'...' quoting syntax expands ANSI-C escapes in ... and leaves the
|
||||||
|
result single-quoted.
|
||||||
|
|
||||||
|
j. The $"..." quoting syntax performs locale-specific translation of ...
|
||||||
|
and leaves the result double-quoted.
|
||||||
|
|
||||||
|
k. LINENO now works correctly in functions.
|
||||||
|
|
||||||
|
l. New variables: DIRSTACK, PIPESTATUS, BASH_VERSINFO, HOSTNAME, SHELLOPTS,
|
||||||
|
MACHTYPE. The first three are array variables.
|
||||||
|
|
||||||
|
m. The BASH_VERSION and BASH_VERSINFO variables now include the shell's
|
||||||
|
`release status' (alpha[N], beta[N], release).
|
||||||
|
|
||||||
|
n. Some variables have been removed: MAIL_WARNING, notify, history_control,
|
||||||
|
command_oriented_history, glob_dot_filenames, allow_null_glob_expansion,
|
||||||
|
nolinks, hostname_completion_file, noclobber, no_exit_on_failed_exec, and
|
||||||
|
cdable_vars. Most of them are now implemented with the new `shopt'
|
||||||
|
builtin; others were already implemented by `set'.
|
||||||
|
|
||||||
|
o. Bash now uses some new variables: LC_ALL, LC_MESSAGES, LC_CTYPE,
|
||||||
|
LC_COLLATE, LANG, GLOBIGNORE, HISTIGNORE.
|
||||||
|
|
||||||
|
p. The shell now supports integer-indexed arrays of unlimited length,
|
||||||
|
with a new compound assignment syntax and changes to the appropriate
|
||||||
|
builtin commands (declare/typeset, read, readonly, etc.). The array
|
||||||
|
index may be an arithmetic expression.
|
||||||
|
|
||||||
|
q. ${!var}: indirect variable expansion, equivalent to eval \${$var}.
|
||||||
|
|
||||||
|
r. ${paramter:offset[:length]}: variable substring extraction.
|
||||||
|
|
||||||
|
s. ${parameter/pattern[/[/]string]}: variable pattern substitution.
|
||||||
|
|
||||||
|
t. The $[...] arithmetic expansion syntax is no longer supported, in
|
||||||
|
favor of $((...)).
|
||||||
|
|
||||||
|
u. Aliases can now be expanded in shell scripts with a shell option
|
||||||
|
(shopt expand_aliases).
|
||||||
|
|
||||||
|
v. History and history expansion can now be used in scripts with
|
||||||
|
set -o history and set -H.
|
||||||
|
|
||||||
|
w. All builtins now return an exit status of 2 for incorrect usage.
|
||||||
|
|
||||||
|
x. Interactive shells resend SIGHUP to all running or stopped children
|
||||||
|
if (and only if) they exit due to a SIGHUP.
|
||||||
|
|
||||||
|
y. New prompting expansions: \a, \e, \H, \T, \@, \v, \V.
|
||||||
|
|
||||||
|
z. Variable expansion in prompt strings is now controllable via a shell
|
||||||
|
option (shopt promptvars).
|
||||||
|
|
||||||
|
aa. Bash now defaults to using command-oriented history.
|
||||||
|
|
||||||
|
bb. The history file ($HISTFILE) is now truncated to $HISTFILESIZE after
|
||||||
|
being written.
|
||||||
|
|
||||||
|
cc. The POSIX.2 conditional arithmetic evaluation syntax (expr ? expr : expr)
|
||||||
|
has been implemented.
|
||||||
|
|
||||||
|
dd. Each builtin now accepts `--' to signify the end of the options, except
|
||||||
|
as documented (echo, etc.).
|
||||||
|
|
||||||
|
ee. All builtins use -p to display values in a re-readable format where
|
||||||
|
appropriate, except as documented (echo, type, etc.).
|
||||||
|
|
||||||
|
ff. The `alias' builtin has a new -p option.
|
||||||
|
|
||||||
|
gg. Changes to the `bind' builtin:
|
||||||
|
o has new options: -psPSVr.
|
||||||
|
o the `-d' option was renamed to `-p'
|
||||||
|
o the `-v' option now dumps variables; the old `-v' is now `-P'
|
||||||
|
|
||||||
|
hh. The `bye' synonym for `exit' was removed.
|
||||||
|
|
||||||
|
ii. The -L and -P options to `cd' and `pwd' have been documented.
|
||||||
|
|
||||||
|
jj. The `cd' builtin now does spelling correction on the directory name
|
||||||
|
by default. This is settable with a shell option (shopt cdspell).
|
||||||
|
|
||||||
|
kk. The `declare' builtin has new options: -a, -F, -p.
|
||||||
|
|
||||||
|
ll. The `dirs' builtin has new options: -c, -p, -v.
|
||||||
|
|
||||||
|
mm. The new `disown' builtin removes jobs from the shell's jobs table
|
||||||
|
or inhibits the resending of SIGHUP when the shell receives a
|
||||||
|
SIGHUP.
|
||||||
|
|
||||||
|
nn. The `echo' builtin has a new escape character: \e.
|
||||||
|
|
||||||
|
oo. The `enable' builtin can now load new builtins dynamically from shared
|
||||||
|
objects on systems with the dlopen/dlsym interface. There are a number
|
||||||
|
of examples in the examples/loadables directory. There are also
|
||||||
|
new options: -d, -f, -s, -p.
|
||||||
|
|
||||||
|
pp. The `-all' option to `enable' was removed in favor of `-a'.
|
||||||
|
|
||||||
|
qq. The `exec' builtin has new options: -l, -c, -a.
|
||||||
|
|
||||||
|
rr. The `hash' builtin has a new option: -p.
|
||||||
|
|
||||||
|
ss. The `history' builtin has new options: -c, -p, -s.
|
||||||
|
|
||||||
|
tt. The `jobs' builtin has new options: -r, -s.
|
||||||
|
|
||||||
|
uu. The `kill' builtin has new options: -n signum, -l signame.
|
||||||
|
|
||||||
|
vv. The `pushd' and `popd' builtins have a new option: -n.
|
||||||
|
|
||||||
|
ww. The `read' builtin has new options: -p prompt, -e, -a.
|
||||||
|
|
||||||
|
xx. The `readonly' builtin has a new -a option, and the -n option was removed.
|
||||||
|
|
||||||
|
yy. Changes to the `set' builtin:
|
||||||
|
o new options: -B, -o keyword, -o onecmd, -o history
|
||||||
|
o options removed: -l, -d, -o nohash
|
||||||
|
o options changed: +o, -h, -o hashall
|
||||||
|
o now displays variables in a format that can be re-read as input
|
||||||
|
|
||||||
|
zz. The new `shopt' builtin controls shell optional behavior previously
|
||||||
|
done by setting and unsetting certain shell variables.
|
||||||
|
|
||||||
|
aaa. The `test' builtin has new operators: -o option, s1 == s2, s1 < s2,
|
||||||
|
and s1 > s2, where s1 and s2 are strings.
|
||||||
|
|
||||||
|
bbb. There is a new trap, DEBUG, executed after every simple command.
|
||||||
|
|
||||||
|
ccc. The `trap' builtin has a new -p option.
|
||||||
|
|
||||||
|
ddd. The `ulimit' builtin has a new -l option on 4.4BSD-based systems.
|
||||||
|
|
||||||
|
eee. The PS1, PS2, PATH, and IFS variables may now be unset.
|
||||||
|
|
||||||
|
fff. The restricted shell mode has been expanded and is now documented.
|
||||||
|
|
||||||
|
ggg. Security improvements:
|
||||||
|
o functions are not imported from the environment if running setuid
|
||||||
|
or with -p
|
||||||
|
o no startup files are sourced if running setuid or with -p
|
||||||
|
|
||||||
|
hhh. The documentation has been overhauled: the texinfo manual was
|
||||||
|
expanded, and HTML versions of the man page and texinfo manual
|
||||||
|
are included.
|
||||||
|
|
||||||
|
iii. Changes to Posix mode:
|
||||||
|
o Command lookup now finds special builtins before shell functions.
|
||||||
|
o Failure of a special builtin causes a non-interactive shell to
|
||||||
|
exit. Failures are defined in the POSIX.2 specification.
|
||||||
|
o If the `cd' builtin finds a directory to change to using $CDPATH,
|
||||||
|
the value assigned to PWD when `cd' completes does not contain
|
||||||
|
any symbolic links.
|
||||||
|
o A non-interactive shell exits if a variable assignment error
|
||||||
|
occurs when no command name follows the assignment statements.
|
||||||
|
o A non-interactive shell exits if the interation variable in a
|
||||||
|
`for' statement or the selection variable in a `select' statement
|
||||||
|
is read-only or another variable assignment error occurs.
|
||||||
|
o The `<>' redirection operator now opens a file for both stdin and
|
||||||
|
stdout by default, not just when in posix mode.
|
||||||
|
o Assignment statements preceding special builtins now persist in
|
||||||
|
the shell's environment when the builtin completes.
|
||||||
|
|
||||||
|
Posix mode is now completely POSIX.2-compliant (modulo bugs). When
|
||||||
|
invoked as sh, bash should be completely POSIX.2-compliant.
|
||||||
|
|
||||||
|
jjj. The default value of PS1 is now "\s-\v\$ ".
|
||||||
|
|
||||||
|
kkk. The ksh-like ((...)) arithmetic command syntax has been implemented.
|
||||||
|
This is exactly equivalent to `let "..."'.
|
||||||
|
|
||||||
|
lll. Integer constants have been extended to base 64.
|
||||||
|
|
||||||
|
mmm. The `ulimit' builtin now sets both hard and soft limits and reports the
|
||||||
|
soft limit by default.
|
||||||
|
|
||||||
|
2. New Features in Readline
|
||||||
|
|
||||||
|
a. New variables: enable-keypad, input-meta (new name for meta-flag),
|
||||||
|
mark-directories, visible-stats (now documented), disable-completion,
|
||||||
|
comment-begin.
|
||||||
|
|
||||||
|
b. New bindable commands: kill-region, copy-region-as-kill,
|
||||||
|
copy-backward-word, copy-forward-word, set-mark, exchange-point-and-mark,
|
||||||
|
character-search, character-search-backward, insert-comment,
|
||||||
|
glob-expand-word, glob-list-expansions, dump-variables, dump-macros.
|
||||||
|
|
||||||
|
c. New emacs keybindings: delete-horizontal-space (M-\),
|
||||||
|
insert-completions (M-*), possible-completions (M-=).
|
||||||
|
|
||||||
|
d. The history-search-backward and history-search-forward commands were
|
||||||
|
modified to be the same as previous-line and next-line if point is at
|
||||||
|
the start of the line.
|
||||||
|
|
||||||
|
e. More file types are available for the visible-stats mode.
|
||||||
|
|
||||||
|
3. Changes of interest in the Bash implementation
|
||||||
|
|
||||||
|
a. There is a new autoconf-based configuration mechanism.
|
||||||
|
|
||||||
|
b. More things have been moved from Posix mode to standard shell behavior.
|
||||||
|
|
||||||
|
c. The trace output (set -x) now inserts quotes where necessary so it can
|
||||||
|
be reused as input.
|
||||||
|
|
||||||
|
d. There is a compile-time option for a system-wide interactive shell
|
||||||
|
startup file (disabled by default).
|
||||||
|
|
||||||
|
e. The YACC grammar is smaller and tighter, and all 66 shift-reduce
|
||||||
|
conflicts are gone. Several parsing bugs have been fixed.
|
||||||
|
|
||||||
|
f. Builtin option parsing has been regularized (using internal_getopt()),
|
||||||
|
with the exception of `echo', `type', and `set'.
|
||||||
|
|
||||||
|
g. Builtins now return standard usage messages constructed from the
|
||||||
|
`short doc' used by the help builtin.
|
||||||
|
|
||||||
|
h. Completion now quotes using backslashes by default, but honors
|
||||||
|
user-supplied quotes.
|
||||||
|
|
||||||
|
i. The GNU libc malloc is available as a configure-time option.
|
||||||
|
|
||||||
|
j. There are more internationalization features; bash uses gettext if
|
||||||
|
it is available. The $"..." translation syntax uses the current
|
||||||
|
locale and gettext.
|
||||||
|
|
||||||
|
k. There is better reporting of job termination when the shell is not
|
||||||
|
interactive.
|
||||||
|
|
||||||
|
l. The shell is somewhat more efficient: it uses a little less memory and
|
||||||
|
makes fewer system calls.
|
||||||
|
|
||||||
|
4. Changes of interest in the Readline implementation
|
||||||
|
|
||||||
|
a. There is now support for readline `callback' functions.
|
||||||
|
|
||||||
|
b. There is now support for user-supplied input, redisplay, and terminal
|
||||||
|
preparation functions.
|
||||||
|
|
||||||
|
c. Most of the shell-specific code in readline has been generalized or
|
||||||
|
removed.
|
||||||
|
|
||||||
|
d. Most of the annoying redisplay bugs have been fixed, notably the problems
|
||||||
|
with incremental search and excessive redrawing when special characters
|
||||||
|
appear in the prompt string.
|
||||||
|
|
||||||
|
e. There are new library functions and variables available to application
|
||||||
|
writers, most having to do with completion and quoting.
|
||||||
|
|
||||||
|
f. The NEWLINE character (^J) is now treated as a search terminator by the
|
||||||
|
incremental search functions.
|
||||||
|
|||||||
42
NOTES
Normal file
42
NOTES
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
Platform-Specific Configuration Notes
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
1. configure --without-gnu-malloc on:
|
||||||
|
|
||||||
|
alpha running OSF/1
|
||||||
|
alpha running Linux
|
||||||
|
|
||||||
|
next running NeXT/OS
|
||||||
|
|
||||||
|
all machines running SunOS YP code: SunOS4, SunOS5, HP/UX
|
||||||
|
|
||||||
|
linux (optional)
|
||||||
|
|
||||||
|
QNX 4.2
|
||||||
|
other OSF/1 machines (KSR/1, HP, IBM AIX/ESA)
|
||||||
|
AIX
|
||||||
|
sparc SVR4, SVR4.2 (ICL reference port)
|
||||||
|
DG/UX
|
||||||
|
Cray
|
||||||
|
|
||||||
|
NetBSD/sparc (malloc needs 8-byte alignment; GNU malloc has 4-byte)
|
||||||
|
|
||||||
|
BSD/OS 2.1 if you want to use loadable builtins
|
||||||
|
|
||||||
|
If you are using GNU libc, especially on a linux system
|
||||||
|
|
||||||
|
(Configuring --without-gnu-malloc will still result in lib/malloc/libmalloc.a
|
||||||
|
being built and linked against, but there is only a stub file in the archive.)
|
||||||
|
|
||||||
|
2. configure using shlicc on BSD/OS 2.1 to use loadable builtins
|
||||||
|
|
||||||
|
3. Bash cannot be built in a directory separate from the source directory
|
||||||
|
using configure --srcdir=... unless the version of `make' you're using
|
||||||
|
does $VPATH handling right. The SunOS make, for one, does not seem to
|
||||||
|
do it right. The script support/mkclone can be used to create a
|
||||||
|
`build tree' using symlinks to get around this.
|
||||||
|
|
||||||
|
4. I've had reports that username completion does not work on IRIX 5.3
|
||||||
|
when linking with -lnsl. This is only a problem when you're running
|
||||||
|
NIS. Editing the Makefile after configure runs and removing the
|
||||||
|
`-lnsl' from the assignment to `LIBS' fixes the problem.
|
||||||
71
README
71
README
@@ -1,48 +1,77 @@
|
|||||||
This README file is in -*- text -*- mode, because Emacs likes it that way.
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
This is GNU Bash, version 1.14. Bash is the GNU Project's Bourne
|
This is GNU Bash, version 2.0. Bash is the GNU Project's Bourne
|
||||||
Again SHell, an interactive shell with Bourne shell syntax (/bin/sh);
|
Again SHell, a complete implementation of the POSIX.2 shell spec,
|
||||||
but also with interactive command line editing, job control on
|
but also with interactive command line editing, job control on
|
||||||
architectures that support it, Csh-like history features and brace
|
architectures that support it, csh-like features such as history
|
||||||
expansion, and a slew of other stuff. For more information on the
|
substitution and brace expansion, and a slew of other features.
|
||||||
features of Bash that are new to this type of shell, see the file
|
For more information on the features of Bash that are new to this
|
||||||
`documentation/features.texi'. There is also a DVI file there, as
|
type of shell, see the file `doc/features.texi'. There is also a
|
||||||
well as a large man page.
|
large man page. The manual page is the definitive description of
|
||||||
|
the shell's features.
|
||||||
|
|
||||||
To compile it, try typing `make'. Bash auto-configures the build
|
See the file CWRU/POSIX.NOTES for a discussion of how Bash differs
|
||||||
process, so no intervention should be necessary. If you want to
|
from the POSIX.2 spec and a description of the Bash `posix mode'.
|
||||||
use gcc, type `make CC=gcc CPPNAME='$(CC) -E''.
|
|
||||||
|
|
||||||
You may want to read the file INSTALL in this directory for more
|
There are some user-visible incompatibilities between this version
|
||||||
information if the make fails.
|
of Bash and the previous version, bash-1.14. For details, see the
|
||||||
|
file COMPAT.
|
||||||
|
|
||||||
|
Bash is free software, distributed under the terms of the GNU Public
|
||||||
|
License, version 2. For more information, see the file COPYING.
|
||||||
|
|
||||||
|
To compile Bash, try typing `./configure', then `make'. Bash
|
||||||
|
auto-configures the build process, so no further intervention
|
||||||
|
should be necessary. Bash builds with `gcc' by default if it is
|
||||||
|
available. If you want to use `cc' instead, type
|
||||||
|
|
||||||
|
CC=cc ./configure
|
||||||
|
|
||||||
|
if you are using a Bourne-style shell. If you are not, the following
|
||||||
|
may work:
|
||||||
|
|
||||||
|
env CC=cc ./configure
|
||||||
|
|
||||||
|
Read the file INSTALL in this directory for more information about how
|
||||||
|
to customize and control the build process. The file NOTES contains
|
||||||
|
platform-specific installation and configuration information.
|
||||||
|
|
||||||
If you are a csh user and wish to convert your csh aliases to Bash
|
If you are a csh user and wish to convert your csh aliases to Bash
|
||||||
aliases, you may wish to use the script in examples/alias-conv.sh
|
aliases, you may wish to use the script `examples/misc/alias-conv.sh'
|
||||||
as a starting point.
|
as a starting point.
|
||||||
|
|
||||||
Bug reports for 1.14 should be sent to:
|
Reporting Bugs
|
||||||
|
==============
|
||||||
|
|
||||||
|
Bug reports for 2.0 should be sent to:
|
||||||
|
|
||||||
bug-bash@prep.ai.mit.edu
|
bug-bash@prep.ai.mit.edu
|
||||||
|
|
||||||
using the `bashbug' program that is built and installed at the same
|
using the `bashbug' program that is built and installed at the same
|
||||||
time as bash.
|
time as bash.
|
||||||
|
|
||||||
The discussion list "bug-bash@prep.ai.mit.edu" often contains information
|
The discussion list `bug-bash@prep.ai.mit.edu' often contains
|
||||||
about new ports of Bash, or discussions of new features or behavior
|
information about new ports of Bash, or discussions of new
|
||||||
changes that people would like. This mailing list is also available
|
features or behavior changes that people would like. This
|
||||||
as a usenet newsgroup: gnu.bash.bug.
|
mailing list is also available as a usenet newsgroup:
|
||||||
|
gnu.bash.bug.
|
||||||
|
|
||||||
When you send a bug report to bash-maintainers@prep.ai.mit.edu, please
|
When you send a bug report to bug-bash@prep.ai.mit.edu, please include:
|
||||||
include:
|
|
||||||
|
|
||||||
* the version number of Bash
|
* the version number of Bash
|
||||||
* the machine and OS that it is running on (see .machine or .made)
|
* the machine and OS that it is running on (see .machine or .made)
|
||||||
|
* a list of the compilation flags or the contents of `config.h', if
|
||||||
|
appropriate
|
||||||
* a description of the bug
|
* a description of the bug
|
||||||
* a recipe for recreating the bug reliably
|
* a recipe for recreating the bug reliably
|
||||||
* a fix for the bug if you have one!
|
* a fix for the bug if you have one!
|
||||||
|
|
||||||
The `bashbug' program includes much of this automatically.
|
The `bashbug' program includes much of this automatically.
|
||||||
|
|
||||||
|
If you would like to contact the Bash maintainers directly, send mail to
|
||||||
|
bash-maintainers@prep.ai.mit.edu.
|
||||||
|
|
||||||
While the Bash maintainers do not promise to fix all bugs, we would
|
While the Bash maintainers do not promise to fix all bugs, we would
|
||||||
like this shell to be the best that we can make it.
|
like this shell to be the best that we can make it.
|
||||||
|
|
||||||
|
|||||||
269
RELEASE
269
RELEASE
@@ -1,269 +0,0 @@
|
|||||||
This file details the changes between the previous release of bash (1.13.5)
|
|
||||||
and this release (1.14.0).
|
|
||||||
|
|
||||||
1. New Features in Bash
|
|
||||||
|
|
||||||
a. The source has been reorganized: nearly all extern function
|
|
||||||
declarations have been moved to header files, function prototypes
|
|
||||||
have been added to most header files, function declarations have
|
|
||||||
been moved to file scope, dead code has been removed, the
|
|
||||||
bash history code has been isolated in bashhist.[ch], and several
|
|
||||||
new header files have been created
|
|
||||||
|
|
||||||
b. `set -o posix' puts bash into Posix.2 mode
|
|
||||||
|
|
||||||
c. If $POSIX_PEDANTIC exists in the initial environment or is assigned
|
|
||||||
a value, bash enters Posix.2 mode
|
|
||||||
|
|
||||||
d. Bash sets $OSTYPE to a string describing the UNIX version
|
|
||||||
|
|
||||||
e. The features.info file was completely rewritten and now reflects
|
|
||||||
the current state of things
|
|
||||||
|
|
||||||
f. A manual page for readline is in documentation/readline.{3,ps}
|
|
||||||
|
|
||||||
g. The test builtin emulates /dev/fd/x for systems without /dev/fd
|
|
||||||
|
|
||||||
h. `dirs' has -n and +n options to access members of the directory stack
|
|
||||||
|
|
||||||
i. Prompt string expansion handles invisible characters in the prompt;
|
|
||||||
\[ and \] are used (and required) to start and end sequences of
|
|
||||||
invisible chars
|
|
||||||
|
|
||||||
j. NO_PROMPT_VARS has been removed
|
|
||||||
|
|
||||||
k. New machine descriptions have been added: IBM AIX/ESA, NEC EWS, NetBSD,
|
|
||||||
FreeBSD, QNX 4.2, concurrent, MIPS SVR4.2, Lynx 2.1
|
|
||||||
|
|
||||||
l. RESTRICTED_SHELL is no longer defined by default in config.h
|
|
||||||
|
|
||||||
m. The version string in $BASH_VERSION has changed to dist.patch(build)
|
|
||||||
|
|
||||||
n. $history_control has been renamed to $HISTCONTROL and now takes the
|
|
||||||
value `ignoreboth' ($history_control is still accepted for backwards
|
|
||||||
compatibility)
|
|
||||||
|
|
||||||
o. There is a new program `bashbug' for reporting bugs. Eventually I will
|
|
||||||
probably switch to gnats.
|
|
||||||
|
|
||||||
p. auto_resume can take the values `exact' and `substring'
|
|
||||||
|
|
||||||
q. `set -P' (`set -o physical') enables the same physical view of the
|
|
||||||
file system that `nolinks' enables (`nolinks' will remain for one
|
|
||||||
more release)
|
|
||||||
|
|
||||||
r. There is a `mkmachtype' program to generate a GNU-style machine type
|
|
||||||
string (e.g., `sparc-sun-sunos4.1.2') suitable for assigning to
|
|
||||||
$MACHTYPE
|
|
||||||
|
|
||||||
s. The variable $HISTCMD returns the current history number
|
|
||||||
|
|
||||||
t. Variables in directory names are now expanded while doing completion
|
|
||||||
|
|
||||||
u. The test suite has been expanded and is runnable as a regression test
|
|
||||||
with `make tests'
|
|
||||||
|
|
||||||
v. `bye' is no longer a builtin synonym for `exit'
|
|
||||||
|
|
||||||
w. The ksh `select' control construct has been implemented
|
|
||||||
|
|
||||||
x. The `ignoreeof' attribute can be inherited if $IGNOREEOF is exported
|
|
||||||
|
|
||||||
y. The `USG-style' echo is now a configuration option. Define
|
|
||||||
DEFAULT_ECHO_TO_USG for default \-interpretation without the -e flag
|
|
||||||
|
|
||||||
z. There is a copy of an article I wrote about bash for the Linux
|
|
||||||
Journal in documentation/article.{ms,ps}
|
|
||||||
|
|
||||||
aa. The `pwd' builtin now obeys the setting of `set -o physical' (`nolinks')
|
|
||||||
|
|
||||||
bb. Process substitution is no longer performed when the shell is in
|
|
||||||
`posix mode'
|
|
||||||
|
|
||||||
cc. Users may change the debugging and optimization flags to cc by specifying
|
|
||||||
CFLAGS to make
|
|
||||||
|
|
||||||
2. New Features in Readline
|
|
||||||
|
|
||||||
a. Readline now understands sequences of invisible characters in the prompt
|
|
||||||
string, as long as they are escaped (e.g., by the bash \[ and \] escapes)
|
|
||||||
|
|
||||||
b. A `set keymap' variable assignment
|
|
||||||
|
|
||||||
c. A `bell-style' variable that can be set to `visible', `audio', or `none'
|
|
||||||
|
|
||||||
d. A `show-all-if-ambiguous' variable, which causes non-unique completion
|
|
||||||
to immediately list the possible completions
|
|
||||||
|
|
||||||
e. An `output-meta' variable to make readline directly output chars
|
|
||||||
with the eighth bit set
|
|
||||||
|
|
||||||
f. New bindable readline commands: kill-whole-line, tilde-expand,
|
|
||||||
vi-redo, vi-tilde-expand, emacs-editing-mode,
|
|
||||||
non-incremental-forward-search-history-again,
|
|
||||||
non-incremental-reverse-search-history-again
|
|
||||||
|
|
||||||
g. New history-search-forward and history-search-backward to search for
|
|
||||||
the characters between the start of the current line and point
|
|
||||||
|
|
||||||
h. Readline takes the name of the startup file from the INPUTRC variable
|
|
||||||
before defaulting to ~/.inputrc
|
|
||||||
|
|
||||||
i. isearch no longer finds identical lines multiple times in succession
|
|
||||||
|
|
||||||
j. M-C-H bound to backward-kill-word in emacs mode
|
|
||||||
|
|
||||||
k. M-~ bound to tilde-expand in emacs mode
|
|
||||||
|
|
||||||
l. History expansion is now fully csh-compatible: missing modifiers and
|
|
||||||
substitutions have been added, and bugs fixed
|
|
||||||
|
|
||||||
m. When asking whether or not to display the possible completions, readline
|
|
||||||
now accepts space as equivalent to `y' and rubout for `n'
|
|
||||||
|
|
||||||
n. Readline now attempts to find and bind the arrow keys into the vi mode
|
|
||||||
movement keymap
|
|
||||||
|
|
||||||
3. Bugs fixed in Bash
|
|
||||||
|
|
||||||
a. Portability fixes: `index' and `rindex' are gone completely, many
|
|
||||||
OS-specific defines have been replaced with feature-test macros,
|
|
||||||
the use of alloca has been reduced, and other platform-specific fixes
|
|
||||||
(e.g. cray) have been made
|
|
||||||
|
|
||||||
b. The man page has been fixed up and brought up to date
|
|
||||||
|
|
||||||
c. Speed improvements: here documents, variable expansion, history
|
|
||||||
expansion, command substitution
|
|
||||||
|
|
||||||
d. If history is stifled, the history list replaces the history file at
|
|
||||||
exit
|
|
||||||
|
|
||||||
e. Asynchronous jobs re-run with fc -s now print the job number
|
|
||||||
|
|
||||||
f. Output redirections do not perform filename expansion in Posix.2 mode
|
|
||||||
when the shell is not interactive
|
|
||||||
|
|
||||||
g. operate_and_get_next now works on the most recent line even if the
|
|
||||||
history is unstifled
|
|
||||||
|
|
||||||
h. $PROMPT_COMMAND execution no longer causes recursive invocations
|
|
||||||
of yyparse()
|
|
||||||
|
|
||||||
i. An error message is printed if job control initialization fails
|
|
||||||
|
|
||||||
j. A command found in $PATH from the temporary environment is not hashed
|
|
||||||
|
|
||||||
k. Errors display the name of the script if the shell is not interactive
|
|
||||||
|
|
||||||
l. Fixed expression evaluation so blank expressions return 0
|
|
||||||
|
|
||||||
m. Fixed a bug that caused SIGINT and SIGQUIT not to be ignored in some
|
|
||||||
asynchronous children
|
|
||||||
|
|
||||||
n. Pipes used for /dev/fd process substitution are now closed on errors
|
|
||||||
|
|
||||||
o. Fixed /dev/null redirection so that ( list ) subshells inherit the
|
|
||||||
`stdin-has-been-redirected' flag as in sh
|
|
||||||
|
|
||||||
p. Process substitution now works only when unquoted
|
|
||||||
|
|
||||||
q. Fixed a bug where the async flag was added inappropriately in a command
|
|
||||||
like `a;b;c;d &'
|
|
||||||
|
|
||||||
r. Fixed off-by-one bug which caused negative history offsets in `fc' to
|
|
||||||
be wrong
|
|
||||||
|
|
||||||
s. Shell now remembers mail dates at startup on all systems
|
|
||||||
|
|
||||||
t. Posix systems without job control no longer create so many zombies
|
|
||||||
|
|
||||||
u. $ENV is now sourced by shells forked to execute scripts without a
|
|
||||||
leading `#!' line
|
|
||||||
|
|
||||||
v. Non-root users can now use the `unlimited' argument to ulimit and have
|
|
||||||
the resource value set to the hard limit
|
|
||||||
|
|
||||||
w. Made bash more sh-compatible by assigning the first argument after
|
|
||||||
`-c command' to $0
|
|
||||||
|
|
||||||
x. Fixed mail checking bug to note that *new* mail has arrived
|
|
||||||
|
|
||||||
y. Fixed off-by-one error in mailcheck.c:free_mail_files()
|
|
||||||
|
|
||||||
z. Fixed a bug where command strings passed to `bash -c' would be truncated
|
|
||||||
after executing the first disk command in the string
|
|
||||||
|
|
||||||
aa. Fixed a bug which caused redirections passed to executable commands with
|
|
||||||
input or output pipes to be closed before the command was executed
|
|
||||||
|
|
||||||
bb. Fixed a bug which caused bash to search for files supplied on the command
|
|
||||||
line in the $PATH if the initial open failed, even if the names contained
|
|
||||||
a slash
|
|
||||||
|
|
||||||
cc. The initial argument parsing was fixed up so that other options can
|
|
||||||
be supplied with -c (that is, `sh -ec command' now works as make
|
|
||||||
intends), and so `bash -o' lists all the shell options at startup.
|
|
||||||
|
|
||||||
dd. Error messages are consistently prefixed with the name of the shell
|
|
||||||
or shell script when non-interactive.
|
|
||||||
|
|
||||||
ee. Fixed up a problem with the `read' builtin that occurred when more
|
|
||||||
variables than arguments were supplied.
|
|
||||||
|
|
||||||
ff. Unset the variables passed to `read' as arguments when EOF is
|
|
||||||
read from stdin (sh, Posix.2 compatibility).
|
|
||||||
|
|
||||||
gg. Fixes to the command printing code to make the output of `type'
|
|
||||||
available as legal shell input.
|
|
||||||
|
|
||||||
ii. Fixes so that command completion is attempted after all of the shell
|
|
||||||
command separator characters.
|
|
||||||
|
|
||||||
jj. Fixes to the shell completion code so that it handles quoted characters
|
|
||||||
and substrings better.
|
|
||||||
|
|
||||||
kk. Bash no longer looks through $PATH for a shell script passed as an
|
|
||||||
argument if the name contains slashes.
|
|
||||||
|
|
||||||
ll. Bash now checks that the `name' in a `name[=value]' argument to `declare'
|
|
||||||
(and thus `typeset', `export', and `readonly') is a legal shell variable
|
|
||||||
name.
|
|
||||||
|
|
||||||
4. Bugs fixed in Readline
|
|
||||||
|
|
||||||
a. The ^W and ^U bindings in non-incremental search mode have been changed
|
|
||||||
to be closer to what Posix specifies
|
|
||||||
|
|
||||||
b. Tries to initialize the keypad to enable the arrow keys
|
|
||||||
|
|
||||||
c. Multiple words are now killed and yanked in the right order
|
|
||||||
|
|
||||||
d. rl_read_init_file now reads filenames in a more regular order: the last
|
|
||||||
one read, $INPUTRC, then ~/.inputrc
|
|
||||||
|
|
||||||
e. yank_nth_arg inserts a space in the right place in vi mode
|
|
||||||
|
|
||||||
f. Fixed a bug in the history library that tried to write to a file opened
|
|
||||||
O_RDONLY
|
|
||||||
|
|
||||||
g. Binding of `0' in vi command mode is now right
|
|
||||||
|
|
||||||
h. The VISIBLE_STATS completion listing code now follows symlinks
|
|
||||||
|
|
||||||
i. Memory allocated with alloca() is no longer passed to other functions
|
|
||||||
|
|
||||||
j. Error messages are now printed for unrecognized history modifiers
|
|
||||||
|
|
||||||
k. Fixed a problem with history library and `!#'; now it is more csh-like.
|
|
||||||
|
|
||||||
l. Fixed a csh incompatibility in the history library: now only an end of
|
|
||||||
line or `?' terminates a ?string history search string.
|
|
||||||
|
|
||||||
m. Fixed a problem with readline completion that sometimes caused possible
|
|
||||||
matches to be listed one per line when `show-all-if-ambiguous' was set.
|
|
||||||
|
|
||||||
n. Fixed a problem in the readline display code that caused divide-by-zero
|
|
||||||
errors.
|
|
||||||
|
|
||||||
o. Fixed an off-by-one error in the kill ring reallocation code.
|
|
||||||
993
aclocal.m4
vendored
Normal file
993
aclocal.m4
vendored
Normal file
@@ -0,0 +1,993 @@
|
|||||||
|
dnl
|
||||||
|
dnl Bash specific tests
|
||||||
|
dnl
|
||||||
|
dnl Some derived from PDKSH 5.1.3 autoconf tests
|
||||||
|
dnl
|
||||||
|
dnl check whether cc can create executables
|
||||||
|
dnl
|
||||||
|
AC_DEFUN(BASH_CC_WORKS,
|
||||||
|
[AC_CACHE_CHECK(whether CC works at all, bash_cv_prog_cc_works,
|
||||||
|
[AC_TRY_RUN([main() { exit(0); }],
|
||||||
|
bash_cv_prog_cc_works=yes, bash_cv_prog_cc_works=no,
|
||||||
|
bash_cv_prog_cc_works=no)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if test "$bash_cv_prog_cc_works" = "no"; then
|
||||||
|
AC_MSG_ERROR([Installation or configuration problem: C compiler cannot create executables])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Check if dup2() does not clear the close on exec flag
|
||||||
|
dnl
|
||||||
|
AC_DEFUN(BASH_DUP2_CLOEXEC_CHECK,
|
||||||
|
[AC_MSG_CHECKING(if dup2 fails to clear the close-on-exec flag)
|
||||||
|
AC_CACHE_VAL(bash_cv_dup2_broken,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
int fd1, fd2, fl;
|
||||||
|
fd1 = open("/dev/null", 2);
|
||||||
|
if (fcntl(fd1, 2, 1) < 0)
|
||||||
|
exit(1);
|
||||||
|
fd2 = dup2(fd1, 1);
|
||||||
|
if (fd2 < 0)
|
||||||
|
exit(2);
|
||||||
|
fl = fcntl(fd2, 1, 0);
|
||||||
|
/* fl will be 1 if dup2 did not reset the close-on-exec flag. */
|
||||||
|
exit(fl != 1);
|
||||||
|
}
|
||||||
|
], bash_cv_dup2_broken=yes, bash_cv_dup2_broken=no,
|
||||||
|
AC_MSG_ERROR(cannot check dup2 if cross compiling))
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($bash_cv_dup2_broken)
|
||||||
|
if test $bash_cv_dup2_broken = yes; then
|
||||||
|
AC_DEFINE(DUP2_BROKEN)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Check type of signal routines (posix, 4.2bsd, 4.1bsd or v7)
|
||||||
|
AC_DEFUN(BASH_SIGNAL_CHECK,
|
||||||
|
[AC_REQUIRE([AC_TYPE_SIGNAL])
|
||||||
|
AC_MSG_CHECKING(for type of signal functions)
|
||||||
|
AC_CACHE_VAL(bash_cv_signal_vintage,
|
||||||
|
[
|
||||||
|
AC_TRY_LINK([#include <signal.h>],[
|
||||||
|
sigset_t ss;
|
||||||
|
struct sigaction sa;
|
||||||
|
sigemptyset(&ss); sigsuspend(&ss);
|
||||||
|
sigaction(SIGINT, &sa, (struct sigaction *) 0);
|
||||||
|
sigprocmask(SIG_BLOCK, &ss, (sigset_t *) 0);
|
||||||
|
], bash_cv_signal_vintage=posix,
|
||||||
|
[
|
||||||
|
AC_TRY_LINK([#include <signal.h>], [
|
||||||
|
int mask = sigmask(SIGINT);
|
||||||
|
sigsetmask(mask); sigblock(mask); sigpause(mask);
|
||||||
|
], bash_cv_signal_vintage=4.2bsd,
|
||||||
|
[
|
||||||
|
AC_TRY_LINK([
|
||||||
|
#include <signal.h>
|
||||||
|
RETSIGTYPE foo() { }], [
|
||||||
|
int mask = sigmask(SIGINT);
|
||||||
|
sigset(SIGINT, foo); sigrelse(SIGINT);
|
||||||
|
sighold(SIGINT); sigpause(SIGINT);
|
||||||
|
], bash_cv_signal_vintage=svr3, bash_cv_signal_vintage=v7
|
||||||
|
)]
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($bash_cv_signal_vintage)
|
||||||
|
if test "$bash_cv_signal_vintage" = posix; then
|
||||||
|
AC_DEFINE(HAVE_POSIX_SIGNALS)
|
||||||
|
elif test "$bash_cv_signal_vintage" = "4.2bsd"; then
|
||||||
|
AC_DEFINE(HAVE_BSD_SIGNALS)
|
||||||
|
elif test "$bash_cv_signal_vintage" = svr3; then
|
||||||
|
AC_DEFINE(HAVE_USG_SIGHOLD)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Check if the pgrp of setpgrp() can't be the pid of a zombie process.
|
||||||
|
AC_DEFUN(BASH_PGRP_SYNC,
|
||||||
|
[AC_REQUIRE([AC_FUNC_GETPGRP])
|
||||||
|
AC_MSG_CHECKING(whether pgrps need synchronization)
|
||||||
|
AC_CACHE_VAL(bash_cv_pgrp_pipe,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
# ifdef GETPGRP_VOID
|
||||||
|
# define getpgID() getpgrp()
|
||||||
|
# else
|
||||||
|
# define getpgID() getpgrp(0)
|
||||||
|
# define setpgid(x,y) setpgrp(x,y)
|
||||||
|
# endif
|
||||||
|
int pid1, pid2, fds[2];
|
||||||
|
int status;
|
||||||
|
char ok;
|
||||||
|
|
||||||
|
switch (pid1 = fork()) {
|
||||||
|
case -1:
|
||||||
|
exit(1);
|
||||||
|
case 0:
|
||||||
|
setpgid(0, getpid());
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
setpgid(pid1, pid1);
|
||||||
|
|
||||||
|
sleep(2); /* let first child die */
|
||||||
|
|
||||||
|
if (pipe(fds) < 0)
|
||||||
|
exit(2);
|
||||||
|
|
||||||
|
switch (pid2 = fork()) {
|
||||||
|
case -1:
|
||||||
|
exit(3);
|
||||||
|
case 0:
|
||||||
|
setpgid(0, pid1);
|
||||||
|
ok = getpgID() == pid1;
|
||||||
|
write(fds[1], &ok, 1);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
setpgid(pid2, pid1);
|
||||||
|
|
||||||
|
close(fds[1]);
|
||||||
|
if (read(fds[0], &ok, 1) != 1)
|
||||||
|
exit(4);
|
||||||
|
wait(&status);
|
||||||
|
wait(&status);
|
||||||
|
exit(ok ? 0 : 5);
|
||||||
|
}
|
||||||
|
], bash_cv_pgrp_pipe=no,bash_cv_pgrp_pipe=yes,
|
||||||
|
AC_MSG_ERROR(cannot check pgrp synchronization if cross compiling))
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($bash_cv_pgrp_pipe)
|
||||||
|
if test $bash_cv_pgrp_pipe = yes; then
|
||||||
|
AC_DEFINE(PGRP_PIPE)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl check for typedef'd symbols in header files, but allow the caller to
|
||||||
|
dnl specify the include files to be checked in addition to the default
|
||||||
|
dnl
|
||||||
|
dnl BASH_CHECK_TYPE(TYPE, HEADERS, DEFAULT[, VALUE-IF-FOUND])
|
||||||
|
AC_DEFUN(BASH_CHECK_TYPE,
|
||||||
|
[AC_REQUIRE([AC_HEADER_STDC])dnl
|
||||||
|
AC_MSG_CHECKING(for $1)
|
||||||
|
AC_CACHE_VAL(bash_cv_type_$1,
|
||||||
|
[AC_EGREP_CPP($1, [#include <sys/types.h>
|
||||||
|
#if STDC_HEADERS
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
$2
|
||||||
|
], bash_cv_type_$1=yes, bash_cv_type_$1=no)])
|
||||||
|
AC_MSG_RESULT($bash_cv_type_$1)
|
||||||
|
ifelse($#, 4, [if test $bash_cv_type_$1 = yes; then
|
||||||
|
AC_DEFINE($4)
|
||||||
|
fi])
|
||||||
|
if test $bash_cv_type_$1 = no; then
|
||||||
|
AC_DEFINE($1, $3)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Type of struct rlimit fields: some systems (OSF/1, NetBSD, RISC/os 5.0)
|
||||||
|
dnl have a rlim_t, others (4.4BSD based systems) use quad_t, others use
|
||||||
|
dnl long and still others use int (HP-UX 9.01, SunOS 4.1.3). To simplify
|
||||||
|
dnl matters, this just checks for rlim_t, quad_t, or long.
|
||||||
|
dnl
|
||||||
|
AC_DEFUN(BASH_RLIMIT_TYPE,
|
||||||
|
[AC_MSG_CHECKING(for size and type of struct rlimit fields)
|
||||||
|
AC_CACHE_VAL(bash_cv_type_rlimit,
|
||||||
|
[AC_TRY_COMPILE([#include <sys/types.h>],
|
||||||
|
[rlim_t xxx;], bash_cv_type_rlimit=rlim_t,[
|
||||||
|
AC_TRY_RUN([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
#ifdef HAVE_QUAD_T
|
||||||
|
struct rlimit rl;
|
||||||
|
if (sizeof(rl.rlim_cur) == sizeof(quad_t))
|
||||||
|
exit(0);
|
||||||
|
#endif
|
||||||
|
exit(1);
|
||||||
|
}], bash_cv_type_rlimit=quad_t, bash_cv_type_rlimit=long,
|
||||||
|
AC_MSG_ERROR(cannot check quad_t if cross compiling))])
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($bash_cv_type_rlimit)
|
||||||
|
if test $bash_cv_type_rlimit = quad_t; then
|
||||||
|
AC_DEFINE(RLIMTYPE, quad_t)
|
||||||
|
elif test $bash_cv_type_rlimit = rlim_t; then
|
||||||
|
AC_DEFINE(RLIMTYPE, rlim_t)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Check for sys_siglist[] or _sys_siglist[]
|
||||||
|
dnl
|
||||||
|
AC_DEFUN(BASH_UNDER_SYS_SIGLIST,
|
||||||
|
[AC_MSG_CHECKING([for _sys_siglist in system C library])
|
||||||
|
AC_CACHE_VAL(bash_cv_under_sys_siglist,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifndef _sys_siglist
|
||||||
|
extern char *_sys_siglist[];
|
||||||
|
#endif
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
char *msg = _sys_siglist[2];
|
||||||
|
exit(msg == 0);
|
||||||
|
}],
|
||||||
|
bash_cv_under_sys_siglist=yes, bash_cv_under_sys_siglist=no,
|
||||||
|
AC_MSG_ERROR(cannot check for _sys_siglist[] if cross compiling))])dnl
|
||||||
|
AC_MSG_RESULT($bash_cv_under_sys_siglist)
|
||||||
|
if test $bash_cv_under_sys_siglist = yes; then
|
||||||
|
AC_DEFINE(HAVE_UNDER_SYS_SIGLIST)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_SYS_SIGLIST,
|
||||||
|
[AC_REQUIRE([AC_DECL_SYS_SIGLIST])
|
||||||
|
AC_MSG_CHECKING([for sys_siglist in system C library])
|
||||||
|
AC_CACHE_VAL(bash_cv_sys_siglist,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifndef SYS_SIGLIST_DECLARED
|
||||||
|
extern char *sys_siglist[];
|
||||||
|
#endif
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
char *msg = sys_siglist[2];
|
||||||
|
exit(msg == 0);
|
||||||
|
}],
|
||||||
|
bash_cv_sys_siglist=yes, bash_cv_sys_siglist=no,
|
||||||
|
AC_MSG_ERROR(cannot check for sys_siglist if cross compiling))])dnl
|
||||||
|
AC_MSG_RESULT($bash_cv_sys_siglist)
|
||||||
|
if test $bash_cv_sys_siglist = yes; then
|
||||||
|
AC_DEFINE(HAVE_SYS_SIGLIST)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Check for sys_errlist[] and sys_nerr, check for declaration
|
||||||
|
AC_DEFUN(BASH_SYS_ERRLIST,
|
||||||
|
[AC_MSG_CHECKING([for sys_errlist and sys_nerr])
|
||||||
|
AC_CACHE_VAL(bash_cv_sys_errlist,
|
||||||
|
[AC_TRY_LINK([#include <errno.h>],
|
||||||
|
[extern char *sys_errlist[];
|
||||||
|
extern int sys_nerr;
|
||||||
|
char *msg = sys_errlist[sys_nerr - 1];],
|
||||||
|
bash_cv_sys_errlist=yes, bash_cv_sys_errlist=no)])dnl
|
||||||
|
AC_MSG_RESULT($bash_cv_sys_errlist)
|
||||||
|
if test $bash_cv_sys_errlist = yes; then
|
||||||
|
AC_DEFINE(HAVE_SYS_ERRLIST)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Check to see if opendir will open non-directories (not a nice thing)
|
||||||
|
AC_DEFUN(BASH_FUNC_OPENDIR_CHECK,
|
||||||
|
[AC_REQUIRE([AC_HEADER_DIRENT])dnl
|
||||||
|
AC_MSG_CHECKING(if opendir() opens non-directories)
|
||||||
|
AC_CACHE_VAL(bash_cv_opendir_not_robust,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif /* HAVE_UNISTD_H */
|
||||||
|
#if defined(HAVE_DIRENT_H)
|
||||||
|
# include <dirent.h>
|
||||||
|
#else
|
||||||
|
# define dirent direct
|
||||||
|
# ifdef HAVE_SYS_NDIR_H
|
||||||
|
# include <sys/ndir.h>
|
||||||
|
# endif /* SYSNDIR */
|
||||||
|
# ifdef HAVE_SYS_DIR_H
|
||||||
|
# include <sys/dir.h>
|
||||||
|
# endif /* SYSDIR */
|
||||||
|
# ifdef HAVE_NDIR_H
|
||||||
|
# include <ndir.h>
|
||||||
|
# endif
|
||||||
|
#endif /* HAVE_DIRENT_H */
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
DIR *dir;
|
||||||
|
int fd;
|
||||||
|
unlink("/tmp/not_a_directory");
|
||||||
|
fd = open("/tmp/not_a_directory", O_WRONLY|O_CREAT, 0666);
|
||||||
|
write(fd, "\n", 1);
|
||||||
|
close(fd);
|
||||||
|
dir = opendir("/tmp/not_a_directory");
|
||||||
|
unlink("/tmp/not_a_directory");
|
||||||
|
exit (dir == 0);
|
||||||
|
}], bash_cv_opendir_not_robust=yes,bash_cv_opendir_not_robust=no,
|
||||||
|
AC_MSG_ERROR(cannot check opendir if cross compiling))])
|
||||||
|
AC_MSG_RESULT($bash_cv_opendir_not_robust)
|
||||||
|
if test $bash_cv_opendir_not_robust = yes; then
|
||||||
|
AC_DEFINE(OPENDIR_NOT_ROBUST)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
AC_DEFUN(BASH_TYPE_SIGHANDLER,
|
||||||
|
[AC_MSG_CHECKING([whether signal handlers are of type void])
|
||||||
|
AC_CACHE_VAL(bash_cv_void_sighandler,
|
||||||
|
[AC_TRY_COMPILE([#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#ifdef signal
|
||||||
|
#undef signal
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
void (*signal ()) ();],
|
||||||
|
[int i;], bash_cv_void_sighandler=yes, bash_cv_void_sighandler=no)])dnl
|
||||||
|
AC_MSG_RESULT($bash_cv_void_sighandler)
|
||||||
|
if test $bash_cv_void_sighandler = yes; then
|
||||||
|
AC_DEFINE(VOID_SIGHANDLER)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_FUNC_STRSIGNAL,
|
||||||
|
[AC_MSG_CHECKING([for the existance of strsignal])
|
||||||
|
AC_CACHE_VAL(bash_cv_have_strsignal,
|
||||||
|
[AC_TRY_LINK([#include <sys/types.h>
|
||||||
|
#include <signal.h>],
|
||||||
|
[char *s = (char *)strsignal(2);],
|
||||||
|
bash_cv_have_strsignal=yes, bash_cv_have_strsignal=no)])
|
||||||
|
AC_MSG_RESULT($bash_cv_have_strsignal)
|
||||||
|
if test $bash_cv_have_strsignal = yes; then
|
||||||
|
AC_DEFINE(HAVE_STRSIGNAL)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_FUNC_LSTAT,
|
||||||
|
[dnl Cannot use AC_CHECK_FUNCS(lstat) because Linux defines lstat() as an
|
||||||
|
dnl inline function in <sys/stat.h>.
|
||||||
|
AC_CACHE_CHECK([for lstat], bash_cv_func_lstat,
|
||||||
|
[AC_TRY_LINK([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
],[ lstat("",(struct stat *)0); ],
|
||||||
|
bash_cv_func_lstat=yes, bash_cv_func_lstat=no)])
|
||||||
|
if test $bash_cv_func_lstat = yes; then
|
||||||
|
AC_DEFINE(HAVE_LSTAT)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_STRUCT_TERMIOS_LDISC,
|
||||||
|
[AC_MSG_CHECKING([for a c_line member of struct termios])
|
||||||
|
AC_CACHE_VAL(bash_cv_termios_ldisc,
|
||||||
|
[AC_TRY_COMPILE([#include <sys/types.h>
|
||||||
|
#include <termios.h>],[struct termios t; int i; i = t.c_line;],
|
||||||
|
bash_cv_termios_ldisc=yes, bash_cv_termios_ldisc=no)])dnl
|
||||||
|
AC_MSG_RESULT($bash_cv_termios_ldisc)
|
||||||
|
if test $bash_cv_termios_ldisc = yes; then
|
||||||
|
AC_DEFINE(TERMIOS_LDISC)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_STRUCT_TERMIO_LDISC,
|
||||||
|
[AC_MSG_CHECKING([for a c_line member of struct termio])
|
||||||
|
AC_CACHE_VAL(bash_cv_termio_ldisc,
|
||||||
|
[AC_TRY_COMPILE([#include <sys/types.h>
|
||||||
|
#include <termio.h>],[struct termio t; int i; i = t.c_line;],
|
||||||
|
bash_cv_termio_ldisc=yes, bash_cv_termio_ldisc=no)])dnl
|
||||||
|
AC_MSG_RESULT($bash_cv_termio_ldisc)
|
||||||
|
if test $bash_cv_termio_ldisc = yes; then
|
||||||
|
AC_DEFINE(TERMIO_LDISC)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_FUNC_GETENV,
|
||||||
|
[AC_MSG_CHECKING(to see if getenv can be redefined)
|
||||||
|
AC_CACHE_VAL(bash_cv_getenv_redef,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifndef __STDC__
|
||||||
|
# ifndef const
|
||||||
|
# define const
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
char *
|
||||||
|
getenv (name)
|
||||||
|
#if defined (__linux__) || defined (__bsdi__) || defined (convex)
|
||||||
|
const char *name;
|
||||||
|
#else
|
||||||
|
char const *name;
|
||||||
|
#endif /* !__linux__ && !__bsdi__ && !convex */
|
||||||
|
{
|
||||||
|
return "42";
|
||||||
|
}
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
/* The next allows this program to run, but does not allow bash to link
|
||||||
|
when it redefines getenv. I'm not really interested in figuring out
|
||||||
|
why not. */
|
||||||
|
#if defined (NeXT)
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
s = getenv("ABCDE");
|
||||||
|
exit(s == 0); /* force optimizer to leave getenv in */
|
||||||
|
}
|
||||||
|
], bash_cv_getenv_redef=yes, bash_cv_getenv_redef=no,
|
||||||
|
AC_MSG_ERROR(cannot check getenv redefinition if cross compiling))])
|
||||||
|
AC_MSG_RESULT($bash_cv_getenv_redef)
|
||||||
|
if test $bash_cv_getenv_redef = yes; then
|
||||||
|
AC_DEFINE(CAN_REDEFINE_GETENV)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_FUNC_PRINTF,
|
||||||
|
[AC_MSG_CHECKING(for declaration of printf in <stdio.h>)
|
||||||
|
AC_CACHE_VAL(bash_cv_printf_declared,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#include <stdio.h>
|
||||||
|
#ifdef __STDC__
|
||||||
|
typedef int (*_bashfunc)(const char *, ...);
|
||||||
|
#else
|
||||||
|
typedef int (*_bashfunc)();
|
||||||
|
#endif
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
_bashfunc pf;
|
||||||
|
pf = printf;
|
||||||
|
exit(pf == 0);
|
||||||
|
}
|
||||||
|
],bash_cv_printf_declared=yes, bash_cv_printf_declared=no,
|
||||||
|
AC_MSG_ERROR(cannot check printf declaration if cross compiling))])
|
||||||
|
AC_MSG_RESULT($bash_cv_printf_declared)
|
||||||
|
if test $bash_cv_printf_declared = yes; then
|
||||||
|
AC_DEFINE(PRINTF_DECLARED)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_FUNC_ULIMIT_MAXFDS,
|
||||||
|
[AC_MSG_CHECKING(whether ulimit can substitute for getdtablesize)
|
||||||
|
AC_CACHE_VAL(bash_cv_ulimit_maxfds,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
long maxfds = ulimit(4, 0L);
|
||||||
|
exit (maxfds == -1L);
|
||||||
|
}
|
||||||
|
],bash_cv_ulimit_maxfds=yes, bash_cv_ulimit_maxfds=no,
|
||||||
|
AC_MSG_ERROR(cannot check ulimit if cross compiling))])
|
||||||
|
AC_MSG_RESULT($bash_cv_ulimit_maxfds)
|
||||||
|
if test $bash_cv_ulimit_maxfds = yes; then
|
||||||
|
AC_DEFINE(ULIMIT_MAXFDS)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_CHECK_LIB_TERMCAP,
|
||||||
|
[
|
||||||
|
if test "X$bash_cv_termcap_lib" = "X"; then
|
||||||
|
_bash_needmsg=yes
|
||||||
|
else
|
||||||
|
AC_MSG_CHECKING(which library has the termcap functions)
|
||||||
|
_bash_needmsg=
|
||||||
|
fi
|
||||||
|
AC_CACHE_VAL(bash_cv_termcap_lib,
|
||||||
|
[AC_CHECK_LIB(termcap, tgetent, bash_cv_termcap_lib=libtermcap,
|
||||||
|
[AC_CHECK_LIB(curses, tgetent, bash_cv_termcap_lib=libcurses,
|
||||||
|
[AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses,
|
||||||
|
bash_cv_termcap_lib=gnutermcap)])])])
|
||||||
|
if test "X$_bash_needmsg" = "Xyes"; then
|
||||||
|
AC_MSG_CHECKING(which library has the termcap functions)
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT(using $bash_cv_termcap_lib)
|
||||||
|
if test $bash_cv_termcap_lib = gnutermcap; then
|
||||||
|
LDFLAGS="$LDFLAGS -L./lib/termcap"
|
||||||
|
TERMCAP_LIB="./lib/termcap/libtermcap.a"
|
||||||
|
TERMCAP_DEP="./lib/termcap/libtermcap.a"
|
||||||
|
elif test $bash_cv_termcap_lib = libtermcap; then
|
||||||
|
TERMCAP_LIB=-ltermcap
|
||||||
|
TERMCAP_DEP=
|
||||||
|
elif test $bash_cv_termcap_lib = libncurses; then
|
||||||
|
TERMCAP_LIB=-lncurses
|
||||||
|
TERMCAP_DEP=
|
||||||
|
else
|
||||||
|
TERMCAP_LIB=-lcurses
|
||||||
|
TERMCAP_DEP=
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_FUNC_GETCWD,
|
||||||
|
[AC_MSG_CHECKING([if getcwd() calls popen()])
|
||||||
|
AC_CACHE_VAL(bash_cv_getcwd_calls_popen,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#include <stdio.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __STDC__
|
||||||
|
#ifndef const
|
||||||
|
#define const
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int popen_called;
|
||||||
|
|
||||||
|
FILE *
|
||||||
|
popen(command, type)
|
||||||
|
const char *command;
|
||||||
|
const char *type;
|
||||||
|
{
|
||||||
|
popen_called = 1;
|
||||||
|
return (FILE *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *_popen(command, type)
|
||||||
|
const char *command;
|
||||||
|
const char *type;
|
||||||
|
{
|
||||||
|
return (popen (command, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pclose(stream)
|
||||||
|
FILE *stream;
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_pclose(stream)
|
||||||
|
FILE *stream;
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
char lbuf[32];
|
||||||
|
popen_called = 0;
|
||||||
|
getcwd(lbuf, 32);
|
||||||
|
exit (popen_called);
|
||||||
|
}
|
||||||
|
], bash_cv_getcwd_calls_popen=no, bash_cv_getcwd_calls_popen=yes,
|
||||||
|
AC_MSG_ERROR(cannot check whether getcwd calls popen if cross compiling))])
|
||||||
|
AC_MSG_RESULT($bash_cv_getcwd_calls_popen)
|
||||||
|
if test $bash_cv_getcwd_calls_popen = yes; then
|
||||||
|
AC_DEFINE(GETCWD_BROKEN)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_STRUCT_DIRENT_D_INO,
|
||||||
|
[AC_REQUIRE([AC_HEADER_DIRENT])
|
||||||
|
AC_MSG_CHECKING(if struct dirent has a d_ino member)
|
||||||
|
AC_CACHE_VAL(bash_cv_dirent_has_dino,
|
||||||
|
[AC_TRY_COMPILE([
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif /* HAVE_UNISTD_H */
|
||||||
|
#if defined(HAVE_DIRENT_H)
|
||||||
|
# include <dirent.h>
|
||||||
|
#else
|
||||||
|
# define dirent direct
|
||||||
|
# ifdef HAVE_SYS_NDIR_H
|
||||||
|
# include <sys/ndir.h>
|
||||||
|
# endif /* SYSNDIR */
|
||||||
|
# ifdef HAVE_SYS_DIR_H
|
||||||
|
# include <sys/dir.h>
|
||||||
|
# endif /* SYSDIR */
|
||||||
|
# ifdef HAVE_NDIR_H
|
||||||
|
# include <ndir.h>
|
||||||
|
# endif
|
||||||
|
#endif /* HAVE_DIRENT_H */
|
||||||
|
],[
|
||||||
|
struct dirent d; int z; z = d.d_ino;
|
||||||
|
], bash_cv_dirent_has_dino=yes, bash_cv_dirent_has_dino=no)])
|
||||||
|
AC_MSG_RESULT($bash_cv_dirent_has_dino)
|
||||||
|
if test $bash_cv_dirent_has_dino = yes; then
|
||||||
|
AC_DEFINE(STRUCT_DIRENT_HAS_D_INO)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_REINSTALL_SIGHANDLERS,
|
||||||
|
[AC_REQUIRE([AC_TYPE_SIGNAL])
|
||||||
|
AC_REQUIRE([BASH_SIGNAL_CHECK])
|
||||||
|
AC_MSG_CHECKING([if signal handlers must be reinstalled when invoked])
|
||||||
|
AC_CACHE_VAL(bash_cv_must_reinstall_sighandlers,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#include <signal.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef RETSIGTYPE sigfunc();
|
||||||
|
|
||||||
|
int nsigint;
|
||||||
|
|
||||||
|
#ifdef HAVE_POSIX_SIGNALS
|
||||||
|
sigfunc *
|
||||||
|
set_signal_handler(sig, handler)
|
||||||
|
int sig;
|
||||||
|
sigfunc *handler;
|
||||||
|
{
|
||||||
|
struct sigaction act, oact;
|
||||||
|
act.sa_handler = handler;
|
||||||
|
act.sa_flags = 0;
|
||||||
|
sigemptyset (&act.sa_mask);
|
||||||
|
sigemptyset (&oact.sa_mask);
|
||||||
|
sigaction (sig, &act, &oact);
|
||||||
|
return (oact.sa_handler);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define set_signal_handler(s, h) signal(s, h)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RETSIGTYPE
|
||||||
|
sigint(s)
|
||||||
|
int s;
|
||||||
|
{
|
||||||
|
nsigint++;
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
nsigint = 0;
|
||||||
|
set_signal_handler(SIGINT, sigint);
|
||||||
|
kill((int)getpid(), SIGINT);
|
||||||
|
kill((int)getpid(), SIGINT);
|
||||||
|
exit(nsigint != 2);
|
||||||
|
}
|
||||||
|
], bash_cv_must_reinstall_sighandlers=no, bash_cv_must_reinstall_sighandlers=yes,
|
||||||
|
AC_MSG_ERROR(cannot check signal handling if cross compiling))])
|
||||||
|
AC_MSG_RESULT($bash_cv_must_reinstall_sighandlers)
|
||||||
|
if test $bash_cv_must_reinstall_sighandlers = yes; then
|
||||||
|
AC_DEFINE(MUST_REINSTALL_SIGHANDLERS)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_FUNC_SBRK_DECLARED,
|
||||||
|
[AC_MSG_CHECKING(for declaration of sbrk in <unistd.h>)
|
||||||
|
AC_CACHE_VAL(bash_cv_sbrk_declared,
|
||||||
|
[AC_EGREP_HEADER(sbrk, unistd.h,
|
||||||
|
bash_cv_sbrk_declared=yes, bash_cv_sbrk_declared=no)])
|
||||||
|
AC_MSG_RESULT($bash_cv_sbrk_declared)
|
||||||
|
if test $bash_cv_sbrk_declared = yes; then
|
||||||
|
AC_DEFINE(SBRK_DECLARED)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl check that some necessary job control definitions are present
|
||||||
|
AC_DEFUN(BASH_JOB_CONTROL_MISSING,
|
||||||
|
[AC_REQUIRE([BASH_SIGNAL_CHECK])
|
||||||
|
AC_MSG_CHECKING(for presence of necessary job control definitions)
|
||||||
|
AC_CACHE_VAL(bash_cv_job_control_missing,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_SYS_WAIT_H
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
/* Add more tests in here as appropriate. */
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
/* signal type */
|
||||||
|
#if !defined (HAVE_POSIX_SIGNALS) && !defined (HAVE_BSD_SIGNALS)
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* signals and tty control. */
|
||||||
|
#if !defined (SIGTSTP) || !defined (SIGSTOP) || !defined (SIGCONT)
|
||||||
|
exit (1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* process control */
|
||||||
|
#if !defined (WNOHANG) || !defined (WUNTRACED)
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Posix systems have tcgetpgrp and waitpid. */
|
||||||
|
#if defined (_POSIX_VERSION) && !defined (HAVE_TCGETPGRP)
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (_POSIX_VERSION) && !defined (HAVE_WAITPID)
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Other systems have TIOCSPGRP/TIOCGPRGP and wait3. */
|
||||||
|
#if !defined (_POSIX_VERSION) && !defined (HAVE_WAIT3)
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}],bash_cv_job_control_missing=present, bash_cv_job_control_missing=missing,
|
||||||
|
AC_MSG_ERROR(cannot check job control if cross-compiling))
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($bash_cv_job_control_missing)
|
||||||
|
if test $bash_cv_job_control_missing = missing; then
|
||||||
|
AC_DEFINE(JOB_CONTROL_MISSING)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl check whether named pipes are present
|
||||||
|
dnl this requires a previous check for mkfifo, but that is awkward to specify
|
||||||
|
AC_DEFUN(BASH_SYS_NAMED_PIPES,
|
||||||
|
[AC_MSG_CHECKING(for presence of named pipes)
|
||||||
|
AC_CACHE_VAL(bash_cv_sys_named_pipes,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Add more tests in here as appropriate. */
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
#if defined (HAVE_MKFIFO)
|
||||||
|
exit (0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined (S_IFIFO) && (defined (_POSIX_VERSION) && !defined (S_ISFIFO))
|
||||||
|
exit (1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (NeXT)
|
||||||
|
exit (1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fd = mknod ("/tmp/sh-np-autoconf", 0666 | S_IFIFO, 0);
|
||||||
|
if (fd == -1)
|
||||||
|
exit (1);
|
||||||
|
close(fd);
|
||||||
|
unlink ("/tmp/sh-np-autoconf");
|
||||||
|
exit(0);
|
||||||
|
}],bash_cv_sys_named_pipes=present, bash_cv_sys_named_pipes=missing,
|
||||||
|
AC_MSG_ERROR(cannot check for named pipes if cross-compiling))
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($bash_cv_sys_named_pipes)
|
||||||
|
if test $bash_cv_sys_named_pipes = missing; then
|
||||||
|
AC_DEFINE(NAMED_PIPES_MISSING)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_FUNC_POSIX_SETJMP,
|
||||||
|
[AC_REQUIRE([BASH_SIGNAL_CHECK])
|
||||||
|
AC_MSG_CHECKING(for presence of POSIX-style sigsetjmp/siglongjmp)
|
||||||
|
AC_CACHE_VAL(bash_cv_func_sigsetjmp,
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
#if !defined (_POSIX_VERSION) || !defined (HAVE_POSIX_SIGNALS)
|
||||||
|
exit (1);
|
||||||
|
#else
|
||||||
|
|
||||||
|
int code;
|
||||||
|
sigset_t set, oset;
|
||||||
|
sigjmp_buf xx;
|
||||||
|
|
||||||
|
/* get the mask */
|
||||||
|
sigemptyset(&set);
|
||||||
|
sigemptyset(&oset);
|
||||||
|
sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &set);
|
||||||
|
sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset);
|
||||||
|
|
||||||
|
/* save it */
|
||||||
|
code = sigsetjmp(xx, 1);
|
||||||
|
if (code)
|
||||||
|
exit(0); /* could get sigmask and compare to oset here. */
|
||||||
|
|
||||||
|
/* change it */
|
||||||
|
sigaddset(&set, SIGINT);
|
||||||
|
sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL);
|
||||||
|
|
||||||
|
/* and siglongjmp */
|
||||||
|
siglongjmp(xx, 10);
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
}],bash_cv_func_sigsetjmp=present, bash_cv_func_sigsetjmp=missing,
|
||||||
|
AC_MSG_ERROR(cannot check for sigsetjmp/siglongjmp if cross-compiling))
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($bash_cv_func_sigsetjmp)
|
||||||
|
if test $bash_cv_func_sigsetjmp = present; then
|
||||||
|
AC_DEFINE(HAVE_POSIX_SIGSETJMP)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_HAVE_TIOCGWINSZ,
|
||||||
|
[AC_MSG_CHECKING(for TIOCGWINSZ in sys/ioctl.h)
|
||||||
|
AC_CACHE_VAL(bash_cv_tiocgwinsz_in_ioctl,
|
||||||
|
[AC_TRY_COMPILE([#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>], [int x = TIOCGWINSZ;],
|
||||||
|
bash_cv_tiocgwinsz_in_ioctl=yes,bash_cv_tiocgwinsz_in_ioctl=no)])
|
||||||
|
AC_MSG_RESULT($bash_cv_tiocgwinsz_in_ioctl)
|
||||||
|
if test $bash_cv_tiocgwinsz_in_ioctl = yes; then
|
||||||
|
AC_DEFINE(GWINSZ_IN_SYS_IOCTL)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_HAVE_TIOCSTAT,
|
||||||
|
[AC_MSG_CHECKING(for TIOCSTAT in sys/ioctl.h)
|
||||||
|
AC_CACHE_VAL(bash_cv_tiocstat_in_ioctl,
|
||||||
|
[AC_TRY_COMPILE([#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>], [int x = TIOCSTAT;],
|
||||||
|
bash_cv_tiocstat_in_ioctl=yes,bash_cv_tiocstat_in_ioctl=no)])
|
||||||
|
AC_MSG_RESULT($bash_cv_tiocstat_in_ioctl)
|
||||||
|
if test $bash_cv_tiocstat_in_ioctl = yes; then
|
||||||
|
AC_DEFINE(TIOCSTAT_IN_SYS_IOCTL)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_HAVE_FIONREAD,
|
||||||
|
[AC_MSG_CHECKING(for FIONREAD in sys/ioctl.h)
|
||||||
|
AC_CACHE_VAL(bash_cv_fionread_in_ioctl,
|
||||||
|
[AC_TRY_COMPILE([#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>], [int x = FIONREAD;],
|
||||||
|
bash_cv_fionread_in_ioctl=yes,bash_cv_fionread_in_ioctl=no)])
|
||||||
|
AC_MSG_RESULT($bash_cv_fionread_in_ioctl)
|
||||||
|
if test $bash_cv_fionread_in_ioctl = yes; then
|
||||||
|
AC_DEFINE(FIONREAD_IN_SYS_IOCTL)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_CHECK_GETPW_FUNCS,
|
||||||
|
[AC_MSG_CHECKING(whether programs are able to redeclare getpw functions)
|
||||||
|
AC_CACHE_VAL(bash_cv_can_redecl_getpw,
|
||||||
|
[AC_TRY_COMPILE([#include <sys/types.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
extern struct passwd *getpwent();], [struct passwd *z; z = getpwent();],
|
||||||
|
bash_cv_can_redecl_getpw=yes,bash_cv_can_redecl_getpw=no)])
|
||||||
|
AC_MSG_RESULT($bash_cv_can_redecl_getpw)
|
||||||
|
if test $bash_cv_can_redecl_getpw = no; then
|
||||||
|
AC_DEFINE(HAVE_GETPW_DECLS)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_CHECK_DEV_FD,
|
||||||
|
[AC_MSG_CHECKING(whether /dev/fd is available)
|
||||||
|
AC_CACHE_VAL(bash_cv_dev_fd,
|
||||||
|
[if test -d /dev/fd && test -r /dev/fd/0; then
|
||||||
|
bash_cv_dev_fd=standard
|
||||||
|
elif test -d /proc/self/fd && test -r /proc/self/fd/0; then
|
||||||
|
bash_cv_dev_fd=whacky
|
||||||
|
else
|
||||||
|
bash_cv_dev_fd=absent
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($bash_cv_dev_fd)
|
||||||
|
if test $bash_cv_dev_fd = "standard"; then
|
||||||
|
AC_DEFINE(HAVE_DEV_FD)
|
||||||
|
AC_DEFINE(DEV_FD_PREFIX, "/dev/fd/")
|
||||||
|
elif test $bash_cv_dev_fd = "whacky"; then
|
||||||
|
AC_DEFINE(HAVE_DEV_FD)
|
||||||
|
AC_DEFINE(DEV_FD_PREFIX, "/proc/self/fd/")
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_CHECK_SOCKLIB,
|
||||||
|
[
|
||||||
|
if test "X$bash_cv_have_socklib" = "X"; then
|
||||||
|
_bash_needmsg=
|
||||||
|
else
|
||||||
|
AC_MSG_CHECKING(for socket library)
|
||||||
|
_bash_needmsg=yes
|
||||||
|
fi
|
||||||
|
AC_CACHE_VAL(bash_cv_have_socklib,
|
||||||
|
[AC_CHECK_LIB(socket, getpeername,
|
||||||
|
bash_cv_have_socklib=yes, bash_cv_have_socklib=no, -lnsl)])
|
||||||
|
if test "X$_bash_needmsg" = Xyes; then
|
||||||
|
AC_MSG_RESULT($bash_cv_have_socklib)
|
||||||
|
_bash_needmsg=
|
||||||
|
fi
|
||||||
|
if test $bash_cv_have_socklib = yes; then
|
||||||
|
# check for libnsl, add it to LIBS if present
|
||||||
|
if test "X$bash_cv_have_libnsl" = "X"; then
|
||||||
|
_bash_needmsg=
|
||||||
|
else
|
||||||
|
AC_MSG_CHECKING(for libnsl)
|
||||||
|
_bash_needmsg=yes
|
||||||
|
fi
|
||||||
|
AC_CACHE_VAL(bash_cv_have_libnsl,
|
||||||
|
[AC_CHECK_LIB(nsl, t_open,
|
||||||
|
bash_cv_have_libnsl=yes, bash_cv_have_libnsl=no)])
|
||||||
|
if test "X$_bash_needmsg" = Xyes; then
|
||||||
|
AC_MSG_RESULT($bash_cv_have_libnsl)
|
||||||
|
_bash_needmsg=
|
||||||
|
fi
|
||||||
|
if test $bash_cv_have_libnsl = yes; then
|
||||||
|
LIBS="-lsocket -lnsl $LIBS"
|
||||||
|
else
|
||||||
|
LIBS="-lsocket $LIBS"
|
||||||
|
fi
|
||||||
|
AC_DEFINE(HAVE_LIBSOCKET)
|
||||||
|
AC_DEFINE(HAVE_GETPEERNAME)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(BASH_DEFAULT_MAIL_DIR,
|
||||||
|
[AC_MSG_CHECKING(for default mail directory)
|
||||||
|
AC_CACHE_VAL(bash_cv_mail_dir,
|
||||||
|
[if test -d /var/mail; then
|
||||||
|
bash_cv_mail_dir=/var/mail
|
||||||
|
elif test -d /usr/mail; then
|
||||||
|
bash_cv_mail_dir=/usr/mail
|
||||||
|
elif test -d /usr/spool/mail; then
|
||||||
|
bash_cv_mail_dir=/usr/spool/mail
|
||||||
|
elif test -d /var/spool/mail; then
|
||||||
|
bash_cv_mail_dir=/var/spool/mail
|
||||||
|
else
|
||||||
|
bash_cv_mail_dir=unknown
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($bash_cv_mail_dir)
|
||||||
|
if test $bash_cv_mail_dir = "/var/mail"; then
|
||||||
|
AC_DEFINE(DEFAULT_MAIL_DIRECTORY, "/var/mail")
|
||||||
|
elif test $bash_cv_mail_dir = "/usr/mail"; then
|
||||||
|
AC_DEFINE(DEFAULT_MAIL_DIRECTORY, "/usr/mail")
|
||||||
|
elif test $bash_cv_mail_dir = "/var/spool/mail"; then
|
||||||
|
AC_DEFINE(DEFAULT_MAIL_DIRECTORY, "/var/spool/mail")
|
||||||
|
elif test $bash_cv_mail_dir = "/usr/spool/mail"; then
|
||||||
|
AC_DEFINE(DEFAULT_MAIL_DIRECTORY, "/usr/spool/mail")
|
||||||
|
else
|
||||||
|
AC_DEFINE(DEFAULT_MAIL_DIRECTORY, "unknown")
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Check if HPUX needs _KERNEL defined for RLIMIT_* definitions
|
||||||
|
dnl
|
||||||
|
AC_DEFUN(BASH_KERNEL_RLIMIT_CHECK,
|
||||||
|
[AC_MSG_CHECKING([whether $host_os needs _KERNEL for RLIMIT defines])
|
||||||
|
AC_CACHE_VAL(bash_cv_kernel_rlimit,
|
||||||
|
[AC_TRY_COMPILE([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
],
|
||||||
|
[
|
||||||
|
int f;
|
||||||
|
f = RLIMIT_DATA;
|
||||||
|
], bash_cv_kernel_rlimit=no,
|
||||||
|
[AC_TRY_COMPILE([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#define _KERNEL
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#undef _KERNEL
|
||||||
|
],
|
||||||
|
[
|
||||||
|
int f;
|
||||||
|
f = RLIMIT_DATA;
|
||||||
|
], bash_cv_kernel_rlimit=yes, bash_cv_kernel_rlimit=no)]
|
||||||
|
)])
|
||||||
|
AC_MSG_RESULT($bash_cv_kernel_rlimit)
|
||||||
|
if test $bash_cv_kernel_rlimit = yes; then
|
||||||
|
AC_DEFINE(RLIMIT_NEEDS_KERNEL)
|
||||||
|
fi
|
||||||
|
])
|
||||||
183
alias.c
183
alias.c
@@ -19,12 +19,19 @@
|
|||||||
along with Bash; see the file COPYING. If not, write to the Free
|
along with Bash; see the file COPYING. If not, write to the Free
|
||||||
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined (ALIAS)
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "bashansi.h"
|
#include "bashansi.h"
|
||||||
#include "config.h"
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include "hash.h"
|
#include "externs.h"
|
||||||
#include "alias.h"
|
#include "alias.h"
|
||||||
|
|
||||||
static int qsort_alias_compare ();
|
static int qsort_alias_compare ();
|
||||||
@@ -44,22 +51,18 @@ initialize_aliases ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Scan the list of aliases looking for one with NAME. Return NULL
|
/* Scan the list of aliases looking for one with NAME. Return NULL
|
||||||
if the alias doesn't exist, else a pointer to the assoc. */
|
if the alias doesn't exist, else a pointer to the alias_t. */
|
||||||
ASSOC *
|
alias_t *
|
||||||
find_alias (name)
|
find_alias (name)
|
||||||
char *name;
|
char *name;
|
||||||
{
|
{
|
||||||
BUCKET_CONTENTS *al;
|
BUCKET_CONTENTS *al;
|
||||||
|
|
||||||
if (!aliases)
|
if (aliases == 0)
|
||||||
return ((ASSOC *)NULL);
|
return ((alias_t *)NULL);
|
||||||
else
|
|
||||||
al = find_hash_item (name, aliases);
|
|
||||||
|
|
||||||
if (al)
|
al = find_hash_item (name, aliases);
|
||||||
return ((ASSOC *)al->data);
|
return (al ? (alias_t *)al->data : (alias_t *)NULL);
|
||||||
else
|
|
||||||
return ((ASSOC *)NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the value of the alias for NAME, or NULL if there is none. */
|
/* Return the value of the alias for NAME, or NULL if there is none. */
|
||||||
@@ -67,11 +70,13 @@ char *
|
|||||||
get_alias_value (name)
|
get_alias_value (name)
|
||||||
char *name;
|
char *name;
|
||||||
{
|
{
|
||||||
ASSOC *alias = find_alias (name);
|
alias_t *alias;
|
||||||
if (alias)
|
|
||||||
return (alias->value);
|
if (aliases == 0)
|
||||||
else
|
|
||||||
return ((char *)NULL);
|
return ((char *)NULL);
|
||||||
|
|
||||||
|
alias = find_alias (name);
|
||||||
|
return (alias ? alias->value : (char *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a new alias from NAME and VALUE. If NAME can be found,
|
/* Make a new alias from NAME and VALUE. If NAME can be found,
|
||||||
@@ -80,10 +85,15 @@ void
|
|||||||
add_alias (name, value)
|
add_alias (name, value)
|
||||||
char *name, *value;
|
char *name, *value;
|
||||||
{
|
{
|
||||||
ASSOC *temp = (ASSOC *)NULL;
|
BUCKET_CONTENTS *elt;
|
||||||
|
alias_t *temp;
|
||||||
|
int n;
|
||||||
|
|
||||||
if (!aliases)
|
if (!aliases)
|
||||||
|
{
|
||||||
initialize_aliases ();
|
initialize_aliases ();
|
||||||
|
temp = (alias_t *)NULL;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
temp = find_alias (name);
|
temp = find_alias (name);
|
||||||
|
|
||||||
@@ -91,20 +101,39 @@ add_alias (name, value)
|
|||||||
{
|
{
|
||||||
free (temp->value);
|
free (temp->value);
|
||||||
temp->value = savestring (value);
|
temp->value = savestring (value);
|
||||||
|
n = value[strlen (value) - 1];
|
||||||
|
if (n == ' ' || n == '\t')
|
||||||
|
temp->flags |= AL_EXPANDNEXT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BUCKET_CONTENTS *elt;
|
temp = (alias_t *)xmalloc (sizeof (alias_t));
|
||||||
|
|
||||||
temp = (ASSOC *)xmalloc (sizeof (ASSOC));
|
|
||||||
temp->name = savestring (name);
|
temp->name = savestring (name);
|
||||||
temp->value = savestring (value);
|
temp->value = savestring (value);
|
||||||
|
temp->flags = 0;
|
||||||
|
|
||||||
|
n = value[strlen (value) - 1];
|
||||||
|
if (n == ' ' || n == '\t')
|
||||||
|
temp->flags |= AL_EXPANDNEXT;
|
||||||
|
|
||||||
elt = add_hash_item (savestring (name), aliases);
|
elt = add_hash_item (savestring (name), aliases);
|
||||||
elt->data = (char *)temp;
|
elt->data = (char *)temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Delete a single alias structure. */
|
||||||
|
static void
|
||||||
|
free_alias_data (data)
|
||||||
|
char *data;
|
||||||
|
{
|
||||||
|
register alias_t *a;
|
||||||
|
|
||||||
|
a = (alias_t *)data;
|
||||||
|
free (a->value);
|
||||||
|
free (a->name);
|
||||||
|
free (data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove the alias with name NAME from the alias table. Returns
|
/* Remove the alias with name NAME from the alias table. Returns
|
||||||
the number of aliases left in the table, or -1 if the alias didn't
|
the number of aliases left in the table, or -1 if the alias didn't
|
||||||
exist. */
|
exist. */
|
||||||
@@ -114,93 +143,59 @@ remove_alias (name)
|
|||||||
{
|
{
|
||||||
BUCKET_CONTENTS *elt;
|
BUCKET_CONTENTS *elt;
|
||||||
|
|
||||||
if (!aliases)
|
if (aliases == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
elt = remove_hash_item (name, aliases);
|
elt = remove_hash_item (name, aliases);
|
||||||
if (elt)
|
if (elt)
|
||||||
{
|
{
|
||||||
ASSOC *t;
|
free_alias_data (elt->data);
|
||||||
|
|
||||||
t = (ASSOC *)elt->data;
|
|
||||||
free (t->name);
|
|
||||||
free (t->value);
|
|
||||||
free (elt->key); /* alias name */
|
free (elt->key); /* alias name */
|
||||||
free (t);
|
|
||||||
|
|
||||||
return (aliases->nentries);
|
return (aliases->nentries);
|
||||||
}
|
}
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete a hash bucket chain of aliases. */
|
|
||||||
static void
|
|
||||||
delete_alias_list (alias_list)
|
|
||||||
BUCKET_CONTENTS *alias_list;
|
|
||||||
{
|
|
||||||
register BUCKET_CONTENTS *bp, *temp;
|
|
||||||
register ASSOC *a;
|
|
||||||
|
|
||||||
for (bp = alias_list; bp; )
|
|
||||||
{
|
|
||||||
temp = bp->next;
|
|
||||||
a = (ASSOC *)bp->data;
|
|
||||||
free (a->value);
|
|
||||||
free (a->name);
|
|
||||||
free (bp->data);
|
|
||||||
free (bp->key);
|
|
||||||
free (bp);
|
|
||||||
bp = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete all aliases. */
|
/* Delete all aliases. */
|
||||||
void
|
void
|
||||||
delete_all_aliases ()
|
delete_all_aliases ()
|
||||||
{
|
{
|
||||||
register int i;
|
if (aliases == 0)
|
||||||
|
|
||||||
if (!aliases)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < aliases->nbuckets; i++)
|
flush_hash_table (aliases, free_alias_data);
|
||||||
{
|
|
||||||
register BUCKET_CONTENTS *bp;
|
|
||||||
|
|
||||||
bp = get_hash_bucket (i, aliases);
|
|
||||||
delete_alias_list (bp);
|
|
||||||
}
|
|
||||||
free (aliases);
|
free (aliases);
|
||||||
aliases = (HASH_TABLE *)NULL;
|
aliases = (HASH_TABLE *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return an array of aliases that satisfy the conditions tested by FUNCTION.
|
/* Return an array of aliases that satisfy the conditions tested by FUNCTION.
|
||||||
If FUNCTION is NULL, return all aliases. */
|
If FUNCTION is NULL, return all aliases. */
|
||||||
static ASSOC **
|
static alias_t **
|
||||||
map_over_aliases (function)
|
map_over_aliases (function)
|
||||||
Function *function;
|
Function *function;
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
register BUCKET_CONTENTS *tlist;
|
register BUCKET_CONTENTS *tlist;
|
||||||
ASSOC *alias, **list = (ASSOC **)NULL;
|
alias_t *alias, **list;
|
||||||
int list_index = 0, list_size = 0;
|
int list_index, list_size;
|
||||||
|
|
||||||
for (i = 0; i < aliases->nbuckets; i++)
|
list = (alias_t **)NULL;
|
||||||
|
for (i = list_index = list_size = 0; i < aliases->nbuckets; i++)
|
||||||
{
|
{
|
||||||
tlist = get_hash_bucket (i, aliases);
|
tlist = get_hash_bucket (i, aliases);
|
||||||
|
|
||||||
while (tlist)
|
while (tlist)
|
||||||
{
|
{
|
||||||
alias = (ASSOC *)tlist->data;
|
alias = (alias_t *)tlist->data;
|
||||||
|
|
||||||
if (!function || (*function) (alias))
|
if (!function || (*function) (alias))
|
||||||
{
|
{
|
||||||
if (list_index + 1 >= list_size)
|
if (list_index + 1 >= list_size)
|
||||||
list = (ASSOC **)
|
list = (alias_t **)
|
||||||
xrealloc ((char *)list, (list_size += 20) * sizeof (ASSOC *));
|
xrealloc ((char *)list, (list_size += 20) * sizeof (alias_t *));
|
||||||
|
|
||||||
list[list_index++] = alias;
|
list[list_index++] = alias;
|
||||||
list[list_index] = (ASSOC *)NULL;
|
list[list_index] = (alias_t *)NULL;
|
||||||
}
|
}
|
||||||
tlist = tlist->next;
|
tlist = tlist->next;
|
||||||
}
|
}
|
||||||
@@ -210,14 +205,14 @@ map_over_aliases (function)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
sort_aliases (array)
|
sort_aliases (array)
|
||||||
ASSOC **array;
|
alias_t **array;
|
||||||
{
|
{
|
||||||
qsort (array, array_len ((char **)array), sizeof (ASSOC *), qsort_alias_compare);
|
qsort (array, array_len ((char **)array), sizeof (alias_t *), qsort_alias_compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qsort_alias_compare (as1, as2)
|
qsort_alias_compare (as1, as2)
|
||||||
ASSOC **as1, **as2;
|
alias_t **as1, **as2;
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
@@ -228,13 +223,13 @@ qsort_alias_compare (as1, as2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return a sorted list of all defined aliases */
|
/* Return a sorted list of all defined aliases */
|
||||||
ASSOC **
|
alias_t **
|
||||||
all_aliases ()
|
all_aliases ()
|
||||||
{
|
{
|
||||||
ASSOC **list;
|
alias_t **list;
|
||||||
|
|
||||||
if (!aliases)
|
if (!aliases)
|
||||||
return ((ASSOC **)NULL);
|
return ((alias_t **)NULL);
|
||||||
|
|
||||||
list = map_over_aliases ((Function *)NULL);
|
list = map_over_aliases ((Function *)NULL);
|
||||||
if (list)
|
if (list)
|
||||||
@@ -246,12 +241,10 @@ char *
|
|||||||
alias_expand_word (s)
|
alias_expand_word (s)
|
||||||
char *s;
|
char *s;
|
||||||
{
|
{
|
||||||
ASSOC *r = find_alias (s);
|
alias_t *r;
|
||||||
|
|
||||||
if (r)
|
r = find_alias (s);
|
||||||
return (savestring (r->value));
|
return (r ? savestring (r->value) : (char *)NULL);
|
||||||
else
|
|
||||||
return ((char *)NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return non-zero if CHARACTER is a member of the class of characters
|
/* Return non-zero if CHARACTER is a member of the class of characters
|
||||||
@@ -431,7 +424,7 @@ alias_expand (string)
|
|||||||
register int i, j, start;
|
register int i, j, start;
|
||||||
char *token = xmalloc (line_len);
|
char *token = xmalloc (line_len);
|
||||||
int tl, real_start, expand_next, expand_this_token;
|
int tl, real_start, expand_next, expand_this_token;
|
||||||
ASSOC *alias;
|
alias_t *alias;
|
||||||
|
|
||||||
line[0] = i = 0;
|
line[0] = i = 0;
|
||||||
expand_next = 0;
|
expand_next = 0;
|
||||||
@@ -462,8 +455,7 @@ alias_expand (string)
|
|||||||
expanding it if there is not enough room. */
|
expanding it if there is not enough room. */
|
||||||
j = strlen (line);
|
j = strlen (line);
|
||||||
tl = i - start; /* number of characters just skipped */
|
tl = i - start; /* number of characters just skipped */
|
||||||
if (1 + j + tl >= line_len)
|
RESIZE_MALLOCED_BUFFER (line, j, (tl + 1), line_len, (tl + 50));
|
||||||
line = (char *)xrealloc (line, line_len += (50 + tl));
|
|
||||||
strncpy (line + j, string + start, tl);
|
strncpy (line + j, string + start, tl);
|
||||||
line[j + tl] = '\0';
|
line[j + tl] = '\0';
|
||||||
|
|
||||||
@@ -506,30 +498,35 @@ alias_expand (string)
|
|||||||
(expand_this_token || alias_expand_all) &&
|
(expand_this_token || alias_expand_all) &&
|
||||||
(alias = find_alias (token)))
|
(alias = find_alias (token)))
|
||||||
{
|
{
|
||||||
char *v = alias->value;
|
char *v;
|
||||||
int l = strlen (v);
|
int vlen, llen;
|
||||||
|
|
||||||
|
v = alias->value;
|
||||||
|
vlen = strlen (v);
|
||||||
|
llen = strlen (line);
|
||||||
|
|
||||||
/* +3 because we possibly add one more character below. */
|
/* +3 because we possibly add one more character below. */
|
||||||
if ((l + 3) > line_len - (int)strlen (line))
|
RESIZE_MALLOCED_BUFFER (line, llen, (vlen + 3), line_len, (vlen + 50));
|
||||||
line = (char *)xrealloc (line, line_len += (50 + l));
|
|
||||||
|
|
||||||
strcat (line, v);
|
strcpy (line + llen, v);
|
||||||
|
|
||||||
if ((expand_this_token && l && whitespace (v[l - 1])) ||
|
if ((expand_this_token && vlen && whitespace (v[vlen - 1])) ||
|
||||||
alias_expand_all)
|
alias_expand_all)
|
||||||
expand_next = 1;
|
expand_next = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int ll = strlen (line);
|
int llen, tlen;
|
||||||
int tlen = i - real_start; /* tlen == strlen(token) */
|
|
||||||
|
|
||||||
if (ll + tlen + 2 > line_len)
|
llen = strlen (line);
|
||||||
line = (char *)xrealloc (line, line_len += 50 + ll + tlen);
|
tlen = i - real_start; /* tlen == strlen(token) */
|
||||||
|
|
||||||
strncpy (line + ll, string + real_start, tlen);
|
RESIZE_MALLOCED_BUFFER (line, llen, (tlen + 1), line_len, (llen + tlen + 50));
|
||||||
line[ll + tlen] = '\0';
|
|
||||||
|
strncpy (line + llen, string + real_start, tlen);
|
||||||
|
line[llen + tlen] = '\0';
|
||||||
}
|
}
|
||||||
command_word = 0;
|
command_word = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* ALIAS */
|
||||||
|
|||||||
45
alias.h
45
alias.h
@@ -18,33 +18,22 @@
|
|||||||
along with Bash; see the file COPYING. If not, write to the Free
|
along with Bash; see the file COPYING. If not, write to the Free
|
||||||
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#if !defined (_ALIAS_)
|
#if !defined (_ALIAS_H_)
|
||||||
#define _ALIAS_
|
#define _ALIAS_H_
|
||||||
|
|
||||||
#include "hash.h"
|
#include "hashlib.h"
|
||||||
|
|
||||||
extern char *xmalloc ();
|
extern char *xmalloc ();
|
||||||
|
|
||||||
#if !defined (whitespace)
|
typedef struct alias {
|
||||||
# define whitespace(c) (((c) == ' ') || ((c) == '\t'))
|
|
||||||
#endif /* !whitespace */
|
|
||||||
|
|
||||||
#if !defined (savestring)
|
|
||||||
# define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x))
|
|
||||||
#endif /* !savestring */
|
|
||||||
|
|
||||||
#if !defined (NULL)
|
|
||||||
# if defined (__STDC__)
|
|
||||||
# define NULL ((void *) 0)
|
|
||||||
# else
|
|
||||||
# define NULL 0x0
|
|
||||||
# endif /* !__STDC__ */
|
|
||||||
#endif /* !NULL */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char *name;
|
char *name;
|
||||||
char *value;
|
char *value;
|
||||||
} ASSOC;
|
char flags;
|
||||||
|
} alias_t;
|
||||||
|
|
||||||
|
/* Values for `flags' member of struct alias. */
|
||||||
|
#define AL_EXPANDNEXT 0x1
|
||||||
|
#define AL_BEINGEXPANDED 0x2
|
||||||
|
|
||||||
/* The list of known aliases. */
|
/* The list of known aliases. */
|
||||||
extern HASH_TABLE *aliases;
|
extern HASH_TABLE *aliases;
|
||||||
@@ -52,8 +41,8 @@ extern HASH_TABLE *aliases;
|
|||||||
extern void initialize_aliases ();
|
extern void initialize_aliases ();
|
||||||
|
|
||||||
/* Scan the list of aliases looking for one with NAME. Return NULL
|
/* Scan the list of aliases looking for one with NAME. Return NULL
|
||||||
if the alias doesn't exist, else a pointer to the assoc. */
|
if the alias doesn't exist, else a pointer to the alias. */
|
||||||
extern ASSOC *find_alias ();
|
extern alias_t *find_alias ();
|
||||||
|
|
||||||
/* Return the value of the alias for NAME, or NULL if there is none. */
|
/* Return the value of the alias for NAME, or NULL if there is none. */
|
||||||
extern char *get_alias_value ();
|
extern char *get_alias_value ();
|
||||||
@@ -66,10 +55,16 @@ extern void add_alias ();
|
|||||||
the index of the removed alias, or -1 if the alias didn't exist. */
|
the index of the removed alias, or -1 if the alias didn't exist. */
|
||||||
extern int remove_alias ();
|
extern int remove_alias ();
|
||||||
|
|
||||||
|
/* Remove all aliases. */
|
||||||
|
extern void delete_all_aliases ();
|
||||||
|
|
||||||
/* Return a new line, with any aliases expanded. */
|
/* Return a new line, with any aliases expanded. */
|
||||||
extern char *alias_expand ();
|
extern char *alias_expand ();
|
||||||
|
|
||||||
/* Return an array of all defined aliases. */
|
/* Return an array of all defined aliases. */
|
||||||
extern ASSOC **all_aliases ();
|
extern alias_t **all_aliases ();
|
||||||
|
|
||||||
#endif /* _ALIAS_ */
|
/* Expand a single word for aliases. */
|
||||||
|
extern char *alias_expand_word ();
|
||||||
|
|
||||||
|
#endif /* _ALIAS_H_ */
|
||||||
|
|||||||
602
array.c
Normal file
602
array.c
Normal file
@@ -0,0 +1,602 @@
|
|||||||
|
/*
|
||||||
|
* array.c - functions to create, destroy, access, and manipulate arrays
|
||||||
|
* of strings.
|
||||||
|
*
|
||||||
|
* Arrays are sparse doubly-linked lists. An element's index is stored
|
||||||
|
* with it.
|
||||||
|
*
|
||||||
|
* Chet Ramey
|
||||||
|
* chet@ins.cwru.edu
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "shell.h"
|
||||||
|
#include "array.h"
|
||||||
|
#include "builtins/common.h"
|
||||||
|
|
||||||
|
extern char *quote_string (); /* XXX */
|
||||||
|
|
||||||
|
#define ADD_BEFORE(ae, new) \
|
||||||
|
do { \
|
||||||
|
ae->prev->next = new; \
|
||||||
|
new->prev = ae->prev; \
|
||||||
|
ae->prev = new; \
|
||||||
|
new->next = ae; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate and return a new array element with index INDEX and value
|
||||||
|
* VALUE.
|
||||||
|
*/
|
||||||
|
ARRAY_ELEMENT *
|
||||||
|
new_array_element(indx, value)
|
||||||
|
arrayind_t indx;
|
||||||
|
char *value;
|
||||||
|
{
|
||||||
|
ARRAY_ELEMENT *r;
|
||||||
|
|
||||||
|
r = (ARRAY_ELEMENT *) xmalloc(sizeof(ARRAY_ELEMENT));
|
||||||
|
r->ind = indx;
|
||||||
|
r->value = value ? savestring(value) : (char *)NULL;
|
||||||
|
r->next = r->prev = (ARRAY_ELEMENT *) NULL;
|
||||||
|
return(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
destroy_array_element(ae)
|
||||||
|
ARRAY_ELEMENT *ae;
|
||||||
|
{
|
||||||
|
FREE(ae->value);
|
||||||
|
free(ae);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARRAY *
|
||||||
|
new_array()
|
||||||
|
{
|
||||||
|
ARRAY *r;
|
||||||
|
ARRAY_ELEMENT *head;
|
||||||
|
|
||||||
|
r =(ARRAY *) xmalloc(sizeof(ARRAY));
|
||||||
|
r->type = array_indexed;
|
||||||
|
r->max_index = r->max_size = -1;
|
||||||
|
r->num_elements = 0;
|
||||||
|
head = new_array_element(-1, (char *)NULL); /* dummy head */
|
||||||
|
head->prev = head->next = head;
|
||||||
|
r->head = head;
|
||||||
|
return(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
empty_array (a)
|
||||||
|
ARRAY *a;
|
||||||
|
{
|
||||||
|
register ARRAY_ELEMENT *r, *r1;
|
||||||
|
|
||||||
|
if (a == 0)
|
||||||
|
return;
|
||||||
|
for (r = element_forw(a->head); r != a->head; ) {
|
||||||
|
r1 = element_forw(r);
|
||||||
|
destroy_array_element(r);
|
||||||
|
r = r1;
|
||||||
|
}
|
||||||
|
a->head->next = a->head->prev = a->head;
|
||||||
|
a->max_index = a->max_size = -1;
|
||||||
|
a->num_elements = a->max_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dispose_array(a)
|
||||||
|
ARRAY *a;
|
||||||
|
{
|
||||||
|
if (a == 0)
|
||||||
|
return;
|
||||||
|
empty_array (a);
|
||||||
|
destroy_array_element(a->head);
|
||||||
|
free(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARRAY *
|
||||||
|
dup_array(a)
|
||||||
|
ARRAY *a;
|
||||||
|
{
|
||||||
|
ARRAY *a1;
|
||||||
|
ARRAY_ELEMENT *ae, *new;
|
||||||
|
|
||||||
|
if (!a)
|
||||||
|
return((ARRAY *) NULL);
|
||||||
|
a1 = new_array();
|
||||||
|
a1->type = a->type;
|
||||||
|
a1->max_index = a->max_index;
|
||||||
|
a1->num_elements = a->num_elements;
|
||||||
|
a1->max_size = a->max_size;
|
||||||
|
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
|
||||||
|
new = new_array_element(element_index(ae), element_value(ae));
|
||||||
|
ADD_BEFORE(a1->head, new);
|
||||||
|
}
|
||||||
|
return(a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make and return a new array composed of the elements in array A from
|
||||||
|
* S to E, inclusive.
|
||||||
|
*/
|
||||||
|
ARRAY *
|
||||||
|
dup_array_subrange(array, s, e)
|
||||||
|
ARRAY *array;
|
||||||
|
ARRAY_ELEMENT *s, *e;
|
||||||
|
{
|
||||||
|
ARRAY *a;
|
||||||
|
ARRAY_ELEMENT *p, *n;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
a = new_array ();
|
||||||
|
a->type = array->type;
|
||||||
|
|
||||||
|
for (p = s, i = 0; p != e; p = element_forw(p), i++) {
|
||||||
|
n = new_array_element (i, element_value(p));
|
||||||
|
ADD_BEFORE(a->head, n);
|
||||||
|
}
|
||||||
|
a->num_elements = a->max_index = i;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
ARRAY_ELEMENT *
|
||||||
|
copy_array_element(ae)
|
||||||
|
ARRAY_ELEMENT *ae;
|
||||||
|
{
|
||||||
|
return(ae ? new_array_element(element_index(ae), element_value(ae))
|
||||||
|
: (ARRAY_ELEMENT *) NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a new element with index I and value V to array A (a[i] = v).
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
array_add_element(a, i, v)
|
||||||
|
ARRAY *a;
|
||||||
|
arrayind_t i;
|
||||||
|
char *v;
|
||||||
|
{
|
||||||
|
register ARRAY_ELEMENT *new, *ae;
|
||||||
|
|
||||||
|
if (!a)
|
||||||
|
return(-1);
|
||||||
|
new = new_array_element(i, v);
|
||||||
|
if (i > array_max_index(a)) {
|
||||||
|
/*
|
||||||
|
* Hook onto the end. This also works for an empty array.
|
||||||
|
* Fast path for the common case of allocating arrays
|
||||||
|
* sequentially.
|
||||||
|
*/
|
||||||
|
ADD_BEFORE(a->head, new);
|
||||||
|
a->max_index = i;
|
||||||
|
a->num_elements++;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Otherwise we search for the spot to insert it.
|
||||||
|
*/
|
||||||
|
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
|
||||||
|
if (element_index(ae) == i) {
|
||||||
|
/*
|
||||||
|
* Replacing an existing element.
|
||||||
|
*/
|
||||||
|
destroy_array_element(new);
|
||||||
|
free(element_value(ae));
|
||||||
|
ae->value = savestring(v);
|
||||||
|
return(0);
|
||||||
|
} else if (element_index(ae) > i) {
|
||||||
|
ADD_BEFORE(ae, new);
|
||||||
|
a->num_elements++;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (-1); /* problem */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete the element with index I from array A and return it so the
|
||||||
|
* caller can dispose of it.
|
||||||
|
*/
|
||||||
|
ARRAY_ELEMENT *
|
||||||
|
array_delete_element(a, i)
|
||||||
|
ARRAY *a;
|
||||||
|
arrayind_t i;
|
||||||
|
{
|
||||||
|
register ARRAY_ELEMENT *ae;
|
||||||
|
|
||||||
|
if (!a || array_empty(a))
|
||||||
|
return((ARRAY_ELEMENT *) NULL);
|
||||||
|
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
|
||||||
|
if (element_index(ae) == i) {
|
||||||
|
ae->next->prev = ae->prev;
|
||||||
|
ae->prev->next = ae->next;
|
||||||
|
a->num_elements--;
|
||||||
|
if (i == array_max_index(a))
|
||||||
|
a->max_index = element_index(ae->prev);
|
||||||
|
return(ae);
|
||||||
|
}
|
||||||
|
return((ARRAY_ELEMENT *) NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the value of a[i].
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
array_reference(a, i)
|
||||||
|
ARRAY *a;
|
||||||
|
arrayind_t i;
|
||||||
|
{
|
||||||
|
register ARRAY_ELEMENT *ae;
|
||||||
|
|
||||||
|
if (a == 0 || array_empty(a))
|
||||||
|
return((char *) NULL);
|
||||||
|
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
|
||||||
|
if (element_index(ae) == i)
|
||||||
|
return(element_value(ae));
|
||||||
|
return((char *) NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Walk the array, calling FUNC once for each element, with the array
|
||||||
|
* element as the argument.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
array_walk(a, func)
|
||||||
|
ARRAY *a;
|
||||||
|
Function *func;
|
||||||
|
{
|
||||||
|
register ARRAY_ELEMENT *ae;
|
||||||
|
|
||||||
|
if (a == 0 || array_empty(a))
|
||||||
|
return;
|
||||||
|
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
|
||||||
|
(*func)(ae);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a string that is the concatenation of all the elements in A,
|
||||||
|
* separated by SEP.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
array_to_string_internal (start, end, sep, quoted)
|
||||||
|
ARRAY_ELEMENT *start, *end;
|
||||||
|
char *sep;
|
||||||
|
int quoted;
|
||||||
|
{
|
||||||
|
char *result, *t;
|
||||||
|
ARRAY_ELEMENT *ae;
|
||||||
|
int slen, rsize, rlen, reg;
|
||||||
|
|
||||||
|
if (start == end) /* XXX - should not happen */
|
||||||
|
return ((char *)NULL);
|
||||||
|
|
||||||
|
slen = strlen(sep);
|
||||||
|
for (rsize = rlen = 0, ae = start; ae != end; ae = element_forw(ae)) {
|
||||||
|
if (rsize == 0)
|
||||||
|
result = xmalloc (rsize = 64);
|
||||||
|
if (element_value(ae)) {
|
||||||
|
t = quoted ? quote_string(element_value(ae)) : element_value(ae);
|
||||||
|
reg = strlen(t);
|
||||||
|
RESIZE_MALLOCED_BUFFER (result, rlen, (reg + slen + 2),
|
||||||
|
rsize, rsize);
|
||||||
|
strcpy(result + rlen, t);
|
||||||
|
rlen += reg;
|
||||||
|
if (quoted && t)
|
||||||
|
free(t);
|
||||||
|
/*
|
||||||
|
* Add a separator only after non-null elements.
|
||||||
|
*/
|
||||||
|
if (element_forw(ae) != end) {
|
||||||
|
strcpy(result + rlen, sep);
|
||||||
|
rlen += slen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result[rlen] = '\0'; /* XXX */
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
array_to_string (a, sep, quoted)
|
||||||
|
ARRAY *a;
|
||||||
|
char *sep;
|
||||||
|
int quoted;
|
||||||
|
{
|
||||||
|
if (a == 0)
|
||||||
|
return((char *)NULL);
|
||||||
|
if (array_empty(a))
|
||||||
|
return(savestring(""));
|
||||||
|
return (array_to_string_internal (element_forw(a->head), a->head, sep, quoted));
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
array_to_assignment_string (a)
|
||||||
|
ARRAY *a;
|
||||||
|
{
|
||||||
|
char *result, *indstr, *valstr;
|
||||||
|
ARRAY_ELEMENT *ae;
|
||||||
|
int rsize, rlen, elen;
|
||||||
|
|
||||||
|
if (a == 0 || array_empty (a))
|
||||||
|
return((char *)NULL);
|
||||||
|
|
||||||
|
result = xmalloc (rsize = 128);
|
||||||
|
result[0] = '(';
|
||||||
|
rlen = 1;
|
||||||
|
|
||||||
|
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
|
||||||
|
indstr = itos (element_index(ae));
|
||||||
|
valstr = element_value (ae) ? double_quote (element_value(ae))
|
||||||
|
: (char *)NULL;
|
||||||
|
elen = STRLEN (indstr) + 8 + STRLEN (valstr);
|
||||||
|
RESIZE_MALLOCED_BUFFER (result, rlen, (elen + 1), rsize, rsize);
|
||||||
|
|
||||||
|
result[rlen++] = '[';
|
||||||
|
strcpy (result + rlen, indstr);
|
||||||
|
rlen += STRLEN (indstr);
|
||||||
|
result[rlen++] = ']';
|
||||||
|
result[rlen++] = '=';
|
||||||
|
if (valstr) {
|
||||||
|
strcpy (result + rlen, valstr);
|
||||||
|
rlen += STRLEN (valstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element_forw(ae) != a->head)
|
||||||
|
result[rlen++] = ' ';
|
||||||
|
|
||||||
|
FREE (indstr);
|
||||||
|
FREE (valstr);
|
||||||
|
}
|
||||||
|
RESIZE_MALLOCED_BUFFER (result, rlen, 1, rsize, 8);
|
||||||
|
result[rlen++] = ')';
|
||||||
|
result[rlen] = '\0';
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
quoted_array_assignment_string (a)
|
||||||
|
ARRAY *a;
|
||||||
|
{
|
||||||
|
char *vstr, *sv;
|
||||||
|
|
||||||
|
sv = array_to_assignment_string (a);
|
||||||
|
if (sv == 0)
|
||||||
|
return ((char *)NULL);
|
||||||
|
|
||||||
|
vstr = single_quote (sv);
|
||||||
|
free (sv);
|
||||||
|
return (vstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Determine if s2 occurs in s1. If so, return a pointer to the
|
||||||
|
match in s1. The compare is case sensitive. */
|
||||||
|
static char *
|
||||||
|
sindex (s1, s2)
|
||||||
|
register char *s1, *s2;
|
||||||
|
{
|
||||||
|
register int i, l, len;
|
||||||
|
|
||||||
|
for (i = 0, l = strlen(s2), len = strlen(s1); (len - i) >= l; i++)
|
||||||
|
if (strncmp (s1 + i, s2, l) == 0)
|
||||||
|
return (s1 + i);
|
||||||
|
return ((char *)NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return an array consisting of elements in S, separated by SEP
|
||||||
|
*/
|
||||||
|
ARRAY *
|
||||||
|
string_to_array(s, sep)
|
||||||
|
char *s, *sep;
|
||||||
|
{
|
||||||
|
ARRAY *a;
|
||||||
|
WORD_LIST *w;
|
||||||
|
|
||||||
|
if (s == 0)
|
||||||
|
return((ARRAY *)NULL);
|
||||||
|
w = list_string (s, sep, 0);
|
||||||
|
if (w == 0)
|
||||||
|
return((ARRAY *)NULL);
|
||||||
|
a = word_list_to_array (w);
|
||||||
|
return (a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convenience routines for the shell to translate to and from the form used
|
||||||
|
by the rest of the code. */
|
||||||
|
WORD_LIST *
|
||||||
|
array_to_word_list(a)
|
||||||
|
ARRAY *a;
|
||||||
|
{
|
||||||
|
WORD_LIST *list;
|
||||||
|
ARRAY_ELEMENT *ae;
|
||||||
|
|
||||||
|
if (a == 0 || array_empty(a))
|
||||||
|
return((WORD_LIST *)NULL);
|
||||||
|
list = (WORD_LIST *)NULL;
|
||||||
|
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
|
||||||
|
list = make_word_list (make_bare_word(element_value(ae)), list);
|
||||||
|
return (REVERSE_LIST(list, WORD_LIST *));
|
||||||
|
}
|
||||||
|
|
||||||
|
ARRAY *
|
||||||
|
assign_word_list (array, list)
|
||||||
|
ARRAY *array;
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
register WORD_LIST *l;
|
||||||
|
register arrayind_t i;
|
||||||
|
|
||||||
|
for (l = list, i = 0; l; l = l->next, i++)
|
||||||
|
array_add_element(array, i, l->word->word);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
ARRAY *
|
||||||
|
word_list_to_array (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
ARRAY *a;
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
return((ARRAY *)NULL);
|
||||||
|
a = new_array();
|
||||||
|
return (assign_word_list (a, list));
|
||||||
|
}
|
||||||
|
|
||||||
|
ARRAY *
|
||||||
|
array_quote(array)
|
||||||
|
ARRAY *array;
|
||||||
|
{
|
||||||
|
ARRAY_ELEMENT *a;
|
||||||
|
char *t;
|
||||||
|
|
||||||
|
if (array == 0 || array->head == 0 || array_empty (array))
|
||||||
|
return (ARRAY *)NULL;
|
||||||
|
for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
|
||||||
|
t = quote_string (a->value);
|
||||||
|
FREE(a->value);
|
||||||
|
a->value = t;
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
array_subrange (a, start, end, quoted)
|
||||||
|
ARRAY *a;
|
||||||
|
int start, end, quoted;
|
||||||
|
{
|
||||||
|
ARRAY_ELEMENT *h, *p;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
p = array_head (a);
|
||||||
|
if (p == 0 || array_empty (a) || start > array_num_elements (a))
|
||||||
|
return ((char *)NULL);
|
||||||
|
|
||||||
|
for (i = 0, p = element_forw(p); p != a->head && i < start; i++, p = element_forw(p))
|
||||||
|
;
|
||||||
|
if (p == a->head)
|
||||||
|
return ((char *)NULL);
|
||||||
|
for (h = p; p != a->head && i < end; i++, p = element_forw(p))
|
||||||
|
;
|
||||||
|
|
||||||
|
return (array_to_string_internal (h, p, " ", quoted));
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
array_pat_subst (a, pat, rep, mflags)
|
||||||
|
ARRAY *a;
|
||||||
|
char *pat, *rep;
|
||||||
|
int mflags;
|
||||||
|
{
|
||||||
|
ARRAY *a2;
|
||||||
|
ARRAY_ELEMENT *e;
|
||||||
|
char *t;
|
||||||
|
|
||||||
|
if (array_head (a) == 0 || array_empty (a))
|
||||||
|
return ((char *)NULL);
|
||||||
|
|
||||||
|
a2 = dup_array (a);
|
||||||
|
for (e = element_forw(a2->head); e != a2->head; e = element_forw(e)) {
|
||||||
|
t = pat_subst(element_value(e), pat, rep, mflags);
|
||||||
|
FREE(element_value(e));
|
||||||
|
e->value = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mflags & MATCH_QUOTED)
|
||||||
|
array_quote (a2);
|
||||||
|
t = array_to_string (a2, " ", 0);
|
||||||
|
dispose_array (a2);
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (TEST_ARRAY)
|
||||||
|
print_element(ae)
|
||||||
|
ARRAY_ELEMENT *ae;
|
||||||
|
{
|
||||||
|
printf("array[%d] = %s\n",(int)element_index(ae), element_value(ae));
|
||||||
|
}
|
||||||
|
|
||||||
|
print_array(a)
|
||||||
|
ARRAY *a;
|
||||||
|
{
|
||||||
|
printf("\n");
|
||||||
|
array_walk(a, print_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
ARRAY *a, *new_a, *copy_of_a;
|
||||||
|
ARRAY_ELEMENT *ae;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
a = new_array();
|
||||||
|
array_add_element(a, 1, "one");
|
||||||
|
array_add_element(a, 7, "seven");
|
||||||
|
array_add_element(a, 4, "four");
|
||||||
|
array_add_element(a, 1029, "one thousand twenty-nine");
|
||||||
|
array_add_element(a, 12, "twelve");
|
||||||
|
array_add_element(a, 42, "forty-two");
|
||||||
|
print_array(a);
|
||||||
|
s = array_to_string (a, " ");
|
||||||
|
printf("s = %s\n", s);
|
||||||
|
copy_of_a = string_to_array(s, " ");
|
||||||
|
printf("copy_of_a:");
|
||||||
|
print_array(copy_of_a);
|
||||||
|
dispose_array(copy_of_a);
|
||||||
|
printf("\n");
|
||||||
|
free(s);
|
||||||
|
ae = array_delete_element(a, 4);
|
||||||
|
destroy_array_element(ae);
|
||||||
|
ae = array_delete_element(a, 1029);
|
||||||
|
destroy_array_element(ae);
|
||||||
|
array_add_element(a, 16, "sixteen");
|
||||||
|
print_array(a);
|
||||||
|
s = array_to_string (a, " ");
|
||||||
|
printf("s = %s\n", s);
|
||||||
|
copy_of_a = string_to_array(s, " ");
|
||||||
|
printf("copy_of_a:");
|
||||||
|
print_array(copy_of_a);
|
||||||
|
dispose_array(copy_of_a);
|
||||||
|
printf("\n");
|
||||||
|
free(s);
|
||||||
|
array_add_element(a, 2, "two");
|
||||||
|
array_add_element(a, 1029, "new one thousand twenty-nine");
|
||||||
|
array_add_element(a, 0, "zero");
|
||||||
|
array_add_element(a, 134, "");
|
||||||
|
print_array(a);
|
||||||
|
s = array_to_string (a, ":");
|
||||||
|
printf("s = %s\n", s);
|
||||||
|
copy_of_a = string_to_array(s, ":");
|
||||||
|
printf("copy_of_a:");
|
||||||
|
print_array(copy_of_a);
|
||||||
|
dispose_array(copy_of_a);
|
||||||
|
printf("\n");
|
||||||
|
free(s);
|
||||||
|
new_a = copy_array(a);
|
||||||
|
print_array(new_a);
|
||||||
|
s = array_to_string (new_a, ":");
|
||||||
|
printf("s = %s\n", s);
|
||||||
|
copy_of_a = string_to_array(s, ":");
|
||||||
|
printf("copy_of_a:");
|
||||||
|
print_array(copy_of_a);
|
||||||
|
dispose_array(copy_of_a);
|
||||||
|
printf("\n");
|
||||||
|
free(s);
|
||||||
|
dispose_array(a);
|
||||||
|
dispose_array(new_a);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TEST_ARRAY */
|
||||||
|
#endif /* ARRAY_VARS */
|
||||||
66
array.h
Normal file
66
array.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/* array.h -- definitions for the interface exported by array.c that allows
|
||||||
|
the rest of the shell to manipulate array variables. */
|
||||||
|
#ifndef _ARRAY_H_
|
||||||
|
#define _ARRAY_H_
|
||||||
|
|
||||||
|
#include "stdc.h"
|
||||||
|
|
||||||
|
typedef int arrayind_t;
|
||||||
|
|
||||||
|
enum atype {array_indexed, array_assoc};
|
||||||
|
|
||||||
|
typedef struct array {
|
||||||
|
enum atype type;
|
||||||
|
arrayind_t max_index, num_elements, max_size;
|
||||||
|
struct array_element *head;
|
||||||
|
} ARRAY;
|
||||||
|
|
||||||
|
typedef struct array_element {
|
||||||
|
arrayind_t ind;
|
||||||
|
char *value;
|
||||||
|
struct array_element *next, *prev;
|
||||||
|
} ARRAY_ELEMENT;
|
||||||
|
|
||||||
|
char *array_reference __P((ARRAY *, arrayind_t));
|
||||||
|
|
||||||
|
extern int array_add_element __P((ARRAY *, arrayind_t, char *));
|
||||||
|
extern ARRAY_ELEMENT *array_delete_element __P((ARRAY *, arrayind_t));
|
||||||
|
|
||||||
|
extern ARRAY_ELEMENT *new_array_element __P((arrayind_t, char *));
|
||||||
|
extern void destroy_array_element __P((ARRAY_ELEMENT *));
|
||||||
|
|
||||||
|
extern ARRAY *new_array __P((void));
|
||||||
|
extern void empty_array __P((ARRAY *));
|
||||||
|
extern void dispose_array __P((ARRAY *));
|
||||||
|
extern ARRAY *dup_array __P((ARRAY *));
|
||||||
|
extern ARRAY *dup_array_subrange __P((ARRAY *, ARRAY_ELEMENT *, ARRAY_ELEMENT *));
|
||||||
|
extern ARRAY_ELEMENT *new_array_element __P((arrayind_t, char *));
|
||||||
|
extern ARRAY_ELEMENT *copy_array_element __P((ARRAY_ELEMENT *));
|
||||||
|
|
||||||
|
extern WORD_LIST *array_to_word_list __P((ARRAY *));
|
||||||
|
extern ARRAY *word_list_to_array __P((WORD_LIST *));
|
||||||
|
extern ARRAY *assign_word_list __P((ARRAY *, WORD_LIST *));
|
||||||
|
|
||||||
|
extern char *array_to_assignment_string __P((ARRAY *));
|
||||||
|
extern char *quoted_array_assignment_string __P((ARRAY *));
|
||||||
|
extern char *array_to_string __P((ARRAY *, char *, int));
|
||||||
|
extern ARRAY *string_to_array __P((char *, char *));
|
||||||
|
|
||||||
|
extern char *array_subrange __P((ARRAY *, int, int, int));
|
||||||
|
extern char *array_pat_subst __P((ARRAY *, char *, char *, int));
|
||||||
|
|
||||||
|
extern ARRAY *array_quote __P((ARRAY *));
|
||||||
|
|
||||||
|
#define array_num_elements(a) ((a)->num_elements)
|
||||||
|
#define array_max_index(a) ((a)->max_index)
|
||||||
|
#define array_head(a) ((a)->head)
|
||||||
|
#define array_empty(a) ((a)->num_elements == 0)
|
||||||
|
|
||||||
|
#define element_value(ae) ((ae)->value)
|
||||||
|
#define element_index(ae) ((ae)->ind)
|
||||||
|
#define element_forw(ae) ((ae)->next)
|
||||||
|
#define element_back(ae) ((ae)->prev)
|
||||||
|
|
||||||
|
#define ALL_ELEMENT_SUB(c) ((c) == '@' || (c) == '*')
|
||||||
|
|
||||||
|
#endif /* _ARRAY_H_ */
|
||||||
417
bashhist.c
417
bashhist.c
@@ -18,7 +18,15 @@
|
|||||||
with Bash; see the file COPYING. If not, write to the Free Software
|
with Bash; see the file COPYING. If not, write to the Free Software
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined (HISTORY)
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bashtypes.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "bashansi.h"
|
#include "bashansi.h"
|
||||||
@@ -26,7 +34,33 @@
|
|||||||
#include "filecntl.h"
|
#include "filecntl.h"
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
#include "input.h"
|
||||||
|
#include "parser.h" /* for the struct dstack stuff. */
|
||||||
|
#include "pathexp.h" /* for the struct ignorevar stuff */
|
||||||
|
#include "builtins/common.h"
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
|
#include <glob/fnmatch.h>
|
||||||
|
|
||||||
|
#if defined (READLINE)
|
||||||
|
# include "bashline.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined (errno)
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int histignore_item_func ();
|
||||||
|
|
||||||
|
static struct ignorevar histignore =
|
||||||
|
{
|
||||||
|
"HISTIGNORE",
|
||||||
|
(struct ign *)0,
|
||||||
|
0,
|
||||||
|
(char *)0,
|
||||||
|
(Function *)histignore_item_func,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HIGN_EXPAND 0x01
|
||||||
|
|
||||||
/* Declarations of bash history variables. */
|
/* Declarations of bash history variables. */
|
||||||
/* Non-zero means to remember lines typed to the shell on the history
|
/* Non-zero means to remember lines typed to the shell on the history
|
||||||
@@ -35,14 +69,16 @@
|
|||||||
int remember_on_history = 1;
|
int remember_on_history = 1;
|
||||||
|
|
||||||
/* The number of lines that Bash has added to this history session. */
|
/* The number of lines that Bash has added to this history session. */
|
||||||
int history_lines_this_session = 0;
|
int history_lines_this_session;
|
||||||
|
|
||||||
/* The number of lines that Bash has read from the history file. */
|
/* The number of lines that Bash has read from the history file. */
|
||||||
int history_lines_in_file = 0;
|
int history_lines_in_file;
|
||||||
|
|
||||||
|
#if defined (BANG_HISTORY)
|
||||||
/* Non-zero means do no history expansion on this line, regardless
|
/* Non-zero means do no history expansion on this line, regardless
|
||||||
of what history_expansion says. */
|
of what history_expansion says. */
|
||||||
int history_expansion_inhibited = 0;
|
int history_expansion_inhibited;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* By default, every line is saved in the history individually. I.e.,
|
/* By default, every line is saved in the history individually. I.e.,
|
||||||
if the user enters:
|
if the user enters:
|
||||||
@@ -72,75 +108,158 @@ int history_expansion_inhibited = 0;
|
|||||||
The user can then recall the whole command all at once instead
|
The user can then recall the whole command all at once instead
|
||||||
of just being able to recall one line at a time.
|
of just being able to recall one line at a time.
|
||||||
*/
|
*/
|
||||||
int command_oriented_history = 0;
|
int command_oriented_history = 1;
|
||||||
|
|
||||||
|
/* Non-zero means to store newlines in the history list when using
|
||||||
|
command_oriented_history rather than trying to use semicolons. */
|
||||||
|
int literal_history;
|
||||||
|
|
||||||
|
/* Non-zero means to append the history to the history file at shell
|
||||||
|
exit, even if the history has been stifled. */
|
||||||
|
int force_append_history;
|
||||||
|
|
||||||
/* A nit for picking at history saving.
|
/* A nit for picking at history saving.
|
||||||
Value of 0 means save all lines parsed by the shell on the history.
|
Value of 0 means save all lines parsed by the shell on the history.
|
||||||
Value of 1 means save all lines that do not start with a space.
|
Value of 1 means save all lines that do not start with a space.
|
||||||
Value of 2 means save all lines that do not match the last line saved. */
|
Value of 2 means save all lines that do not match the last line saved. */
|
||||||
int history_control = 0;
|
int history_control;
|
||||||
|
|
||||||
|
#if defined (READLINE)
|
||||||
|
/* If non-zero, and readline is being used, the user is offered the
|
||||||
|
chance to re-edit a failed history expansion. */
|
||||||
|
int history_reediting;
|
||||||
|
|
||||||
|
/* If non-zero, and readline is being used, don't directly execute a
|
||||||
|
line with history substitution. Reload it into the editing buffer
|
||||||
|
instead and let the user further edit and confirm with a newline. */
|
||||||
|
int hist_verify;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Variables declared in other files used here. */
|
/* Variables declared in other files used here. */
|
||||||
extern int interactive;
|
extern int interactive;
|
||||||
extern int current_command_line_count;
|
extern int current_command_line_count;
|
||||||
extern int delimiter_depth;
|
|
||||||
|
|
||||||
|
extern struct dstack dstack;
|
||||||
|
|
||||||
|
extern char *extract_colon_unit ();
|
||||||
extern char *history_delimiting_chars ();
|
extern char *history_delimiting_chars ();
|
||||||
extern void maybe_add_history (); /* forward declaration */
|
extern void maybe_add_history (); /* forward declaration */
|
||||||
|
|
||||||
static void bash_add_history ();
|
static void bash_add_history ();
|
||||||
|
static int history_should_ignore ();
|
||||||
|
|
||||||
|
void
|
||||||
|
bash_initialize_history ()
|
||||||
|
{
|
||||||
|
history_quotes_inhibit_expansion = 1;
|
||||||
|
history_search_delimiter_chars = ";&()|<>";
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bash_history_reinit (interact)
|
||||||
|
int interact;
|
||||||
|
{
|
||||||
|
#if defined (BANG_HISTORY)
|
||||||
|
history_expansion = interact != 0;
|
||||||
|
history_expansion_inhibited = 1;
|
||||||
|
#endif
|
||||||
|
remember_on_history = interact != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bash_history_disable ()
|
||||||
|
{
|
||||||
|
remember_on_history = 0;
|
||||||
|
#if defined (BANG_HISTORY)
|
||||||
|
history_expansion_inhibited = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bash_history_enable ()
|
||||||
|
{
|
||||||
|
remember_on_history = 1;
|
||||||
|
#if defined (BANG_HISTORY)
|
||||||
|
history_expansion_inhibited = 0;
|
||||||
|
#endif
|
||||||
|
sv_history_control ("HISTCONTROL");
|
||||||
|
sv_histignore ("HISTIGNORE");
|
||||||
|
}
|
||||||
|
|
||||||
/* Load the history list from the history file. */
|
/* Load the history list from the history file. */
|
||||||
void
|
void
|
||||||
load_history ()
|
load_history ()
|
||||||
{
|
{
|
||||||
char *hf;
|
char *hf;
|
||||||
|
struct stat buf;
|
||||||
|
|
||||||
/* Truncate history file for interactive shells which desire it.
|
/* Truncate history file for interactive shells which desire it.
|
||||||
Note that the history file is automatically truncated to the
|
Note that the history file is automatically truncated to the
|
||||||
size of HISTSIZE if the user does not explicitly set the size
|
size of HISTSIZE if the user does not explicitly set the size
|
||||||
differently. */
|
differently. */
|
||||||
set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
|
set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
|
||||||
stupidly_hack_special_variables ("HISTFILESIZE");
|
sv_histsize ("HISTFILESIZE");
|
||||||
|
|
||||||
/* Read the history in HISTFILE into the history list. */
|
/* Read the history in HISTFILE into the history list. */
|
||||||
hf = get_string_value ("HISTFILE");
|
hf = get_string_value ("HISTFILE");
|
||||||
|
|
||||||
if (hf && *hf)
|
if (hf && *hf && stat (hf, &buf) == 0)
|
||||||
{
|
|
||||||
struct stat buf;
|
|
||||||
|
|
||||||
if (stat (hf, &buf) == 0)
|
|
||||||
{
|
{
|
||||||
read_history (hf);
|
read_history (hf);
|
||||||
using_history ();
|
using_history ();
|
||||||
history_lines_in_file = where_history ();
|
history_lines_in_file = where_history ();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the existing history out to the history file. */
|
/* Write the existing history out to the history file. */
|
||||||
void
|
void
|
||||||
save_history ()
|
save_history ()
|
||||||
{
|
{
|
||||||
char *hf = get_string_value ("HISTFILE");
|
char *hf;
|
||||||
|
|
||||||
if (hf && *hf)
|
|
||||||
{
|
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
|
||||||
if (stat (hf, &buf) == 0)
|
hf = get_string_value ("HISTFILE");
|
||||||
|
if (hf && *hf && stat (hf, &buf) == 0)
|
||||||
{
|
{
|
||||||
/* Append only the lines that occurred this session to
|
/* Append only the lines that occurred this session to
|
||||||
the history file. */
|
the history file. */
|
||||||
using_history ();
|
using_history ();
|
||||||
|
|
||||||
if (history_lines_this_session < where_history ())
|
if (history_lines_this_session < where_history () || force_append_history)
|
||||||
append_history (history_lines_this_session, hf);
|
append_history (history_lines_this_session, hf);
|
||||||
else
|
else
|
||||||
write_history (hf);
|
write_history (hf);
|
||||||
|
|
||||||
|
sv_histsize ("HISTFILESIZE");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
maybe_append_history (filename)
|
||||||
|
char *filename;
|
||||||
|
{
|
||||||
|
int fd, result;
|
||||||
|
struct stat buf;
|
||||||
|
|
||||||
|
result = EXECUTION_SUCCESS;
|
||||||
|
if (history_lines_this_session && (history_lines_this_session < where_history ()))
|
||||||
|
{
|
||||||
|
/* If the filename was supplied, then create it if necessary. */
|
||||||
|
if (stat (filename, &buf) == -1 && errno == ENOENT)
|
||||||
|
{
|
||||||
|
fd = open (filename, O_WRONLY|O_CREAT, 0666);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
builtin_error ("%s: cannot create: %s", filename, strerror (errno));
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
result = append_history (history_lines_this_session, filename);
|
||||||
|
history_lines_in_file += history_lines_this_session;
|
||||||
|
history_lines_this_session = 0;
|
||||||
|
}
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is an interactive shell, then append the lines executed
|
/* If this is an interactive shell, then append the lines executed
|
||||||
@@ -148,20 +267,22 @@ save_history ()
|
|||||||
int
|
int
|
||||||
maybe_save_shell_history ()
|
maybe_save_shell_history ()
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result;
|
||||||
|
char *hf;
|
||||||
|
struct stat buf;
|
||||||
|
|
||||||
|
result = 0;
|
||||||
if (history_lines_this_session)
|
if (history_lines_this_session)
|
||||||
{
|
{
|
||||||
char *hf = get_string_value ("HISTFILE");
|
hf = get_string_value ("HISTFILE");
|
||||||
|
|
||||||
if (hf && *hf)
|
if (hf && *hf)
|
||||||
{
|
{
|
||||||
struct stat buf;
|
|
||||||
|
|
||||||
/* If the file doesn't exist, then create it. */
|
/* If the file doesn't exist, then create it. */
|
||||||
if (stat (hf, &buf) == -1)
|
if (stat (hf, &buf) == -1)
|
||||||
{
|
{
|
||||||
int file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0666);
|
int file;
|
||||||
|
file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0666);
|
||||||
if (file != -1)
|
if (file != -1)
|
||||||
close (file);
|
close (file);
|
||||||
}
|
}
|
||||||
@@ -170,7 +291,7 @@ maybe_save_shell_history ()
|
|||||||
stifled. If the history has been stifled, rewrite the
|
stifled. If the history has been stifled, rewrite the
|
||||||
history file. */
|
history file. */
|
||||||
using_history ();
|
using_history ();
|
||||||
if (history_lines_this_session <= where_history ())
|
if (history_lines_this_session <= where_history () || force_append_history)
|
||||||
{
|
{
|
||||||
result = append_history (history_lines_this_session, hf);
|
result = append_history (history_lines_this_session, hf);
|
||||||
history_lines_in_file += history_lines_this_session;
|
history_lines_in_file += history_lines_this_session;
|
||||||
@@ -181,23 +302,36 @@ maybe_save_shell_history ()
|
|||||||
history_lines_in_file = history_lines_this_session;
|
history_lines_in_file = history_lines_this_session;
|
||||||
}
|
}
|
||||||
history_lines_this_session = 0;
|
history_lines_this_session = 0;
|
||||||
|
|
||||||
|
sv_histsize ("HISTFILESIZE");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (HISTORY_REEDITING)
|
#if defined (READLINE)
|
||||||
/* Tell readline () that we have some text for it to edit. */
|
/* Tell readline () that we have some text for it to edit. */
|
||||||
static void
|
static void
|
||||||
re_edit (text)
|
re_edit (text)
|
||||||
char *text;
|
char *text;
|
||||||
{
|
{
|
||||||
#if defined (READLINE)
|
if (bash_input.type == st_stdin)
|
||||||
if (strcmp (bash_input.name, "readline stdin") == 0)
|
|
||||||
bash_re_edit (text);
|
bash_re_edit (text);
|
||||||
#endif /* READLINE */
|
|
||||||
}
|
}
|
||||||
#endif /* HISTORY_REEDITING */
|
#endif /* READLINE */
|
||||||
|
|
||||||
|
/* Return 1 if this line needs history expansion. */
|
||||||
|
static int
|
||||||
|
history_expansion_p (line)
|
||||||
|
char *line;
|
||||||
|
{
|
||||||
|
register char *s;
|
||||||
|
|
||||||
|
for (s = line; *s; s++)
|
||||||
|
if (*s == history_expansion_char || *s == history_subst_char)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then
|
/* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then
|
||||||
print the results of expanding the line if there were any changes.
|
print the results of expanding the line if there were any changes.
|
||||||
@@ -213,14 +347,15 @@ pre_process_line (line, print_changes, addit)
|
|||||||
{
|
{
|
||||||
char *history_value;
|
char *history_value;
|
||||||
char *return_value;
|
char *return_value;
|
||||||
int expanded = 0;
|
int expanded;
|
||||||
|
|
||||||
return_value = line;
|
return_value = line;
|
||||||
|
expanded = 0;
|
||||||
|
|
||||||
# if defined (BANG_HISTORY)
|
# if defined (BANG_HISTORY)
|
||||||
/* History expand the line. If this results in no errors, then
|
/* History expand the line. If this results in no errors, then
|
||||||
add that line to the history if ADDIT is non-zero. */
|
add that line to the history if ADDIT is non-zero. */
|
||||||
if (!history_expansion_inhibited && history_expansion)
|
if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
|
||||||
{
|
{
|
||||||
expanded = history_expand (line, &history_value);
|
expanded = history_expand (line, &history_value);
|
||||||
|
|
||||||
@@ -230,7 +365,7 @@ pre_process_line (line, print_changes, addit)
|
|||||||
{
|
{
|
||||||
if (expanded < 0)
|
if (expanded < 0)
|
||||||
internal_error (history_value);
|
internal_error (history_value);
|
||||||
else
|
else if (hist_verify == 0)
|
||||||
fprintf (stderr, "%s\n", history_value);
|
fprintf (stderr, "%s\n", history_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,13 +374,22 @@ pre_process_line (line, print_changes, addit)
|
|||||||
{
|
{
|
||||||
free (history_value);
|
free (history_value);
|
||||||
|
|
||||||
# if defined (HISTORY_REEDITING)
|
# if defined (READLINE)
|
||||||
/* New hack. We can allow the user to edit the
|
/* New hack. We can allow the user to edit the
|
||||||
failed history expansion. */
|
failed history expansion. */
|
||||||
|
if (history_reediting && expanded < 0)
|
||||||
re_edit (line);
|
re_edit (line);
|
||||||
# endif /* HISTORY_REEDITING */
|
# endif /* READLINE */
|
||||||
return ((char *)NULL);
|
return ((char *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if defined (READLINE)
|
||||||
|
if (hist_verify && expanded == 1)
|
||||||
|
{
|
||||||
|
re_edit (history_value);
|
||||||
|
return ((char *)NULL);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Let other expansions know that return_value can be free'ed,
|
/* Let other expansions know that return_value can be free'ed,
|
||||||
@@ -259,7 +403,7 @@ pre_process_line (line, print_changes, addit)
|
|||||||
if (addit && remember_on_history && *return_value)
|
if (addit && remember_on_history && *return_value)
|
||||||
maybe_add_history (return_value);
|
maybe_add_history (return_value);
|
||||||
|
|
||||||
if (!expanded)
|
if (expanded == 0)
|
||||||
return_value = savestring (line);
|
return_value = savestring (line);
|
||||||
|
|
||||||
return (return_value);
|
return (return_value);
|
||||||
@@ -270,43 +414,46 @@ void
|
|||||||
maybe_add_history (line)
|
maybe_add_history (line)
|
||||||
char *line;
|
char *line;
|
||||||
{
|
{
|
||||||
int h;
|
int should_add;
|
||||||
|
HIST_ENTRY *temp;
|
||||||
|
|
||||||
|
should_add = 0;
|
||||||
|
|
||||||
/* Don't use the value of history_control to affect the second
|
/* Don't use the value of history_control to affect the second
|
||||||
and subsequent lines of a multi-line command when
|
and subsequent lines of a multi-line command when
|
||||||
command_oriented_history is enabled. */
|
command_oriented_history is enabled. */
|
||||||
if (command_oriented_history && current_command_line_count > 1)
|
if (command_oriented_history && current_command_line_count > 1)
|
||||||
h = 0;
|
{
|
||||||
else
|
bash_add_history (line);
|
||||||
h = history_control;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (h)
|
switch (history_control)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
bash_add_history (line);
|
should_add = 1;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (*line != ' ')
|
if (*line != ' ')
|
||||||
bash_add_history (line);
|
should_add = 1;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (*line == ' ')
|
if (*line == ' ')
|
||||||
break;
|
break;
|
||||||
/* FALLTHROUGH if case == 3 (`ignoreboth') */
|
/* FALLTHROUGH if case == 3 (`ignoreboth') */
|
||||||
case 2:
|
case 2:
|
||||||
{
|
|
||||||
HIST_ENTRY *temp;
|
|
||||||
|
|
||||||
using_history ();
|
using_history ();
|
||||||
temp = previous_history ();
|
temp = previous_history ();
|
||||||
|
|
||||||
if (!temp || (STREQ (temp->line, line) == 0))
|
if (temp == 0 || STREQ (temp->line, line) == 0)
|
||||||
bash_add_history (line);
|
should_add = 1;
|
||||||
|
|
||||||
using_history ();
|
using_history ();
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (should_add && history_should_ignore (line) == 0)
|
||||||
|
bash_add_history (line);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a line to the history list.
|
/* Add a line to the history list.
|
||||||
@@ -318,18 +465,16 @@ static void
|
|||||||
bash_add_history (line)
|
bash_add_history (line)
|
||||||
char *line;
|
char *line;
|
||||||
{
|
{
|
||||||
int add_it = 1;
|
int add_it, offset, curlen;
|
||||||
|
HIST_ENTRY *current, *old;
|
||||||
if (command_oriented_history && current_command_line_count > 1)
|
|
||||||
{
|
|
||||||
register int offset;
|
|
||||||
register HIST_ENTRY *current, *old;
|
|
||||||
char *chars_to_add, *new_line;
|
char *chars_to_add, *new_line;
|
||||||
|
|
||||||
chars_to_add = history_delimiting_chars ();
|
add_it = 1;
|
||||||
|
if (command_oriented_history && current_command_line_count > 1)
|
||||||
|
{
|
||||||
|
chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
|
||||||
|
|
||||||
using_history ();
|
using_history ();
|
||||||
|
|
||||||
current = previous_history ();
|
current = previous_history ();
|
||||||
|
|
||||||
if (current)
|
if (current)
|
||||||
@@ -337,11 +482,9 @@ bash_add_history (line)
|
|||||||
/* If the previous line ended with an escaped newline (escaped
|
/* If the previous line ended with an escaped newline (escaped
|
||||||
with backslash, but otherwise unquoted), then remove the quoted
|
with backslash, but otherwise unquoted), then remove the quoted
|
||||||
newline, since that is what happens when the line is parsed. */
|
newline, since that is what happens when the line is parsed. */
|
||||||
int curlen;
|
|
||||||
|
|
||||||
curlen = strlen (current->line);
|
curlen = strlen (current->line);
|
||||||
|
|
||||||
if (!delimiter_depth && current->line[curlen - 1] == '\\' &&
|
if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
|
||||||
current->line[curlen - 2] != '\\')
|
current->line[curlen - 2] != '\\')
|
||||||
{
|
{
|
||||||
current->line[curlen - 1] = '\0';
|
current->line[curlen - 1] = '\0';
|
||||||
@@ -349,22 +492,18 @@ bash_add_history (line)
|
|||||||
chars_to_add = "";
|
chars_to_add = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = where_history ();
|
|
||||||
new_line = (char *) xmalloc (1
|
new_line = (char *) xmalloc (1
|
||||||
+ curlen
|
+ curlen
|
||||||
+ strlen (line)
|
+ strlen (line)
|
||||||
+ strlen (chars_to_add));
|
+ strlen (chars_to_add));
|
||||||
sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
|
sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
|
||||||
|
offset = where_history ();
|
||||||
old = replace_history_entry (offset, new_line, current->data);
|
old = replace_history_entry (offset, new_line, current->data);
|
||||||
free (new_line);
|
free (new_line);
|
||||||
|
|
||||||
if (old)
|
if (old)
|
||||||
{
|
{
|
||||||
/* Note that the old data is not freed, since it was simply
|
FREE (old->line);
|
||||||
copied to the new history entry. */
|
|
||||||
if (old->line)
|
|
||||||
free (old->line);
|
|
||||||
|
|
||||||
free (old);
|
free (old);
|
||||||
}
|
}
|
||||||
add_it = 0;
|
add_it = 0;
|
||||||
@@ -383,8 +522,144 @@ int
|
|||||||
history_number ()
|
history_number ()
|
||||||
{
|
{
|
||||||
using_history ();
|
using_history ();
|
||||||
if (get_string_value ("HISTSIZE"))
|
return (get_string_value ("HISTSIZE") ? history_base + where_history () : 1);
|
||||||
return (history_base + where_history ());
|
|
||||||
else
|
|
||||||
return (1); /* default to command number 1 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
should_expand (s)
|
||||||
|
char *s;
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
for (p = s; p && *p; p++)
|
||||||
|
{
|
||||||
|
if (*p == '\\')
|
||||||
|
p++;
|
||||||
|
else if (*p == '&')
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
histignore_item_func (ign)
|
||||||
|
struct ign *ign;
|
||||||
|
{
|
||||||
|
if (should_expand (ign->val))
|
||||||
|
ign->flags |= HIGN_EXPAND;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setup_history_ignore (varname)
|
||||||
|
char *varname;
|
||||||
|
{
|
||||||
|
setup_ignore_patterns (&histignore);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HIST_ENTRY *
|
||||||
|
last_history_entry ()
|
||||||
|
{
|
||||||
|
HIST_ENTRY *he;
|
||||||
|
|
||||||
|
using_history ();
|
||||||
|
he = previous_history ();
|
||||||
|
using_history ();
|
||||||
|
return he;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
last_history_line ()
|
||||||
|
{
|
||||||
|
HIST_ENTRY *he;
|
||||||
|
|
||||||
|
he = last_history_entry ();
|
||||||
|
if (he == 0)
|
||||||
|
return ((char *)NULL);
|
||||||
|
return he->line;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
expand_histignore_pattern (pat)
|
||||||
|
char *pat;
|
||||||
|
{
|
||||||
|
HIST_ENTRY *phe;
|
||||||
|
char *ret, *p, *r, *t;
|
||||||
|
int len, rlen, ind, tlen;
|
||||||
|
|
||||||
|
phe = last_history_entry ();
|
||||||
|
|
||||||
|
if (phe == (HIST_ENTRY *)0)
|
||||||
|
return (savestring (pat));
|
||||||
|
|
||||||
|
len = strlen (phe->line);
|
||||||
|
rlen = len + strlen (pat) + 2;
|
||||||
|
ret = xmalloc (rlen);
|
||||||
|
|
||||||
|
for (p = pat, r = ret; p && *p; )
|
||||||
|
{
|
||||||
|
if (*p == '&')
|
||||||
|
{
|
||||||
|
ind = r - ret;
|
||||||
|
if (glob_pattern_p (phe->line) || strchr (phe->line, '\\'))
|
||||||
|
{
|
||||||
|
t = quote_globbing_chars (phe->line);
|
||||||
|
tlen = strlen (t);
|
||||||
|
RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
|
||||||
|
r = ret + ind; /* in case reallocated */
|
||||||
|
strcpy (r, t);
|
||||||
|
r += tlen;
|
||||||
|
free (t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tlen = strlen (phe->line);
|
||||||
|
RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
|
||||||
|
r = ret + ind; /* in case reallocated */
|
||||||
|
strcpy (r, phe->line);
|
||||||
|
r += len;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == '\\' && p[1] == '&')
|
||||||
|
p++;
|
||||||
|
|
||||||
|
*r++ = *p++;
|
||||||
|
}
|
||||||
|
*r = '\0';
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return 1 if we should not put LINE into the history according to the
|
||||||
|
patterns in HISTIGNORE. */
|
||||||
|
static int
|
||||||
|
history_should_ignore (line)
|
||||||
|
char *line;
|
||||||
|
{
|
||||||
|
register int i, match;
|
||||||
|
char *npat;
|
||||||
|
|
||||||
|
if (histignore.num_ignores == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = match = 0; i < histignore.num_ignores; i++)
|
||||||
|
{
|
||||||
|
if (histignore.ignores[i].flags & HIGN_EXPAND)
|
||||||
|
npat = expand_histignore_pattern (histignore.ignores[i].val);
|
||||||
|
else
|
||||||
|
npat = histignore.ignores[i].val;
|
||||||
|
|
||||||
|
match = fnmatch (npat, line, 0) != FNM_NOMATCH;
|
||||||
|
|
||||||
|
if (histignore.ignores[i].flags & HIGN_EXPAND)
|
||||||
|
free (npat);
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
#endif /* HISTORY */
|
||||||
|
|||||||
15
bashhist.h
15
bashhist.h
@@ -18,8 +18,8 @@
|
|||||||
with Bash; see the file COPYING. If not, write to the Free Software
|
with Bash; see the file COPYING. If not, write to the Free Software
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#if !defined (__BASHHIST_H__)
|
#if !defined (_BASHHIST_H_)
|
||||||
#define __BASHHIST_H__
|
#define _BASHHIST_H_
|
||||||
|
|
||||||
extern int remember_on_history;
|
extern int remember_on_history;
|
||||||
extern int history_lines_this_session;
|
extern int history_lines_this_session;
|
||||||
@@ -32,11 +32,20 @@ extern int command_oriented_history;
|
|||||||
extern int history_expansion_inhibited;
|
extern int history_expansion_inhibited;
|
||||||
# endif /* BANG_HISTORY */
|
# endif /* BANG_HISTORY */
|
||||||
|
|
||||||
|
extern void bash_initialize_history ();
|
||||||
|
extern void bash_history_reinit ();
|
||||||
|
extern void bash_history_disable ();
|
||||||
|
extern void bash_history_enable ();
|
||||||
extern void load_history ();
|
extern void load_history ();
|
||||||
extern void save_history ();
|
extern void save_history ();
|
||||||
|
extern int maybe_append_history ();
|
||||||
extern int maybe_save_shell_history ();
|
extern int maybe_save_shell_history ();
|
||||||
extern char *pre_process_line ();
|
extern char *pre_process_line ();
|
||||||
extern int history_number ();
|
extern int history_number ();
|
||||||
extern void maybe_add_history ();
|
extern void maybe_add_history ();
|
||||||
|
|
||||||
#endif /* __BASHHIST_H__ */
|
extern void setup_history_ignore ();
|
||||||
|
|
||||||
|
extern char *last_history_line ();
|
||||||
|
|
||||||
|
#endif /* _BASHHIST_H_ */
|
||||||
|
|||||||
49
bashintl.h
Normal file
49
bashintl.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* bashintl.h -- Internationalization stuff
|
||||||
|
|
||||||
|
Copyright (C) 1996 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#if !defined (_BASHINTL_H_)
|
||||||
|
#define _BASHINTL_H_
|
||||||
|
|
||||||
|
/* Include this *after* config.h */
|
||||||
|
#if defined (HAVE_LIBINTL_H)
|
||||||
|
# include <libintl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (HAVE_LOCALE_H)
|
||||||
|
# include <locale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (HAVE_SETLOCALE) && !defined (LC_ALL)
|
||||||
|
# undef HAVE_SETLOCALE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined (HAVE_SETLOCALE)
|
||||||
|
# define setlocale(cat, loc)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined (HAVE_TEXTDOMAIN)
|
||||||
|
# define textdomain(dom)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined (HAVE_BINDTEXTDOMAIN)
|
||||||
|
# define bindtextdomain(dom, dir)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_BASHINTL_H_ */
|
||||||
35
bashjmp.h
Normal file
35
bashjmp.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/* bashjmp.h -- wrapper for setjmp.h with necessary bash definitions. */
|
||||||
|
|
||||||
|
#ifndef _BASHJMP_H_
|
||||||
|
#define _BASHJMP_H_
|
||||||
|
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
/* This *must* be included *after* config.h */
|
||||||
|
|
||||||
|
#if defined (HAVE_POSIX_SIGSETJMP)
|
||||||
|
# define procenv_t sigjmp_buf
|
||||||
|
# undef setjmp
|
||||||
|
# define setjmp(x) sigsetjmp((x), 1)
|
||||||
|
# undef longjmp
|
||||||
|
# define longjmp(x, n) siglongjmp((x), (n))
|
||||||
|
#else
|
||||||
|
# define procenv_t jmp_buf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern procenv_t top_level;
|
||||||
|
extern procenv_t subshell_top_level;
|
||||||
|
extern procenv_t return_catch; /* used by `return' builtin */
|
||||||
|
|
||||||
|
#define SHFUNC_RETURN() longjmp (return_catch, 1)
|
||||||
|
|
||||||
|
#define COPY_PROCENV(old, save) \
|
||||||
|
xbcopy ((char *)old, (char *)save, sizeof (procenv_t));
|
||||||
|
|
||||||
|
/* Values for the second argument to longjmp/siglongjmp. */
|
||||||
|
#define NOT_JUMPED 0 /* Not returning from a longjmp. */
|
||||||
|
#define FORCE_EOF 1 /* We want to stop parsing. */
|
||||||
|
#define DISCARD 2 /* Discard current command. */
|
||||||
|
#define EXITPROG 3 /* Unconditionally exit the program now. */
|
||||||
|
|
||||||
|
#endif /* _BASHJMP_H_ */
|
||||||
765
bashline.c
765
bashline.c
File diff suppressed because it is too large
Load Diff
33
bashline.h
Normal file
33
bashline.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/* bashline.h -- interface to the bash readline functions in bashline.c. */
|
||||||
|
|
||||||
|
/* Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#if !defined (_BASHLINE_H_)
|
||||||
|
#define _BASHLINE_H_
|
||||||
|
|
||||||
|
#include "stdc.h"
|
||||||
|
|
||||||
|
extern int bash_readline_initialized;
|
||||||
|
|
||||||
|
extern void posix_readline_initialize __P((int));
|
||||||
|
extern void initialize_readline __P((void));
|
||||||
|
extern void bashline_reinitialize __P((void));
|
||||||
|
extern int bash_re_edit __P((char *));
|
||||||
|
|
||||||
|
#endif /* _BASHLINE_H_ */
|
||||||
34
bashtty.h
Normal file
34
bashtty.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/* bashtty.h -- what kind of tty driver do we have? */
|
||||||
|
|
||||||
|
/* Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#if !defined (_BASHTTY_H_)
|
||||||
|
#define _BASHTTY_H_
|
||||||
|
|
||||||
|
#if defined (_POSIX_VERSION) && defined (HAVE_TERMIOS_H) && defined (HAVE_TCGETATTR) && !defined (TERMIOS_MISSING)
|
||||||
|
# define TERMIOS_TTY_DRIVER
|
||||||
|
#else
|
||||||
|
# if defined (HAVE_TERMIO_H)
|
||||||
|
# define TERMIO_TTY_DRIVER
|
||||||
|
# else
|
||||||
|
# define NEW_TTY_DRIVER
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _BASHTTY_H */
|
||||||
@@ -18,8 +18,8 @@
|
|||||||
with Bash; see the file COPYING. If not, write to the Free Software
|
with Bash; see the file COPYING. If not, write to the Free Software
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#if !defined (__BASHTYPES_H)
|
#if !defined (_BASHTYPES_H_)
|
||||||
# define __BASHTYPES_H
|
# define _BASHTYPES_H_
|
||||||
|
|
||||||
#if defined (CRAY)
|
#if defined (CRAY)
|
||||||
# define word __word
|
# define word __word
|
||||||
@@ -31,4 +31,4 @@
|
|||||||
# undef word
|
# undef word
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __BASHTYPES_H */
|
#endif /* _BASHTYPES_H_ */
|
||||||
|
|||||||
98
bashwait.h
Normal file
98
bashwait.h
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/* bashwait.h -- definitions for using a `union wait' on systems without
|
||||||
|
one. */
|
||||||
|
|
||||||
|
/* Copyright (C) 1996 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef _BASH_WAIT_H
|
||||||
|
#define _BASH_WAIT_H
|
||||||
|
|
||||||
|
#if !defined (WORDS_BIGENDIAN)
|
||||||
|
union wait
|
||||||
|
{
|
||||||
|
int w_status; /* used in syscall */
|
||||||
|
|
||||||
|
/* Terminated process status. */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned short
|
||||||
|
w_Termsig : 7, /* termination signal */
|
||||||
|
w_Coredump : 1, /* core dump indicator */
|
||||||
|
w_Retcode : 8, /* exit code if w_termsig==0 */
|
||||||
|
w_Fill1 : 16; /* high 16 bits unused */
|
||||||
|
} w_T;
|
||||||
|
|
||||||
|
/* Stopped process status. Returned
|
||||||
|
only for traced children unless requested
|
||||||
|
with the WUNTRACED option bit. */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned short
|
||||||
|
w_Stopval : 8, /* == W_STOPPED if stopped */
|
||||||
|
w_Stopsig : 8, /* actually zero on XENIX */
|
||||||
|
w_Fill2 : 16; /* high 16 bits unused */
|
||||||
|
} w_S;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* WORDS_BIGENDIAN */
|
||||||
|
|
||||||
|
/* This is for big-endian machines like the IBM RT, HP 9000, or Sun-3 */
|
||||||
|
|
||||||
|
union wait
|
||||||
|
{
|
||||||
|
int w_status; /* used in syscall */
|
||||||
|
|
||||||
|
/* Terminated process status. */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned short w_Fill1 : 16; /* high 16 bits unused */
|
||||||
|
unsigned w_Retcode : 8; /* exit code if w_termsig==0 */
|
||||||
|
unsigned w_Coredump : 1; /* core dump indicator */
|
||||||
|
unsigned w_Termsig : 7; /* termination signal */
|
||||||
|
} w_T;
|
||||||
|
|
||||||
|
/* Stopped process status. Returned
|
||||||
|
only for traced children unless requested
|
||||||
|
with the WUNTRACED option bit. */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned short w_Fill2 : 16; /* high 16 bits unused */
|
||||||
|
unsigned w_Stopsig : 8; /* signal that stopped us */
|
||||||
|
unsigned w_Stopval : 8; /* == W_STOPPED if stopped */
|
||||||
|
} w_S;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* WORDS_BIGENDIAN */
|
||||||
|
|
||||||
|
#define w_termsig w_T.w_Termsig
|
||||||
|
#define w_coredump w_T.w_Coredump
|
||||||
|
#define w_retcode w_T.w_Retcode
|
||||||
|
#define w_stopval w_S.w_Stopval
|
||||||
|
#define w_stopsig w_S.w_Stopsig
|
||||||
|
|
||||||
|
#define WSTOPPED 0177
|
||||||
|
#define WIFSTOPPED(x) ((x).w_stopval == WSTOPPED)
|
||||||
|
#define WIFEXITED(x) ((x).w_stopval != WSTOPPED && (x).w_termsig == 0)
|
||||||
|
#define WIFSIGNALED(x) ((x).w_stopval != WSTOPPED && (x).w_termsig != 0)
|
||||||
|
|
||||||
|
#define WTERMSIG(x) ((x).w_termsig)
|
||||||
|
#define WSTOPSIG(x) ((x).w_stopsig)
|
||||||
|
#define WEXITSTATUS(x) ((x).w_retcode)
|
||||||
|
#define WIFCORED(x) ((x).w_coredump)
|
||||||
|
|
||||||
|
#endif /* _BASH_WAIT_H */
|
||||||
16
bracecomp.c
16
bracecomp.c
@@ -22,8 +22,15 @@
|
|||||||
with Bash; see the file COPYING. If not, write to the Free Software
|
with Bash; see the file COPYING. If not, write to the Free Software
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if defined (BRACE_EXPANSION) && defined (READLINE)
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined (HAVE_STRING_H)
|
#if defined (HAVE_STRING_H)
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
#else /* !HAVE_STRING_H */
|
#else /* !HAVE_STRING_H */
|
||||||
@@ -71,7 +78,7 @@ really_munge_braces (array, real_start, real_end, gcd_zero)
|
|||||||
return (savestring (array[0]));
|
return (savestring (array[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
result = (char *) xmalloc (result_size = 1);
|
result = xmalloc (result_size = 1);
|
||||||
*result = '\0';
|
*result = '\0';
|
||||||
|
|
||||||
for (start = real_start; start < real_end; start = end + 1)
|
for (start = real_start; start < real_end; start = end + 1)
|
||||||
@@ -95,7 +102,7 @@ really_munge_braces (array, real_start, real_end, gcd_zero)
|
|||||||
/* In this case, add in a leading '{', because we are at
|
/* In this case, add in a leading '{', because we are at
|
||||||
top level, and there isn't a consistent prefix. */
|
top level, and there isn't a consistent prefix. */
|
||||||
result_size += 1;
|
result_size += 1;
|
||||||
result = (char *) xrealloc (result, result_size);
|
result = xrealloc (result, result_size);
|
||||||
strcpy (result, "{");
|
strcpy (result, "{");
|
||||||
flag++;
|
flag++;
|
||||||
}
|
}
|
||||||
@@ -107,7 +114,7 @@ really_munge_braces (array, real_start, real_end, gcd_zero)
|
|||||||
/* If there is more than one element in the subarray,
|
/* If there is more than one element in the subarray,
|
||||||
insert the prefix and an opening brace. */
|
insert the prefix and an opening brace. */
|
||||||
result_size += gcd - gcd_zero + 1;
|
result_size += gcd - gcd_zero + 1;
|
||||||
result = (char *) xrealloc (result, result_size);
|
result = xrealloc (result, result_size);
|
||||||
strncat (result, array[start] + gcd_zero, gcd - gcd_zero);
|
strncat (result, array[start] + gcd_zero, gcd - gcd_zero);
|
||||||
strcat (result, "{");
|
strcat (result, "{");
|
||||||
subterm = really_munge_braces (array, start, end + 1, gcd);
|
subterm = really_munge_braces (array, start, end + 1, gcd);
|
||||||
@@ -115,7 +122,7 @@ really_munge_braces (array, real_start, real_end, gcd_zero)
|
|||||||
}
|
}
|
||||||
|
|
||||||
result_size += strlen (subterm) + 1;
|
result_size += strlen (subterm) + 1;
|
||||||
result = (char *) xrealloc (result, result_size);
|
result = xrealloc (result, result_size);
|
||||||
strcat (result, subterm);
|
strcat (result, subterm);
|
||||||
strcat (result, ",");
|
strcat (result, ",");
|
||||||
free (subterm);
|
free (subterm);
|
||||||
@@ -164,3 +171,4 @@ bash_brace_completion ()
|
|||||||
rl_attempted_completion_function = orig_attempt_func;
|
rl_attempted_completion_function = orig_attempt_func;
|
||||||
rl_completion_entry_function = orig_entry_func;
|
rl_completion_entry_function = orig_entry_func;
|
||||||
}
|
}
|
||||||
|
#endif /* BRACE_EXPANSION && READLINE */
|
||||||
|
|||||||
44
braces.c
44
braces.c
@@ -18,12 +18,15 @@
|
|||||||
along with Bash; see the file COPYING. If not, write to the Free
|
along with Bash; see the file COPYING. If not, write to the Free
|
||||||
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
/* Stuff in curly braces gets expanded after variable and command
|
/* Stuff in curly braces gets expanded before all other shell expansions. */
|
||||||
substitution, but before filename globbing.
|
|
||||||
|
|
||||||
(Actually, this should be true for the sake of efficiency, but it
|
#include "config.h"
|
||||||
isn't because of quoting hacks. Once I rebuild quoting it will be
|
|
||||||
true. */
|
#if defined (BRACE_EXPANSION)
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined (HAVE_STRING_H)
|
#if defined (HAVE_STRING_H)
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
@@ -32,7 +35,7 @@
|
|||||||
#endif /* !HAVE_STRING_H */
|
#endif /* !HAVE_STRING_H */
|
||||||
|
|
||||||
#if defined (SHELL)
|
#if defined (SHELL)
|
||||||
#include "shell.h"
|
# include "shell.h"
|
||||||
#endif /* SHELL */
|
#endif /* SHELL */
|
||||||
|
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
@@ -61,7 +64,7 @@ brace_expand (text)
|
|||||||
register int start;
|
register int start;
|
||||||
char *preamble, *postamble, *amble;
|
char *preamble, *postamble, *amble;
|
||||||
char **tack, **result;
|
char **tack, **result;
|
||||||
int i, c;
|
int i, j, c;
|
||||||
|
|
||||||
/* Find the text of the preamble. */
|
/* Find the text of the preamble. */
|
||||||
i = 0;
|
i = 0;
|
||||||
@@ -85,11 +88,9 @@ brace_expand (text)
|
|||||||
c = brace_gobbler (text, &i, '}');
|
c = brace_gobbler (text, &i, '}');
|
||||||
|
|
||||||
/* What if there isn't a matching close brace? */
|
/* What if there isn't a matching close brace? */
|
||||||
if (!c)
|
if (c == 0)
|
||||||
{
|
{
|
||||||
#if defined (NOTDEF)
|
#if defined (NOTDEF)
|
||||||
register int j;
|
|
||||||
|
|
||||||
/* Well, if we found an unquoted BRACE_ARG_SEPARATOR between START
|
/* Well, if we found an unquoted BRACE_ARG_SEPARATOR between START
|
||||||
and I, then this should be an error. Otherwise, it isn't. */
|
and I, then this should be an error. Otherwise, it isn't. */
|
||||||
for (j = start; j < i; j++)
|
for (j = start; j < i; j++)
|
||||||
@@ -103,7 +104,7 @@ brace_expand (text)
|
|||||||
if (text[j] == brace_arg_separator)
|
if (text[j] == brace_arg_separator)
|
||||||
{
|
{
|
||||||
free_array (result);
|
free_array (result);
|
||||||
report_error ("Missing `}'");
|
report_error ("missing `}'");
|
||||||
throw_to_top_level ();
|
throw_to_top_level ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,9 +121,6 @@ brace_expand (text)
|
|||||||
#if defined (SHELL)
|
#if defined (SHELL)
|
||||||
/* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then
|
/* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then
|
||||||
just return without doing any expansion. */
|
just return without doing any expansion. */
|
||||||
{
|
|
||||||
register int j;
|
|
||||||
|
|
||||||
for (j = 0; amble[j]; j++)
|
for (j = 0; amble[j]; j++)
|
||||||
{
|
{
|
||||||
if (amble[j] == '\\')
|
if (amble[j] == '\\')
|
||||||
@@ -141,7 +139,6 @@ brace_expand (text)
|
|||||||
result[0] = savestring (text);
|
result[0] = savestring (text);
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif /* SHELL */
|
#endif /* SHELL */
|
||||||
|
|
||||||
postamble = &text[i + 1];
|
postamble = &text[i + 1];
|
||||||
@@ -245,11 +242,11 @@ brace_gobbler (text, indx, satisfy)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == satisfy && !level && !quoted)
|
if (c == satisfy && level == 0 && quoted == 0)
|
||||||
{
|
{
|
||||||
/* We ignore an open brace surrounded by whitespace, and also
|
/* We ignore an open brace surrounded by whitespace, and also
|
||||||
an open brace followed immediately by a close brace, that
|
an open brace followed immediately by a close brace preceded
|
||||||
was preceded with whitespace. */
|
by whitespace. */
|
||||||
if (c == '{' &&
|
if (c == '{' &&
|
||||||
((!i || brace_whitespace (text[i - 1])) &&
|
((!i || brace_whitespace (text[i - 1])) &&
|
||||||
(brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
|
(brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
|
||||||
@@ -257,10 +254,8 @@ brace_gobbler (text, indx, satisfy)
|
|||||||
#if defined (SHELL)
|
#if defined (SHELL)
|
||||||
/* If this is being compiled as part of bash, ignore the `{'
|
/* If this is being compiled as part of bash, ignore the `{'
|
||||||
in a `${}' construct */
|
in a `${}' construct */
|
||||||
if ((c != '{') || !i || (text[i - 1] != '$'))
|
if ((c != '{') || i == 0 || (text[i - 1] != '$'))
|
||||||
#else /* !SHELL */
|
#endif /* SHELL */
|
||||||
if ((c != '{') || !i)
|
|
||||||
#endif /* !SHELL */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,10 +281,10 @@ array_concat (arr1, arr2)
|
|||||||
register int i, j, len, len1, len2;
|
register int i, j, len, len1, len2;
|
||||||
register char **result;
|
register char **result;
|
||||||
|
|
||||||
if (!arr1)
|
if (arr1 == 0)
|
||||||
return (copy_array (arr2));
|
return (copy_array (arr2));
|
||||||
|
|
||||||
if (!arr2)
|
if (arr2 == 0)
|
||||||
return (copy_array (arr1));
|
return (copy_array (arr1));
|
||||||
|
|
||||||
len1 = array_len (arr1);
|
len1 = array_len (arr1);
|
||||||
@@ -369,3 +364,4 @@ main ()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#endif /* TEST */
|
#endif /* TEST */
|
||||||
|
#endif /* BRACE_EXPANSION */
|
||||||
|
|||||||
16
builtins.h
16
builtins.h
@@ -19,6 +19,11 @@
|
|||||||
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
|
|
||||||
@@ -28,8 +33,10 @@
|
|||||||
|
|
||||||
/* Flags describing various things about a builtin. */
|
/* Flags describing various things about a builtin. */
|
||||||
#define BUILTIN_ENABLED 0x1 /* This builtin is enabled. */
|
#define BUILTIN_ENABLED 0x1 /* This builtin is enabled. */
|
||||||
#define STATIC_BUILTIN 0x2 /* This builtin is not dynamically loaded. */
|
#define BUILTIN_DELETED 0x2 /* This has been deleted with enable -d. */
|
||||||
#define SPECIAL_BUILTIN 0x4 /* This is a Posix `special' builtin. */
|
#define STATIC_BUILTIN 0x4 /* This builtin is not dynamically loaded. */
|
||||||
|
#define SPECIAL_BUILTIN 0x8 /* This is a Posix `special' builtin. */
|
||||||
|
#define ASSIGNMENT_BUILTIN 0x10 /* This builtin takes assignment statements. */
|
||||||
|
|
||||||
/* The thing that we build the array of builtins out of. */
|
/* The thing that we build the array of builtins out of. */
|
||||||
struct builtin {
|
struct builtin {
|
||||||
@@ -38,8 +45,11 @@ struct builtin {
|
|||||||
int flags; /* One of the #defines above. */
|
int flags; /* One of the #defines above. */
|
||||||
char **long_doc; /* NULL terminated array of strings. */
|
char **long_doc; /* NULL terminated array of strings. */
|
||||||
char *short_doc; /* Short version of documenation. */
|
char *short_doc; /* Short version of documenation. */
|
||||||
|
char *handle; /* for future use */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Found in builtins.c, created by builtins/mkbuiltins. */
|
/* Found in builtins.c, created by builtins/mkbuiltins. */
|
||||||
extern int num_shell_builtins; /* Number of shell builtins. */
|
extern int num_shell_builtins; /* Number of shell builtins. */
|
||||||
extern struct builtin shell_builtins[];
|
extern struct builtin static_shell_builtins[];
|
||||||
|
extern struct builtin *shell_builtins;
|
||||||
|
extern struct builtin *current_builtin;
|
||||||
|
|||||||
@@ -1,267 +0,0 @@
|
|||||||
# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs.
|
|
||||||
#
|
|
||||||
MKBUILTINS = mkbuiltins
|
|
||||||
RANLIB = /usr/bin/ranlib
|
|
||||||
CFLAGS = -g -I.. -I.
|
|
||||||
SHELL = /bin/sh
|
|
||||||
# CC = cc
|
|
||||||
AR = ar
|
|
||||||
RM = rm -f
|
|
||||||
CP = cp
|
|
||||||
|
|
||||||
srcdir = .
|
|
||||||
VPATH = .:$(srcdir)
|
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
.SUFFIXES: .def .c .o
|
|
||||||
# How to make a .o file from a .def file.
|
|
||||||
.def.o:
|
|
||||||
$(RM) $@
|
|
||||||
./$(MKBUILTINS) $(DIRECTDEFINE) $<
|
|
||||||
$(CC) -c $(CFLAGS) $(CPPFLAGS) $*.c || ( $(RM) $*.c ; exit 1 )
|
|
||||||
$(RM) $*.c
|
|
||||||
|
|
||||||
# How to make a .c file from a .def file.
|
|
||||||
.def.c:
|
|
||||||
$(RM) $@
|
|
||||||
./$(MKBUILTINS) $(DIRECTDEFINE) $<
|
|
||||||
|
|
||||||
# Here is a rule for making .o files from .c files that does not
|
|
||||||
# force the type of the machine (like -M_MACHINE) into the flags.
|
|
||||||
.c.o:
|
|
||||||
$(RM) $@
|
|
||||||
$(CC) -c $(CFLAGS) $(CPPFLAGS) $<
|
|
||||||
|
|
||||||
DEFS = $(srcdir)/alias.def $(srcdir)/bind.def $(srcdir)/break.def \
|
|
||||||
$(srcdir)/builtin.def $(srcdir)/cd.def $(srcdir)/colon.def \
|
|
||||||
$(srcdir)/command.def $(srcdir)/declare.def $(srcdir)/echo.def \
|
|
||||||
$(srcdir)/enable.def $(srcdir)/eval.def $(srcdir)/getopts.def \
|
|
||||||
$(srcdir)/exec.def $(srcdir)/exit.def $(srcdir)/fc.def \
|
|
||||||
$(srcdir)/fg_bg.def $(srcdir)/hash.def $(srcdir)/help.def \
|
|
||||||
$(srcdir)/history.def $(srcdir)/jobs.def $(srcdir)/kill.def \
|
|
||||||
$(srcdir)/let.def $(srcdir)/read.def $(srcdir)/return.def \
|
|
||||||
$(srcdir)/set.def $(srcdir)/setattr.def $(srcdir)/shift.def \
|
|
||||||
$(srcdir)/source.def $(srcdir)/suspend.def $(srcdir)/test.def \
|
|
||||||
$(srcdir)/times.def $(srcdir)/trap.def $(srcdir)/type.def \
|
|
||||||
$(srcdir)/ulimit.def $(srcdir)/umask.def $(srcdir)/wait.def \
|
|
||||||
$(srcdir)/reserved.def
|
|
||||||
|
|
||||||
STATIC_SOURCE = common.c getopt.c bashgetopt.c getopt.h
|
|
||||||
|
|
||||||
OFILES = builtins.o \
|
|
||||||
alias.o bind.o break.o builtin.o cd.o colon.o command.o \
|
|
||||||
common.o declare.o echo.o enable.o eval.o exec.o exit.o \
|
|
||||||
fc.o fg_bg.o hash.o help.o history.o jobs.o kill.o \
|
|
||||||
let.o read.o return.o set.o setattr.o shift.o source.o \
|
|
||||||
suspend.o test.o times.o trap.o type.o ulimit.o umask.o \
|
|
||||||
wait.o getopts.o getopt.o bashgetopt.o
|
|
||||||
|
|
||||||
THINGS_TO_TAR = $(DEFS) $(STATIC_SOURCE) Makefile ChangeLog
|
|
||||||
|
|
||||||
CREATED_FILES = builtext.h builtins.c psize.aux pipesize.h
|
|
||||||
|
|
||||||
all: $(MKBUILTINS) libbuiltins.a
|
|
||||||
|
|
||||||
libbuiltins.a: $(MKBUILTINS) $(OFILES)
|
|
||||||
$(RM) $@
|
|
||||||
$(AR) cq $@ $(OFILES)
|
|
||||||
-$(RANLIB) $@
|
|
||||||
|
|
||||||
builtext.h builtins.c: $(MKBUILTINS) $(DEFS)
|
|
||||||
$(RM) builtext.h builtins.c
|
|
||||||
./$(MKBUILTINS) -externfile builtext.h -structfile builtins.c \
|
|
||||||
-noproduction $(DIRECTDEFINE) $(DEFS)
|
|
||||||
|
|
||||||
mkbuiltins: $(srcdir)/mkbuiltins.c ../config.h
|
|
||||||
$(CC) $(CFLAGS) -o $(MKBUILTINS) $(srcdir)/mkbuiltins.c
|
|
||||||
|
|
||||||
ulimit.o: ulimit.def pipesize.h
|
|
||||||
|
|
||||||
pipesize.h: psize.aux
|
|
||||||
$(SHELL) $(srcdir)/psize.sh > pipesize.h
|
|
||||||
|
|
||||||
psize.aux: psize.c
|
|
||||||
$(CC) $(CFLAGS) -o $@ $(srcdir)/psize.c
|
|
||||||
|
|
||||||
documentation: builtins.texi
|
|
||||||
|
|
||||||
$(OFILES): $(MKBUILTINS) ../config.h
|
|
||||||
|
|
||||||
builtins.texi: $(MKBUILTINS)
|
|
||||||
./$(MKBUILTINS) -documentonly $(DEFS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) $(OFILES) $(CREATED_FILES) $(MKBUILTINS)
|
|
||||||
|
|
||||||
mostlyclean:
|
|
||||||
$(RM) $(OFILES) libbuiltins.a
|
|
||||||
|
|
||||||
distclean realclean maintainer-clean: clean
|
|
||||||
$(RM) libbuiltins.a
|
|
||||||
|
|
||||||
alias.o: alias.def
|
|
||||||
bind.o: bind.def
|
|
||||||
break.o: break.def
|
|
||||||
builtin.o: builtin.def
|
|
||||||
cd.o: cd.def
|
|
||||||
colon.o: colon.def
|
|
||||||
command.o: command.def
|
|
||||||
declare.o: declare.def
|
|
||||||
echo.o: echo.def
|
|
||||||
enable.o: enable.def
|
|
||||||
eval.o: eval.def
|
|
||||||
exec.o: exec.def
|
|
||||||
exit.o: exit.def
|
|
||||||
fc.o: fc.def
|
|
||||||
fg_bg.o: fg_bg.def
|
|
||||||
hash.o: hash.def
|
|
||||||
help.o: help.def
|
|
||||||
history.o: history.def
|
|
||||||
jobs.o: jobs.def
|
|
||||||
kill.o: kill.def
|
|
||||||
let.o: let.def
|
|
||||||
read.o: read.def
|
|
||||||
return.o: return.def
|
|
||||||
set.o: set.def
|
|
||||||
setattr.o: setattr.def
|
|
||||||
shift.o: shift.def
|
|
||||||
source.o: source.def
|
|
||||||
suspend.o: suspend.def
|
|
||||||
test.o: test.def
|
|
||||||
times.o: times.def
|
|
||||||
trap.o: trap.def
|
|
||||||
type.o: type.def
|
|
||||||
umask.o: umask.def
|
|
||||||
wait.o: wait.def
|
|
||||||
getopts.o: getopts.def
|
|
||||||
reserved.o: reserved.def
|
|
||||||
|
|
||||||
common.o: ../shell.h ../command.h ../config.h ../memalloc.h ../general.h
|
|
||||||
common.o: ../variables.h ../input.h hashcom.h ../bashhist.h
|
|
||||||
common.o: ../quit.h ../unwind_prot.h ../maxpath.h ../jobs.h ../builtins.h
|
|
||||||
common.o: ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
common.o: ../execute_cmd.h ../error.h
|
|
||||||
alias.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
alias.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
alias.o: ../shell.h ../unwind_prot.h ../variables.h common.h ../maxpath.h
|
|
||||||
bind.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
bind.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
bind.o: ../maxpath.h
|
|
||||||
bind.o: ../shell.h ../unwind_prot.h ../variables.h bashgetopt.h
|
|
||||||
break.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
break.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
break.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
builtin.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
builtin.o: ../quit.h common.h ../maxpath.h
|
|
||||||
builtin.o: ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
builtin.o: ../shell.h ../unwind_prot.h ../variables.h
|
|
||||||
cd.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
cd.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
cd.o: ../shell.h ../unwind_prot.h ../variables.h common.h ../maxpath.h
|
|
||||||
command.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
command.o: ../quit.h bashgetopt.h ../maxpath.h
|
|
||||||
command.o: ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
command.o: ../shell.h ../unwind_prot.h ../variables.h
|
|
||||||
declare.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
declare.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
declare.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
echo.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
echo.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
echo.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
enable.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
enable.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
enable.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
eval.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
eval.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
eval.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
exec.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
exec.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
exec.o: ../shell.h ../unwind_prot.h ../variables.h common.h ../execute_cmd.h
|
|
||||||
exec.o: ../maxpath.h ../flags.h
|
|
||||||
exit.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
exit.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
exit.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
fc.o: ../builtins.h ../command.h bashgetopt.h ../bashhist.h
|
|
||||||
fc.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
fc.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
fc.o: ../flags.h ../unwind_prot.h ../variables.h ../shell.h ../maxpath.h
|
|
||||||
fg_bg.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
fg_bg.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
fg_bg.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
getopts.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
getopts.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
getopts.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
hash.o: ../builtins.h ../command.h ../quit.h ../execute_cmd.h
|
|
||||||
hash.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
hash.o: ../shell.h ../unwind_prot.h ../variables.h common.h ../maxpath.h
|
|
||||||
help.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
help.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
help.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
history.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
history.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
history.o: ../filecntl.h ../shell.h ../unwind_prot.h ../variables.h
|
|
||||||
history.o: ../bashhist.h ../maxpath.h
|
|
||||||
inlib.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
inlib.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
inlib.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
jobs.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
jobs.o: ../quit.h bashgetopt.h ../maxpath.h
|
|
||||||
jobs.o: ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
jobs.o: ../shell.h ../unwind_prot.h ../variables.h
|
|
||||||
kill.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
kill.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
kill.o: ../shell.h ../trap.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
let.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
let.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
let.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
read.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
read.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
read.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
return.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
return.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
return.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
set.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
set.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
set.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
setattr.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
setattr.o: ../quit.h common.h bashgetopt.h ../maxpath.h
|
|
||||||
setattr.o: ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
setattr.o: ../shell.h ../unwind_prot.h ../variables.h
|
|
||||||
shift.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
shift.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
shift.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
source.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
source.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
source.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
suspend.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
suspend.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
suspend.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
test.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
test.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
test.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
times.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
times.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
times.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
trap.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
trap.o: ../quit.h common.h ../maxpath.h
|
|
||||||
trap.o: ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
trap.o: ../shell.h ../unwind_prot.h ../variables.h ../execute_cmd.h
|
|
||||||
type.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
type.o: ../quit.h common.h ../maxpath.h
|
|
||||||
type.o: ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
type.o: ../shell.h ../unwind_prot.h ../variables.h
|
|
||||||
ulimit.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
ulimit.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
ulimit.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
umask.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
umask.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
umask.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
wait.o: ../command.h ../config.h ../memalloc.h ../error.h ../general.h
|
|
||||||
wait.o: ../quit.h ../dispose_cmd.h ../make_cmd.h ../subst.h ../externs.h
|
|
||||||
wait.o: ../shell.h ../unwind_prot.h ../variables.h ../maxpath.h
|
|
||||||
|
|
||||||
bashgetopt.o: ../bashansi.h ../ansi_stdlib.h
|
|
||||||
mkbuiltins.o: ../bashansi.h ../ansi_stdlib.h
|
|
||||||
fc.o: ../bashansi.h ../ansi_stdlib.h
|
|
||||||
|
|
||||||
#bind.o: $(RL_LIBSRC)chardefs.h $(RL_LIBSRC)readline.h $(RL_LIBSRC)keymaps.h
|
|
||||||
375
builtins/Makefile.in
Normal file
375
builtins/Makefile.in
Normal file
@@ -0,0 +1,375 @@
|
|||||||
|
# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs.
|
||||||
|
#
|
||||||
|
MKBUILTINS = mkbuiltins
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
LOCAL_CFLAGS = @LOCAL_CFLAGS@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
SHELL = /bin/sh
|
||||||
|
CC = @CC@
|
||||||
|
AR = @AR@
|
||||||
|
RM = rm -f
|
||||||
|
CP = cp
|
||||||
|
|
||||||
|
LIBS = @LIBS@
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = .:@srcdir@
|
||||||
|
topdir = @top_srcdir@
|
||||||
|
includedir = @includedir@
|
||||||
|
|
||||||
|
DEFS = @DEFS@
|
||||||
|
|
||||||
|
INCLUDES = -I. -I.. -I$(topdir) -I$(topdir)/lib -I$(srcdir)
|
||||||
|
|
||||||
|
CCFLAGS = $(DEFS) $(SYSTEM_FLAGS) $(CPPFLAGS) ${INCLUDES} $(LOCAL_CFLAGS) $(CFLAGS)
|
||||||
|
|
||||||
|
DIRECTDEFINE = -D $(srcdir)
|
||||||
|
|
||||||
|
# xxx this is bad style
|
||||||
|
RL_LIBSRC = $(topdir)/lib/readline
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .def .c .o
|
||||||
|
# How to make a .o file from a .def file.
|
||||||
|
.def.o:
|
||||||
|
$(RM) $@
|
||||||
|
./$(MKBUILTINS) $(DIRECTDEFINE) $<
|
||||||
|
$(CC) -c $(CCFLAGS) $*.c || ( $(RM) $*.c ; exit 1 )
|
||||||
|
$(RM) $*.c
|
||||||
|
|
||||||
|
# How to make a .c file from a .def file.
|
||||||
|
.def.c:
|
||||||
|
$(RM) $@
|
||||||
|
./$(MKBUILTINS) $(DIRECTDEFINE) $<
|
||||||
|
|
||||||
|
# default rule for making a .o file from a .c file
|
||||||
|
.c.o:
|
||||||
|
$(RM) $@
|
||||||
|
$(CC) -c $(CCFLAGS) $<
|
||||||
|
|
||||||
|
DEFSRC = $(srcdir)/alias.def $(srcdir)/bind.def $(srcdir)/break.def \
|
||||||
|
$(srcdir)/builtin.def $(srcdir)/cd.def $(srcdir)/colon.def \
|
||||||
|
$(srcdir)/command.def $(srcdir)/declare.def $(srcdir)/echo.def \
|
||||||
|
$(srcdir)/enable.def $(srcdir)/eval.def $(srcdir)/getopts.def \
|
||||||
|
$(srcdir)/exec.def $(srcdir)/exit.def $(srcdir)/fc.def \
|
||||||
|
$(srcdir)/fg_bg.def $(srcdir)/hash.def $(srcdir)/help.def \
|
||||||
|
$(srcdir)/history.def $(srcdir)/jobs.def $(srcdir)/kill.def \
|
||||||
|
$(srcdir)/let.def $(srcdir)/read.def $(srcdir)/return.def \
|
||||||
|
$(srcdir)/set.def $(srcdir)/setattr.def $(srcdir)/shift.def \
|
||||||
|
$(srcdir)/source.def $(srcdir)/suspend.def $(srcdir)/test.def \
|
||||||
|
$(srcdir)/times.def $(srcdir)/trap.def $(srcdir)/type.def \
|
||||||
|
$(srcdir)/ulimit.def $(srcdir)/umask.def $(srcdir)/wait.def \
|
||||||
|
$(srcdir)/reserved.def $(srcdir)/pushd.def $(srcdir)/shopt.def
|
||||||
|
|
||||||
|
STATIC_SOURCE = common.c evalstring.c evalfile.c getopt.c bashgetopt.c \
|
||||||
|
getopt.h
|
||||||
|
|
||||||
|
OFILES = builtins.o \
|
||||||
|
alias.o bind.o break.o builtin.o cd.o colon.o command.o \
|
||||||
|
common.o declare.o echo.o enable.o eval.o evalfile.o \
|
||||||
|
evalstring.o exec.o \
|
||||||
|
exit.o fc.o fg_bg.o hash.o help.o history.o jobs.o kill.o let.o \
|
||||||
|
pushd.o read.o return.o set.o setattr.o shift.o source.o \
|
||||||
|
suspend.o test.o times.o trap.o type.o ulimit.o umask.o \
|
||||||
|
wait.o getopts.o shopt.o getopt.o bashgetopt.o
|
||||||
|
|
||||||
|
CREATED_FILES = builtext.h builtins.c psize.aux pipesize.h
|
||||||
|
|
||||||
|
all: $(MKBUILTINS) libbuiltins.a
|
||||||
|
|
||||||
|
libbuiltins.a: $(MKBUILTINS) $(OFILES)
|
||||||
|
$(RM) $@
|
||||||
|
$(AR) cr $@ $(OFILES)
|
||||||
|
-$(RANLIB) $@
|
||||||
|
|
||||||
|
builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC)
|
||||||
|
$(RM) builtext.h builtins.c
|
||||||
|
./$(MKBUILTINS) -externfile builtext.h -structfile builtins.c \
|
||||||
|
-noproduction $(DIRECTDEFINE) $(DEFSRC)
|
||||||
|
|
||||||
|
mkbuiltins: $(srcdir)/mkbuiltins.c ../config.h
|
||||||
|
$(CC) $(CCFLAGS) -o $(MKBUILTINS) $(srcdir)/mkbuiltins.c $(LIBS)
|
||||||
|
|
||||||
|
# rules for deficient makes, like SunOS
|
||||||
|
common.o: common.c
|
||||||
|
bashgetopt.o: bashgetopt.c
|
||||||
|
getopt.o: getopt.c
|
||||||
|
|
||||||
|
ulimit.o: ulimit.def pipesize.h
|
||||||
|
|
||||||
|
pipesize.h: psize.aux
|
||||||
|
$(SHELL) $(srcdir)/psize.sh > pipesize.h
|
||||||
|
|
||||||
|
psize.aux: psize.c
|
||||||
|
$(CC) $(CCFLAGS) -o $@ $(srcdir)/psize.c
|
||||||
|
|
||||||
|
documentation: builtins.texi
|
||||||
|
|
||||||
|
$(OFILES): $(MKBUILTINS) ../config.h
|
||||||
|
|
||||||
|
builtins.texi: $(MKBUILTINS)
|
||||||
|
./$(MKBUILTINS) -documentonly $(DEFSRC)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(OFILES) $(CREATED_FILES) $(MKBUILTINS) libbuiltins.a
|
||||||
|
|
||||||
|
mostlyclean:
|
||||||
|
$(RM) $(OFILES) libbuiltins.a
|
||||||
|
|
||||||
|
distclean maintainer-clean: clean
|
||||||
|
$(RM) Makefile
|
||||||
|
|
||||||
|
alias.o: alias.def
|
||||||
|
bind.o: bind.def
|
||||||
|
break.o: break.def
|
||||||
|
builtin.o: builtin.def
|
||||||
|
cd.o: cd.def
|
||||||
|
colon.o: colon.def
|
||||||
|
command.o: command.def
|
||||||
|
declare.o: declare.def
|
||||||
|
echo.o: echo.def
|
||||||
|
enable.o: enable.def
|
||||||
|
eval.o: eval.def
|
||||||
|
exec.o: exec.def
|
||||||
|
exit.o: exit.def
|
||||||
|
fc.o: fc.def
|
||||||
|
fg_bg.o: fg_bg.def
|
||||||
|
hash.o: hash.def
|
||||||
|
help.o: help.def
|
||||||
|
history.o: history.def
|
||||||
|
jobs.o: jobs.def
|
||||||
|
kill.o: kill.def
|
||||||
|
let.o: let.def
|
||||||
|
pushd.o: pushd.def
|
||||||
|
read.o: read.def
|
||||||
|
return.o: return.def
|
||||||
|
set.o: set.def
|
||||||
|
setattr.o: setattr.def
|
||||||
|
shift.o: shift.def
|
||||||
|
source.o: source.def
|
||||||
|
suspend.o: suspend.def
|
||||||
|
test.o: test.def
|
||||||
|
times.o: times.def
|
||||||
|
trap.o: trap.def
|
||||||
|
type.o: type.def
|
||||||
|
umask.o: umask.def
|
||||||
|
wait.o: wait.def
|
||||||
|
getopts.o: getopts.def
|
||||||
|
reserved.o: reserved.def
|
||||||
|
|
||||||
|
common.o: $(topdir)/shell.h $(topdir)/command.h ../config.h
|
||||||
|
common.o: $(topdir)/memalloc.h $(topdir)/general.h
|
||||||
|
common.o: $(topdir)/variables.h $(topdir)/input.h $(srcdir)/hashcom.h
|
||||||
|
common.o: $(topdir)/bashhist.h $(topdir)/quit.h $(topdir)/unwind_prot.h
|
||||||
|
common.o: $(topdir)/maxpath.h $(topdir)/jobs.h $(topdir)/builtins.h
|
||||||
|
common.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||||
|
common.o: $(topdir)/execute_cmd.h $(topdir)/error.h $(topdir)/externs.h
|
||||||
|
alias.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
alias.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/maxpath.h
|
||||||
|
alias.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
alias.o: $(topdir)/subst.h $(topdir)/externs.h $(srcdir)/common.h
|
||||||
|
alias.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
bind.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h $(topdir)/error.h
|
||||||
|
bind.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
bind.o: $(topdir)/subst.h $(topdir)/externs.h $(srcdir)/bashgetopt.h
|
||||||
|
bind.o: $(topdir)/general.h $(topdir)/maxpath.h $(topdir)/bashline.h
|
||||||
|
bind.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
break.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
break.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
break.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
break.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
break.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
builtin.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
builtin.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/externs.h
|
||||||
|
builtin.o: $(topdir)/quit.h $(srcdir)/common.h $(topdir)/maxpath.h
|
||||||
|
builtin.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||||
|
builtin.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
cd.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h $(topdir)/error.h
|
||||||
|
cd.o: $(topdir)/general.h $(topdir)/quit.h $(topdir)/dispose_cmd.h
|
||||||
|
cd.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/externs.h
|
||||||
|
cd.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
cd.o: $(srcdir)/common.h $(topdir)/maxpath.h
|
||||||
|
command.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
command.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/externs.h
|
||||||
|
command.o: $(topdir)/quit.h $(srcdir)/bashgetopt.h $(topdir)/maxpath.h
|
||||||
|
command.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||||
|
command.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
declare.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
declare.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
declare.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
declare.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
declare.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
echo.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h $(topdir)/error.h
|
||||||
|
echo.o: $(topdir)/general.h $(topdir)/subst.h $(topdir)/externs.h
|
||||||
|
echo.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
echo.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
echo.o: $(topdir)/maxpath.h
|
||||||
|
enable.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
enable.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
enable.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
enable.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||||
|
enable.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
enable.o: $(topdir)/maxpath.h
|
||||||
|
eval.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
eval.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
eval.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
eval.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||||
|
eval.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
eval.o: $(topdir)/maxpath.h
|
||||||
|
exec.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
exec.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
exec.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
exec.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/flags.h
|
||||||
|
exec.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
exec.o: $(srcdir)/common.h $(topdir)/execute_cmd.h $(topdir)/maxpath.h
|
||||||
|
exit.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
exit.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
exit.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
exit.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||||
|
exit.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
exit.o: $(topdir)/maxpath.h
|
||||||
|
fc.o: $(topdir)/builtins.h $(topdir)/command.h $(srcdir)/bashgetopt.h
|
||||||
|
fc.o: $(topdir)/bashhist.h
|
||||||
|
fc.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h $(topdir)/error.h
|
||||||
|
fc.o: $(topdir)/general.h $(topdir)/maxpath.h
|
||||||
|
fc.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
fc.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/shell.h
|
||||||
|
fc.o: $(topdir)/flags.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
fg_bg.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
fg_bg.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
fg_bg.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
fg_bg.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
fg_bg.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
getopts.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
getopts.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
getopts.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
getopts.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
getopts.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
hash.o: $(topdir)/builtins.h $(topdir)/command.h $(topdir)/quit.h
|
||||||
|
hash.o: $(topdir)/execute_cmd.h $(topdir)/hashlib.h
|
||||||
|
hash.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
hash.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
hash.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
hash.o: $(srcdir)/common.h $(topdir)/maxpath.h
|
||||||
|
help.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
help.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
help.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
help.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
help.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
history.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
history.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
history.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
history.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||||
|
history.o: $(topdir)/filecntl.h $(topdir)/shell.h $(topdir)/unwind_prot.h
|
||||||
|
history.o: $(topdir)/variables.h $(topdir)/bashhist.h $(topdir)/maxpath.h
|
||||||
|
inlib.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
inlib.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
inlib.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
inlib.o: $(topdir)/maxpath.h $(topdir)/subst.h $(topdir)/externs.h
|
||||||
|
inlib.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
jobs.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h $(topdir)/error.h
|
||||||
|
jobs.o: $(topdir)/general.h $(topdir)/quit.h $(srcdir)/bashgetopt.h
|
||||||
|
jobs.o: $(topdir)/maxpath.h $(topdir)/externs.h
|
||||||
|
jobs.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||||
|
jobs.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
kill.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h $(topdir)/error.h
|
||||||
|
kill.o: $(topdir)/general.h $(topdir)/subst.h $(topdir)/externs.h
|
||||||
|
kill.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
kill.o: $(topdir)/shell.h $(topdir)/trap.h $(topdir)/unwind_prot.h
|
||||||
|
kill.o: $(topdir)/variables.h $(topdir)/maxpath.h
|
||||||
|
let.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
let.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
let.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
let.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
let.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
pushd.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
pushd.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
pushd.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
pushd.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||||
|
pushd.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
pushd.o: $(topdir)/maxpath.h $(srcdir)/common.h
|
||||||
|
read.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
read.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
read.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
read.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
read.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
return.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
return.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
return.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
return.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
return.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
set.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
set.o: $(topdir)/general.h $(topdir)/subst.h $(topdir)/externs.h
|
||||||
|
set.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
set.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
set.o: $(topdir)/maxpath.h $(topdir)/error.h
|
||||||
|
setattr.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
setattr.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/maxpath.h
|
||||||
|
setattr.o: $(topdir)/quit.h $(srcdir)/common.h $(srcdir)/bashgetopt.h
|
||||||
|
setattr.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||||
|
setattr.o: $(topdir)/externs.h
|
||||||
|
setattr.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
shift.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
shift.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
shift.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
shift.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
shift.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
source.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
source.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
source.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
source.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
source.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
suspend.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
suspend.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
suspend.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
suspend.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
suspend.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
test.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
test.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
test.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
test.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
test.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
times.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
times.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
times.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
times.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
times.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
trap.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
trap.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/externs.h
|
||||||
|
trap.o: $(topdir)/quit.h $(srcdir)/common.h $(topdir)/maxpath.h
|
||||||
|
trap.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||||
|
trap.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
trap.o: $(topdir)/execute_cmd.h
|
||||||
|
type.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
type.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
type.o: $(topdir)/quit.h $(srcdir)/common.h $(topdir)/maxpath.h
|
||||||
|
type.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||||
|
type.o: $(topdir)/externs.h
|
||||||
|
type.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
ulimit.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
ulimit.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
ulimit.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
ulimit.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
ulimit.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
umask.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
umask.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
umask.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
umask.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
umask.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
wait.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
wait.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
wait.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
wait.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
wait.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
shopt.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
|
||||||
|
shopt.o: $(topdir)/error.h $(topdir)/general.h
|
||||||
|
shopt.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||||
|
shopt.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
|
||||||
|
shopt.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||||
|
shopt.o: $(srcdir)/common.h $(srcdir)/bashgetopt.h
|
||||||
|
bashgetopt.o: $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
|
||||||
|
mkbuiltins.o: $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
|
||||||
|
fc.o: $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
|
||||||
|
|
||||||
|
#bind.o: $(RL_LIBSRC)chardefs.h $(RL_LIBSRC)readline.h $(RL_LIBSRC)keymaps.h
|
||||||
@@ -23,55 +23,81 @@ $BUILTIN alias
|
|||||||
$FUNCTION alias_builtin
|
$FUNCTION alias_builtin
|
||||||
$DEPENDS_ON ALIAS
|
$DEPENDS_ON ALIAS
|
||||||
$PRODUCES alias.c
|
$PRODUCES alias.c
|
||||||
$SHORT_DOC alias [ name[=value] ... ]
|
$SHORT_DOC alias [-p] [name[=value] ... ]
|
||||||
`alias' with no arguments prints the list of aliases in the form
|
`alias' with no arguments or with the -p option prints the list
|
||||||
NAME=VALUE on standard output. An alias is defined for each NAME
|
of aliases in the form alias NAME=VALUE on standard output.
|
||||||
whose VALUE is given. A trailing space in VALUE causes the next
|
Otherwise, an alias is defined for each NAME whose VALUE is given.
|
||||||
word to be checked for alias substitution. Alias returns true
|
A trailing space in VALUE causes the next word to be checked for
|
||||||
unless a NAME is given for which no alias has been defined.
|
alias substitution when the alias is expanded. Alias returns
|
||||||
|
true unless a NAME is given for which no alias has been defined.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include "../config.h"
|
#include <config.h>
|
||||||
|
|
||||||
#if defined (ALIAS)
|
#if defined (ALIAS)
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include "../shell.h"
|
# include "../shell.h"
|
||||||
# include "../alias.h"
|
# include "../alias.h"
|
||||||
# include "common.h"
|
# include "common.h"
|
||||||
|
# include "bashgetopt.h"
|
||||||
|
|
||||||
extern int interactive;
|
extern int interactive;
|
||||||
static void print_alias ();
|
static void print_alias ();
|
||||||
|
|
||||||
/* Hack the alias command in a Korn shell way. */
|
/* Hack the alias command in a Korn shell way. */
|
||||||
|
int
|
||||||
alias_builtin (list)
|
alias_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int any_failed = 0;
|
int any_failed, offset, pflag;
|
||||||
|
alias_t **alias_list, *t;
|
||||||
|
char *name, *value;
|
||||||
|
|
||||||
if (!list)
|
pflag = 0;
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((offset = internal_getopt (list, "p")) != -1)
|
||||||
{
|
{
|
||||||
register int i;
|
switch (offset)
|
||||||
ASSOC **alias_list;
|
{
|
||||||
|
case 'p':
|
||||||
|
pflag = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
|
return (EX_USAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!aliases)
|
list = loptend;
|
||||||
|
|
||||||
|
if (list == 0 || pflag)
|
||||||
|
{
|
||||||
|
if (aliases == 0)
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
|
|
||||||
alias_list = all_aliases ();
|
alias_list = all_aliases ();
|
||||||
|
|
||||||
if (!alias_list)
|
if (alias_list == 0)
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
|
|
||||||
for (i = 0; alias_list[i]; i++)
|
for (offset = 0; alias_list[offset]; offset++)
|
||||||
print_alias (alias_list[i]);
|
print_alias (alias_list[offset]);
|
||||||
|
|
||||||
free (alias_list); /* XXX - Do not free the strings. */
|
free (alias_list); /* XXX - Do not free the strings. */
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
any_failed = 0;
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
register char *value, *name = list->word->word;
|
name = list->word->word;
|
||||||
register int offset;
|
|
||||||
|
|
||||||
for (offset = 0; name[offset] && name[offset] != '='; offset++)
|
for (offset = 0; name[offset] && name[offset] != '='; offset++)
|
||||||
;
|
;
|
||||||
@@ -85,7 +111,7 @@ alias_builtin (list)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSOC *t = find_alias (name);
|
t = find_alias (name);
|
||||||
if (t)
|
if (t)
|
||||||
print_alias (t);
|
print_alias (t);
|
||||||
else
|
else
|
||||||
@@ -97,11 +123,8 @@ alias_builtin (list)
|
|||||||
}
|
}
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (any_failed)
|
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
else
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
}
|
||||||
#endif /* ALIAS */
|
#endif /* ALIAS */
|
||||||
|
|
||||||
@@ -115,33 +138,37 @@ $END
|
|||||||
|
|
||||||
#if defined (ALIAS)
|
#if defined (ALIAS)
|
||||||
/* Remove aliases named in LIST from the aliases database. */
|
/* Remove aliases named in LIST from the aliases database. */
|
||||||
|
int
|
||||||
unalias_builtin (list)
|
unalias_builtin (list)
|
||||||
register WORD_LIST *list;
|
register WORD_LIST *list;
|
||||||
{
|
{
|
||||||
register ASSOC *alias;
|
register alias_t *alias;
|
||||||
int any_failed = 0;
|
int opt, aflag;
|
||||||
|
|
||||||
while (list && *list->word->word == '-')
|
aflag = 0;
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "a")) != -1)
|
||||||
{
|
{
|
||||||
register char *word = list->word->word;
|
switch (opt)
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
aflag = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
|
return (EX_USAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ISOPTION (word, 'a'))
|
list = loptend;
|
||||||
|
|
||||||
|
if (aflag)
|
||||||
{
|
{
|
||||||
delete_all_aliases ();
|
delete_all_aliases ();
|
||||||
list = list->next;
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
|
||||||
else if (ISOPTION (word, '-'))
|
|
||||||
{
|
|
||||||
list = list->next;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bad_option (word);
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aflag = 0;
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
alias = find_alias (list->word->word);
|
alias = find_alias (list->word->word);
|
||||||
@@ -151,27 +178,25 @@ unalias_builtin (list)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (interactive)
|
if (interactive)
|
||||||
builtin_error ("`%s' not an alias", list->word->word);
|
builtin_error ("`%s': not an alias", list->word->word);
|
||||||
|
|
||||||
any_failed++;
|
aflag++;
|
||||||
}
|
}
|
||||||
|
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (any_failed)
|
return (aflag ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
else
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output ALIAS in such a way as to allow it to be read back in. */
|
/* Output ALIAS in such a way as to allow it to be read back in. */
|
||||||
static void
|
static void
|
||||||
print_alias (alias)
|
print_alias (alias)
|
||||||
ASSOC *alias;
|
alias_t *alias;
|
||||||
{
|
{
|
||||||
char *value = single_quote (alias->value);
|
char *value;
|
||||||
|
|
||||||
|
value = single_quote (alias->value);
|
||||||
printf ("alias %s=%s\n", alias->name, value);
|
printf ("alias %s=%s\n", alias->name, value);
|
||||||
free (value);
|
free (value);
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,17 @@ 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
|
with Bash; see the file COPYING. If not, write to the Free Software
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include <errno.h>
|
#include <config.h>
|
||||||
#include "shell.h"
|
|
||||||
|
|
||||||
#include "bashansi.h"
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "../shell.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#define ERR(S, C) builtin_error("%s%c", (S), (C))
|
#define ERR(S, C) builtin_error("%s%c", (S), (C))
|
||||||
|
|
||||||
@@ -41,14 +48,21 @@ char *opts;
|
|||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
register char *cp;
|
register char *cp;
|
||||||
|
int plus; /* nonzero means to handle +option */
|
||||||
|
|
||||||
if (!list) {
|
if (*opts == '+') {
|
||||||
|
plus = 1;
|
||||||
|
opts++;
|
||||||
|
} else
|
||||||
|
plus = 0;
|
||||||
|
|
||||||
|
if (list == 0) {
|
||||||
list_optarg = (char *)NULL;
|
list_optarg = (char *)NULL;
|
||||||
loptend = (WORD_LIST *)NULL; /* No non-option arguments */
|
loptend = (WORD_LIST *)NULL; /* No non-option arguments */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list != lhead || !lhead) {
|
if (list != lhead || lhead == 0) {
|
||||||
/* Hmmm.... called with a different word list. Reset. */
|
/* Hmmm.... called with a different word list. Reset. */
|
||||||
sp = 1;
|
sp = 1;
|
||||||
lcurrent = lhead = list;
|
lcurrent = lhead = list;
|
||||||
@@ -56,7 +70,7 @@ char *opts;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sp == 1) {
|
if (sp == 1) {
|
||||||
if (!lcurrent ||
|
if (lcurrent == 0 ||
|
||||||
(lcurrent->word->word[0] != '-' || lcurrent->word->word[1] == '\0')) {
|
(lcurrent->word->word[0] != '-' || lcurrent->word->word[1] == '\0')) {
|
||||||
lhead = (WORD_LIST *)NULL;
|
lhead = (WORD_LIST *)NULL;
|
||||||
loptend = lcurrent;
|
loptend = lcurrent;
|
||||||
@@ -84,23 +98,46 @@ char *opts;
|
|||||||
return('?');
|
return('?');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*++cp == ':') {
|
if (*++cp == ':' || *cp == ';') {
|
||||||
/* Option requires an argument. */
|
/* `:': Option requires an argument. */
|
||||||
|
/* `;': option argument may be missing */
|
||||||
/* We allow -l2 as equivalent to -l 2 */
|
/* We allow -l2 as equivalent to -l 2 */
|
||||||
if (lcurrent->word->word[sp+1] != '\0') {
|
if (lcurrent->word->word[sp+1]) {
|
||||||
list_optarg = &(lcurrent->word->word[sp+1]);
|
list_optarg = lcurrent->word->word + sp + 1;
|
||||||
lcurrent = lcurrent->next;
|
lcurrent = lcurrent->next;
|
||||||
} else if (lcurrent->next == NULL) {
|
/* If the specifier is `;', don't set optarg if the next
|
||||||
|
argument looks like another option. */
|
||||||
|
} else if (lcurrent->next && (*cp == ':' || lcurrent->next->word->word[0] != '-')) {
|
||||||
|
lcurrent = lcurrent->next;
|
||||||
|
list_optarg = lcurrent->word->word;
|
||||||
|
lcurrent = lcurrent->next;
|
||||||
|
} else if (*cp == ';') {
|
||||||
|
list_optarg = (char *)NULL;
|
||||||
|
lcurrent = lcurrent->next;
|
||||||
|
} else { /* lcurrent->next == NULL */
|
||||||
ERR("option requires an argument: -", c);
|
ERR("option requires an argument: -", c);
|
||||||
sp = 1;
|
sp = 1;
|
||||||
list_optarg = (char *)NULL;
|
list_optarg = (char *)NULL;
|
||||||
return('?');
|
return('?');
|
||||||
|
}
|
||||||
|
sp = 1;
|
||||||
|
} else if (*cp == '#') {
|
||||||
|
/* optional numeric argument */
|
||||||
|
if (lcurrent->word->word[sp+1]) {
|
||||||
|
if (digit(lcurrent->word->word[sp+1])) {
|
||||||
|
list_optarg = lcurrent->word->word + sp + 1;
|
||||||
|
lcurrent = lcurrent->next;
|
||||||
|
} else
|
||||||
|
list_optarg = (char *)NULL;
|
||||||
} else {
|
} else {
|
||||||
|
if (lcurrent->next && legal_number(lcurrent->next->word->word, (long *)0)) {
|
||||||
lcurrent = lcurrent->next;
|
lcurrent = lcurrent->next;
|
||||||
list_optarg = lcurrent->word->word;
|
list_optarg = lcurrent->word->word;
|
||||||
lcurrent = lcurrent->next;
|
lcurrent = lcurrent->next;
|
||||||
|
} else
|
||||||
|
list_optarg = (char *)NULL;
|
||||||
}
|
}
|
||||||
sp = 1;
|
|
||||||
} else {
|
} else {
|
||||||
/* No argument, just return the option. */
|
/* No argument, just return the option. */
|
||||||
if (lcurrent->word->word[++sp] == '\0') {
|
if (lcurrent->word->word[++sp] == '\0') {
|
||||||
|
|||||||
@@ -21,10 +21,12 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||||||
|
|
||||||
$PRODUCES bind.c
|
$PRODUCES bind.c
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
$BUILTIN bind
|
$BUILTIN bind
|
||||||
$DEPENDS_ON READLINE
|
$DEPENDS_ON READLINE
|
||||||
$FUNCTION bind_builtin
|
$FUNCTION bind_builtin
|
||||||
$SHORT_DOC bind [-lvd] [-m keymap] [-f filename] [-q name] [keyseq:readline-function]
|
$SHORT_DOC bind [-lpvsPVS] [-m keymap] [-f filename] [-q name] [-r keyseq] [keyseq:readline-function]
|
||||||
Bind a key sequence to a Readline function, or to a macro. The
|
Bind a key sequence to a Readline function, or to a macro. The
|
||||||
syntax is equivalent to that found in ~/.inputrc, but must be
|
syntax is equivalent to that found in ~/.inputrc, but must be
|
||||||
passed as a single argument: bind '"\C-x\C-r": re-read-init-file'.
|
passed as a single argument: bind '"\C-x\C-r": re-read-init-file'.
|
||||||
@@ -34,49 +36,75 @@ Arguments we accept:
|
|||||||
emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,
|
emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,
|
||||||
vi-command, and vi-insert.
|
vi-command, and vi-insert.
|
||||||
-l List names of functions.
|
-l List names of functions.
|
||||||
-v List function names and bindings.
|
-P List function names and bindings.
|
||||||
-d Dump functions and bindings such that they
|
-p List functions and bindings in a form that can be
|
||||||
can be read back in.
|
reused as input.
|
||||||
|
-r keyseq Remove the binding for KEYSEQ.
|
||||||
-f filename Read key bindings from FILENAME.
|
-f filename Read key bindings from FILENAME.
|
||||||
-q function-name Query about which keys invoke the named function.
|
-q function-name Query about which keys invoke the named function.
|
||||||
|
-V List variable names and values
|
||||||
|
-v List variable names and values in a form that can
|
||||||
|
be reused as input.
|
||||||
|
-S List key sequences that invoke macros and their values
|
||||||
|
-s List key sequences that invoke macros and their values in
|
||||||
|
a form that can be reused as input.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "../shell.h"
|
|
||||||
#if defined (READLINE)
|
#if defined (READLINE)
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#if !defined (errno)
|
#if !defined (errno)
|
||||||
extern int errno;
|
extern int errno;
|
||||||
#endif /* !errno */
|
#endif /* !errno */
|
||||||
|
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
|
|
||||||
|
#include "../shell.h"
|
||||||
|
#include "../bashline.h"
|
||||||
#include "bashgetopt.h"
|
#include "bashgetopt.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
static int query_bindings ();
|
static int query_bindings ();
|
||||||
|
|
||||||
extern int bash_readline_initialized;
|
|
||||||
extern int no_line_editing;
|
extern int no_line_editing;
|
||||||
|
|
||||||
#define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0)
|
#define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0)
|
||||||
|
|
||||||
#define USAGE "usage: bind [-lvd] [-m keymap] [-f filename] [-q name] [keyseq:readline_func]"
|
#define LFLAG 0x01
|
||||||
|
#define PFLAG 0x02
|
||||||
|
#define FFLAG 0x04
|
||||||
|
#define VFLAG 0x08
|
||||||
|
#define QFLAG 0x10
|
||||||
|
#define MFLAG 0x20
|
||||||
|
#define RFLAG 0x40
|
||||||
|
#define PPFLAG 0x80
|
||||||
|
#define VVFLAG 0x100
|
||||||
|
#define SFLAG 0x200
|
||||||
|
#define SSFLAG 0x400
|
||||||
|
|
||||||
int
|
int
|
||||||
bind_builtin (list)
|
bind_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int return_code = EXECUTION_SUCCESS;
|
int return_code;
|
||||||
FILE *old_rl_outstream;
|
FILE *old_rl_outstream;
|
||||||
Keymap kmap, saved_keymap;
|
Keymap kmap, saved_keymap;
|
||||||
int lflag, dflag, fflag, vflag, qflag, mflag, opt;
|
int flags, opt;
|
||||||
char *initfile, *map_name, *fun_name;
|
char *initfile, *map_name, *fun_name, *remove_seq;
|
||||||
|
|
||||||
if (no_line_editing)
|
if (no_line_editing)
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
|
|
||||||
kmap = saved_keymap = (Keymap) NULL;
|
kmap = saved_keymap = (Keymap) NULL;
|
||||||
lflag = dflag = vflag = fflag = qflag = mflag = 0;
|
flags = 0;
|
||||||
initfile = map_name = fun_name = (char *)NULL;
|
initfile = map_name = fun_name = remove_seq = (char *)NULL;
|
||||||
|
return_code = EXECUTION_SUCCESS;
|
||||||
|
|
||||||
if (!bash_readline_initialized)
|
if (!bash_readline_initialized)
|
||||||
initialize_readline ();
|
initialize_readline ();
|
||||||
@@ -88,39 +116,49 @@ bind_builtin (list)
|
|||||||
rl_outstream = stdout;
|
rl_outstream = stdout;
|
||||||
|
|
||||||
reset_internal_getopt ();
|
reset_internal_getopt ();
|
||||||
while ((opt = internal_getopt (list, "lvdf:q:m:")) != EOF)
|
while ((opt = internal_getopt (list, "lvpVPsSf:q:m:r:")) != EOF)
|
||||||
{
|
{
|
||||||
switch (opt)
|
switch (opt)
|
||||||
{
|
{
|
||||||
case 'l':
|
case 'l':
|
||||||
lflag++;
|
flags |= LFLAG;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
vflag++;
|
flags |= VFLAG;
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
case 'd':
|
flags |= PFLAG;
|
||||||
dflag++;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
fflag++;
|
flags |= FFLAG;
|
||||||
initfile = list_optarg;
|
initfile = list_optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm':
|
case 'm':
|
||||||
mflag++;
|
flags |= MFLAG;
|
||||||
map_name = list_optarg;
|
map_name = list_optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'q':
|
case 'q':
|
||||||
qflag++;
|
flags |= QFLAG;
|
||||||
fun_name = list_optarg;
|
fun_name = list_optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
flags |= RFLAG;
|
||||||
|
remove_seq = list_optarg;
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
flags |= VVFLAG;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
flags |= PPFLAG;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
flags |= SFLAG;
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
flags |= SSFLAG;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
builtin_error (USAGE);
|
builtin_usage ();
|
||||||
BIND_RETURN (EX_USAGE);
|
BIND_RETURN (EX_USAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,12 +168,12 @@ bind_builtin (list)
|
|||||||
/* First, see if we need to install a special keymap for this
|
/* First, see if we need to install a special keymap for this
|
||||||
command. Then start on the arguments. */
|
command. Then start on the arguments. */
|
||||||
|
|
||||||
if (mflag && map_name)
|
if ((flags & MFLAG) && map_name)
|
||||||
{
|
{
|
||||||
kmap = rl_get_keymap_by_name (map_name);
|
kmap = rl_get_keymap_by_name (map_name);
|
||||||
if (!kmap)
|
if (!kmap)
|
||||||
{
|
{
|
||||||
builtin_error ("`%s': illegal keymap name", map_name);
|
builtin_error ("`%s': invalid keymap name", map_name);
|
||||||
BIND_RETURN (EXECUTION_FAILURE);
|
BIND_RETURN (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,16 +187,28 @@ bind_builtin (list)
|
|||||||
/* XXX - we need to add exclusive use tests here. It doesn't make sense
|
/* XXX - we need to add exclusive use tests here. It doesn't make sense
|
||||||
to use some of these options together. */
|
to use some of these options together. */
|
||||||
/* Now hack the option arguments */
|
/* Now hack the option arguments */
|
||||||
if (lflag)
|
if (flags & LFLAG)
|
||||||
rl_list_funmap_names (0);
|
rl_list_funmap_names ();
|
||||||
|
|
||||||
if (vflag)
|
if (flags & PFLAG)
|
||||||
rl_function_dumper (0);
|
|
||||||
|
|
||||||
if (dflag)
|
|
||||||
rl_function_dumper (1);
|
rl_function_dumper (1);
|
||||||
|
|
||||||
if (fflag && initfile)
|
if (flags & PPFLAG)
|
||||||
|
rl_function_dumper (0);
|
||||||
|
|
||||||
|
if (flags & SFLAG)
|
||||||
|
rl_macro_dumper (1);
|
||||||
|
|
||||||
|
if (flags & SSFLAG)
|
||||||
|
rl_macro_dumper (0);
|
||||||
|
|
||||||
|
if (flags & VFLAG)
|
||||||
|
rl_variable_dumper (1);
|
||||||
|
|
||||||
|
if (flags & VVFLAG)
|
||||||
|
rl_variable_dumper (0);
|
||||||
|
|
||||||
|
if ((flags & FFLAG) && initfile)
|
||||||
{
|
{
|
||||||
if (rl_read_init_file (initfile) != 0)
|
if (rl_read_init_file (initfile) != 0)
|
||||||
{
|
{
|
||||||
@@ -167,9 +217,18 @@ bind_builtin (list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qflag && fun_name)
|
if ((flags & QFLAG) && fun_name)
|
||||||
return_code = query_bindings (fun_name);
|
return_code = query_bindings (fun_name);
|
||||||
|
|
||||||
|
if ((flags & RFLAG) && remove_seq)
|
||||||
|
{
|
||||||
|
if (rl_set_key (remove_seq, (Function *)NULL, rl_get_keymap ()) != 0)
|
||||||
|
{
|
||||||
|
builtin_error ("cannot unbind %s", remove_seq);
|
||||||
|
BIND_RETURN (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Process the rest of the arguments as binding specifications. */
|
/* Process the rest of the arguments as binding specifications. */
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,8 +27,14 @@ $SHORT_DOC break [n]
|
|||||||
Exit from within a FOR, WHILE or UNTIL loop. If N is specified,
|
Exit from within a FOR, WHILE or UNTIL loop. If N is specified,
|
||||||
break N levels.
|
break N levels.
|
||||||
$END
|
$END
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
extern char *this_command_name;
|
extern char *this_command_name;
|
||||||
|
|
||||||
@@ -45,6 +51,7 @@ int continuing = 0;
|
|||||||
|
|
||||||
/* Set up to break x levels, where x defaults to 1, but can be specified
|
/* Set up to break x levels, where x defaults to 1, but can be specified
|
||||||
as the first argument. */
|
as the first argument. */
|
||||||
|
int
|
||||||
break_builtin (list)
|
break_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
@@ -75,6 +82,7 @@ $END
|
|||||||
|
|
||||||
/* Set up to continue x levels, where x defaults to 1, but can be specified
|
/* Set up to continue x levels, where x defaults to 1, but can be specified
|
||||||
as the first argument. */
|
as the first argument. */
|
||||||
|
int
|
||||||
continue_builtin (list)
|
continue_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
@@ -103,7 +111,7 @@ check_loop_level ()
|
|||||||
{
|
{
|
||||||
#if defined (BREAK_COMPLAINS)
|
#if defined (BREAK_COMPLAINS)
|
||||||
if (!loop_level)
|
if (!loop_level)
|
||||||
builtin_error ("Only meaningful in a `for', `while', or `until' loop");
|
builtin_error ("only meaningful in a `for', `while', or `until' loop");
|
||||||
#endif /* BREAK_COMPLAINS */
|
#endif /* BREAK_COMPLAINS */
|
||||||
|
|
||||||
return (loop_level);
|
return (loop_level);
|
||||||
|
|||||||
@@ -28,15 +28,20 @@ Run a shell builtin. This is useful when you wish to rename a
|
|||||||
shell builtin to be a function, but need the functionality of the
|
shell builtin to be a function, but need the functionality of the
|
||||||
builtin within the function itself.
|
builtin within the function itself.
|
||||||
$END
|
$END
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
extern char *this_command_name;
|
extern char *this_command_name;
|
||||||
|
|
||||||
/* Run the command mentioned in list directly, without going through the
|
/* Run the command mentioned in list directly, without going through the
|
||||||
normal alias/function/builtin/filename lookup process. */
|
normal alias/function/builtin/filename lookup process. */
|
||||||
|
int
|
||||||
builtin_builtin (list)
|
builtin_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
|
|||||||
854
builtins/cd.def
854
builtins/cd.def
@@ -1,5 +1,5 @@
|
|||||||
This file is cd.def, from which is created cd.c. It implements the
|
This file is cd.def, from which is created cd.c. It implements the
|
||||||
builtins "cd", "pwd", "pushd", "popd", and "dirs" in Bash.
|
builtins "cd" and "pwd" in Bash.
|
||||||
|
|
||||||
Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
|
||||||
@@ -20,15 +20,20 @@ with Bash; see the file COPYING. If not, write to the Free Software
|
|||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
$PRODUCES cd.c
|
$PRODUCES cd.c
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../bashtypes.h"
|
||||||
|
#include "../posixdir.h"
|
||||||
|
#include "../posixstat.h"
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
#if defined (HAVE_STRING_H)
|
#include <stdio.h>
|
||||||
# include <string.h>
|
|
||||||
#else /* !HAVE_STRING_H */
|
#include "../bashansi.h"
|
||||||
# include <strings.h>
|
|
||||||
#endif /* !HAVE_STRING_H */
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <tilde/tilde.h>
|
#include <tilde/tilde.h>
|
||||||
@@ -37,27 +42,102 @@ $PRODUCES cd.c
|
|||||||
#include "../flags.h"
|
#include "../flags.h"
|
||||||
#include "../maxpath.h"
|
#include "../maxpath.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
#if !defined (errno)
|
#if !defined (errno)
|
||||||
extern int errno;
|
extern int errno;
|
||||||
#endif /* !errno */
|
#endif /* !errno */
|
||||||
|
|
||||||
static int change_to_directory (), cd_to_string ();
|
extern int posixly_correct, interactive;
|
||||||
|
extern char *bash_getcwd_errstr;
|
||||||
|
|
||||||
|
static int change_to_directory ();
|
||||||
|
|
||||||
|
static char *cdspell ();
|
||||||
|
static int spname (), mindist (), spdist ();
|
||||||
|
int cdspelling = 1;
|
||||||
|
|
||||||
|
int cdable_vars;
|
||||||
|
|
||||||
$BUILTIN cd
|
$BUILTIN cd
|
||||||
$FUNCTION cd_builtin
|
$FUNCTION cd_builtin
|
||||||
$SHORT_DOC cd [dir]
|
$SHORT_DOC cd [-PL] [dir]
|
||||||
Change the current directory to DIR. The variable $HOME is the
|
Change the current directory to DIR. The variable $HOME is the
|
||||||
default DIR. The variable $CDPATH defines the search path for
|
default DIR. The variable $CDPATH defines the search path for
|
||||||
the directory containing DIR. Alternative directory names are
|
the directory containing DIR. Alternative directory names in CDPATH
|
||||||
separated by a colon (:). A null directory name is the same as
|
are separated by a colon (:). A null directory name is the same as
|
||||||
the current directory, i.e. `.'. If DIR begins with a slash (/),
|
the current directory, i.e. `.'. If DIR begins with a slash (/),
|
||||||
then $CDPATH is not used. If the directory is not found, and the
|
then $CDPATH is not used. If the directory is not found, and the
|
||||||
shell variable `cdable_vars' exists, then try the word as a variable
|
shell option `cdable_vars' is set, then try the word as a variable
|
||||||
name. If that variable has a value, then cd to the value of that
|
name. If that variable has a value, then cd to the value of that
|
||||||
variable.
|
variable. The -P option says to use the physical directory structure
|
||||||
|
instead of following symbolic links; the -L option forces symbolic links
|
||||||
|
to be followed.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
/* Take PATH, an element from $CDPATH, and DIR, a directory name, and paste
|
||||||
|
them together into PATH/DIR. Tilde expansion is performed on PATH if
|
||||||
|
DOTILDE is non-zero. If PATH is the empty string, it is converted to
|
||||||
|
`./', since a null element in $CDPATH means the current directory. */
|
||||||
|
static char *
|
||||||
|
mkpath (path, dir, dotilde)
|
||||||
|
char *path, *dir;
|
||||||
|
int dotilde;
|
||||||
|
{
|
||||||
|
int dirlen, pathlen;
|
||||||
|
char *ret, *xpath;
|
||||||
|
|
||||||
|
if (*path == '\0')
|
||||||
|
{
|
||||||
|
xpath = xmalloc (2);
|
||||||
|
xpath[0] = '.';
|
||||||
|
xpath[1] = '\0';
|
||||||
|
pathlen = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xpath = (dotilde && *path == '~') ? bash_tilde_expand (path) : path;
|
||||||
|
pathlen = strlen (xpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
dirlen = strlen (dir);
|
||||||
|
ret = xmalloc (2 + dirlen + pathlen);
|
||||||
|
strcpy (ret, xpath);
|
||||||
|
if (xpath[pathlen - 1] != '/')
|
||||||
|
{
|
||||||
|
ret[pathlen++] = '/';
|
||||||
|
ret[pathlen] = '\0';
|
||||||
|
}
|
||||||
|
strcpy (ret + pathlen, dir);
|
||||||
|
if (xpath != path)
|
||||||
|
free (xpath);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
bindpwd (no_symlinks)
|
||||||
|
int no_symlinks;
|
||||||
|
{
|
||||||
|
char *dirname;
|
||||||
|
int old_symlinks;
|
||||||
|
|
||||||
|
if (no_symlinks)
|
||||||
|
{
|
||||||
|
old_symlinks = no_symbolic_links;
|
||||||
|
no_symbolic_links = 1;
|
||||||
|
dirname = get_working_directory ("cd");
|
||||||
|
no_symbolic_links = old_symlinks;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dirname = get_working_directory ("cd");
|
||||||
|
|
||||||
|
bind_variable ("OLDPWD", get_string_value ("PWD"));
|
||||||
|
bind_variable ("PWD", dirname);
|
||||||
|
|
||||||
|
FREE (dirname);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
/* This builtin is ultimately the way that all user-visible commands should
|
/* This builtin is ultimately the way that all user-visible commands should
|
||||||
change the current working directory. It is called by cd_to_string (),
|
change the current working directory. It is called by cd_to_string (),
|
||||||
so the programming interface is simple, and it handles errors and
|
so the programming interface is simple, and it handles errors and
|
||||||
@@ -66,7 +146,9 @@ int
|
|||||||
cd_builtin (list)
|
cd_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
char *dirname;
|
char *dirname, *cdpath, *path, *temp;
|
||||||
|
int path_index, no_symlinks, opt;
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
#if defined (RESTRICTED_SHELL)
|
#if defined (RESTRICTED_SHELL)
|
||||||
if (restricted)
|
if (restricted)
|
||||||
@@ -76,154 +158,177 @@ cd_builtin (list)
|
|||||||
}
|
}
|
||||||
#endif /* RESTRICTED_SHELL */
|
#endif /* RESTRICTED_SHELL */
|
||||||
|
|
||||||
if (list)
|
no_symlinks = no_symbolic_links;
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "LP")) != -1)
|
||||||
{
|
{
|
||||||
char *extract_colon_unit ();
|
switch (opt)
|
||||||
char *path_string = get_string_value ("CDPATH");
|
|
||||||
char *path;
|
|
||||||
int path_index = 0, dirlen, pathlen;
|
|
||||||
|
|
||||||
dirname = list->word->word;
|
|
||||||
|
|
||||||
if (path_string && !absolute_pathname (dirname))
|
|
||||||
{
|
{
|
||||||
while ((path = extract_colon_unit (path_string, &path_index)))
|
case 'P':
|
||||||
{
|
no_symlinks = 1;
|
||||||
char *dir;
|
break;
|
||||||
|
case 'L':
|
||||||
|
no_symlinks = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
if (*path == '~')
|
if (list == 0)
|
||||||
{
|
{
|
||||||
char *te_string = tilde_expand (path);
|
/* `cd' without arguments is equivalent to `cd $HOME' */
|
||||||
|
dirname = get_string_value ("HOME");
|
||||||
|
|
||||||
free (path);
|
if (dirname == 0)
|
||||||
path = te_string;
|
{
|
||||||
|
builtin_error ("HOME not set");
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*path)
|
if (change_to_directory (dirname, no_symlinks) == 0)
|
||||||
{
|
{
|
||||||
free (path);
|
builtin_error ("%s: %s", dirname, strerror (errno));
|
||||||
path = xmalloc (2);
|
return (EXECUTION_FAILURE);
|
||||||
path[0] = '.'; /* by definition. */
|
|
||||||
path[1] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dirlen = strlen (dirname);
|
|
||||||
pathlen = strlen (path);
|
|
||||||
dir = xmalloc (2 + dirlen + pathlen);
|
|
||||||
strcpy (dir, path);
|
|
||||||
if (path[pathlen - 1] != '/')
|
|
||||||
{
|
|
||||||
dir[pathlen++] = '/';
|
|
||||||
dir[pathlen] = '\0';
|
|
||||||
}
|
}
|
||||||
strcpy (dir + pathlen, dirname);
|
else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
|
||||||
free (path);
|
|
||||||
|
|
||||||
if (change_to_directory (dir))
|
|
||||||
{
|
{
|
||||||
/* replaces (strncmp (dir, "./", 2) != 0) */
|
/* This is `cd -', equivalent to `cd $OLDPWD' */
|
||||||
if (dir[0] != '.' || dir[1] != '/')
|
dirname = get_string_value ("OLDPWD");
|
||||||
printf ("%s\n", dir);
|
|
||||||
|
|
||||||
free (dir);
|
if (dirname == 0 || change_to_directory (dirname, no_symlinks) == 0)
|
||||||
goto bind_and_exit;
|
{
|
||||||
|
if (dirname == 0)
|
||||||
|
builtin_error ("OLDPWD not set");
|
||||||
|
else
|
||||||
|
builtin_error ("%s: %s", dirname, strerror (errno));
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
free (dir);
|
{
|
||||||
|
dirname = list->word->word;
|
||||||
|
|
||||||
|
if (absolute_pathname (dirname) == 0 && (cdpath = get_string_value ("CDPATH")))
|
||||||
|
{
|
||||||
|
/* Find directory in $CDPATH. */
|
||||||
|
path_index = 0;
|
||||||
|
while ((path = extract_colon_unit (cdpath, &path_index)))
|
||||||
|
{
|
||||||
|
temp = mkpath (path, dirname, 1);
|
||||||
|
free (path);
|
||||||
|
|
||||||
|
if (stat (temp, &sb) < 0 || S_ISDIR (sb.st_mode) == 0)
|
||||||
|
{
|
||||||
|
free (temp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (change_to_directory (temp, no_symlinks))
|
||||||
|
{
|
||||||
|
if (temp[0] != '.' || temp[1] != '/')
|
||||||
|
printf ("%s\n", temp);
|
||||||
|
|
||||||
|
free (temp);
|
||||||
|
/* Posix.2 says that after using CDPATH, the resultant
|
||||||
|
value of $PWD will not contain symlinks. */
|
||||||
|
return (bindpwd (posixly_correct));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
free (temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!change_to_directory (dirname))
|
if (change_to_directory (dirname, no_symlinks))
|
||||||
{
|
return (bindpwd (no_symlinks));
|
||||||
/* Maybe this is `cd -', equivalent to `cd $OLDPWD' */
|
|
||||||
if (dirname[0] == '-' && dirname[1] == '\0')
|
|
||||||
{
|
|
||||||
char *t = get_string_value ("OLDPWD");
|
|
||||||
|
|
||||||
if (t && change_to_directory (t))
|
|
||||||
goto bind_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the user requests it, then perhaps this is the name of
|
/* If the user requests it, then perhaps this is the name of
|
||||||
a shell variable, whose value contains the directory to
|
a shell variable, whose value contains the directory to
|
||||||
change to. If that is the case, then change to that
|
change to. If that is the case, then change to that
|
||||||
directory. */
|
directory. */
|
||||||
if (find_variable ("cdable_vars"))
|
if (cdable_vars)
|
||||||
{
|
{
|
||||||
char *t = get_string_value (dirname);
|
temp = get_string_value (dirname);
|
||||||
|
if (temp && change_to_directory (temp, no_symlinks))
|
||||||
if (t && change_to_directory (t))
|
|
||||||
{
|
{
|
||||||
printf ("%s\n", t);
|
printf ("%s\n", temp);
|
||||||
goto bind_and_exit;
|
return (bindpwd (no_symlinks));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file_error (dirname);
|
/* If the user requests it, try to find a directory name similar in
|
||||||
return (EXECUTION_FAILURE);
|
spelling to the one requested, in case the user made a simple
|
||||||
}
|
typo. This is similar to the UNIX 8th and 9th Edition shells. */
|
||||||
goto bind_and_exit;
|
if (interactive && cdspelling)
|
||||||
|
{
|
||||||
|
temp = cdspell (dirname);
|
||||||
|
if (temp && change_to_directory (temp, no_symlinks))
|
||||||
|
{
|
||||||
|
printf ("%s\n", temp);
|
||||||
|
free (temp);
|
||||||
|
return (bindpwd (no_symlinks));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
FREE (temp);
|
||||||
dirname = get_string_value ("HOME");
|
}
|
||||||
|
|
||||||
if (!dirname)
|
builtin_error ("%s: %s", dirname, strerror (errno));
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
|
|
||||||
if (!change_to_directory (dirname))
|
|
||||||
{
|
|
||||||
file_error (dirname);
|
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bind_and_exit:
|
return (bindpwd (no_symlinks));
|
||||||
{
|
|
||||||
char *directory;
|
|
||||||
|
|
||||||
directory = get_working_directory ("cd");
|
|
||||||
|
|
||||||
bind_variable ("OLDPWD", get_string_value ("PWD"));
|
|
||||||
bind_variable ("PWD", directory);
|
|
||||||
|
|
||||||
FREE (directory);
|
|
||||||
}
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$BUILTIN pwd
|
$BUILTIN pwd
|
||||||
$FUNCTION pwd_builtin
|
$FUNCTION pwd_builtin
|
||||||
$SHORT_DOC pwd
|
$SHORT_DOC pwd [-PL]
|
||||||
Print the current working directory.
|
Print the current working directory. With the -P option, pwd prints
|
||||||
|
the physical directory, without any symbolic links; the -L option
|
||||||
|
makes pwd follow symbolic links.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
/* Non-zero means that pwd always give verbatim directory, regardless of
|
/* Non-zero means that pwd always prints the physical directory, without
|
||||||
symbolic link following. */
|
symbolic links. */
|
||||||
static int verbatim_pwd;
|
static int verbatim_pwd;
|
||||||
|
|
||||||
/* Print the name of the current working directory. */
|
/* Print the name of the current working directory. */
|
||||||
|
int
|
||||||
pwd_builtin (list)
|
pwd_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
char *directory, *s;
|
char *directory, *buffer;
|
||||||
|
int opt;
|
||||||
|
|
||||||
#if 0
|
|
||||||
no_args (list);
|
|
||||||
#else
|
|
||||||
verbatim_pwd = no_symbolic_links;
|
verbatim_pwd = no_symbolic_links;
|
||||||
if (list && (s = list->word->word) && s[0] == '-' && s[1] == 'P' && !s[2])
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "LP")) != -1)
|
||||||
|
{
|
||||||
|
switch (opt)
|
||||||
|
{
|
||||||
|
case 'P':
|
||||||
verbatim_pwd = 1;
|
verbatim_pwd = 1;
|
||||||
#endif
|
break;
|
||||||
|
case 'L':
|
||||||
|
verbatim_pwd = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
if (verbatim_pwd)
|
if (verbatim_pwd)
|
||||||
{
|
{
|
||||||
char *buffer = xmalloc (MAXPATHLEN);
|
buffer = xmalloc (PATH_MAX);
|
||||||
directory = getwd (buffer);
|
directory = getcwd (buffer, PATH_MAX);
|
||||||
|
|
||||||
if (!directory)
|
if (directory == 0)
|
||||||
{
|
{
|
||||||
builtin_error ("%s", buffer);
|
builtin_error ("%s: %s", bash_getcwd_errstr, strerror (errno));
|
||||||
free (buffer);
|
free (buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,370 +346,22 @@ pwd_builtin (list)
|
|||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
$BUILTIN pushd
|
|
||||||
$FUNCTION pushd_builtin
|
|
||||||
$DEPENDS_ON PUSHD_AND_POPD
|
|
||||||
$SHORT_DOC pushd [dir | +n | -n]
|
|
||||||
Adds a directory to the top of the directory stack, or rotates
|
|
||||||
the stack, making the new top of the stack the current working
|
|
||||||
directory. With no arguments, exchanges the top two directories.
|
|
||||||
|
|
||||||
+n Rotates the stack so that the Nth directory (counting
|
|
||||||
from the left of the list shown by `dirs') is at the top.
|
|
||||||
|
|
||||||
-n Rotates the stack so that the Nth directory (counting
|
|
||||||
from the right) is at the top.
|
|
||||||
|
|
||||||
dir adds DIR to the directory stack at the top, making it the
|
|
||||||
new current working directory.
|
|
||||||
|
|
||||||
You can see the directory stack with the `dirs' command.
|
|
||||||
$END
|
|
||||||
|
|
||||||
#if defined (PUSHD_AND_POPD)
|
|
||||||
/* Some useful commands whose behaviour has been observed in Csh. */
|
|
||||||
|
|
||||||
/* The list of remembered directories. */
|
|
||||||
static char **pushd_directory_list = (char **)NULL;
|
|
||||||
|
|
||||||
/* Number of existing slots in this list. */
|
|
||||||
static int directory_list_size = 0;
|
|
||||||
|
|
||||||
/* Offset to the end of the list. */
|
|
||||||
static int directory_list_offset = 0;
|
|
||||||
|
|
||||||
pushd_builtin (list)
|
|
||||||
WORD_LIST *list;
|
|
||||||
{
|
|
||||||
char *temp, *current_directory;
|
|
||||||
int j = directory_list_offset - 1;
|
|
||||||
char direction = '+';
|
|
||||||
|
|
||||||
/* If there is no argument list then switch current and
|
|
||||||
top of list. */
|
|
||||||
if (!list)
|
|
||||||
{
|
|
||||||
if (!directory_list_offset)
|
|
||||||
{
|
|
||||||
builtin_error ("No other directory");
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
current_directory = get_working_directory ("pushd");
|
|
||||||
if (!current_directory)
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
|
|
||||||
temp = pushd_directory_list[j];
|
|
||||||
pushd_directory_list[j] = current_directory;
|
|
||||||
goto change_to_temp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
direction = *(list->word->word);
|
|
||||||
if (direction == '+' || direction == '-')
|
|
||||||
{
|
|
||||||
int num;
|
|
||||||
if (1 == sscanf (&(list->word->word)[1], "%d", &num))
|
|
||||||
{
|
|
||||||
if (direction == '-')
|
|
||||||
num = directory_list_offset - num;
|
|
||||||
|
|
||||||
if (num > directory_list_offset || num < 0)
|
|
||||||
{
|
|
||||||
if (!directory_list_offset)
|
|
||||||
builtin_error ("Directory stack empty");
|
|
||||||
else
|
|
||||||
builtin_error ("Stack contains only %d directories",
|
|
||||||
directory_list_offset + 1);
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Rotate the stack num times. Remember, the
|
|
||||||
current directory acts like it is part of the
|
|
||||||
stack. */
|
|
||||||
temp = get_working_directory ("pushd");
|
|
||||||
|
|
||||||
if (!num)
|
|
||||||
goto change_to_temp;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
char *top =
|
|
||||||
pushd_directory_list[directory_list_offset - 1];
|
|
||||||
|
|
||||||
for (j = directory_list_offset - 2; j > -1; j--)
|
|
||||||
pushd_directory_list[j + 1] = pushd_directory_list[j];
|
|
||||||
|
|
||||||
pushd_directory_list[j + 1] = temp;
|
|
||||||
|
|
||||||
temp = top;
|
|
||||||
num--;
|
|
||||||
}
|
|
||||||
while (num);
|
|
||||||
|
|
||||||
temp = savestring (temp);
|
|
||||||
change_to_temp:
|
|
||||||
{
|
|
||||||
int tt = EXECUTION_FAILURE;
|
|
||||||
|
|
||||||
if (temp)
|
|
||||||
{
|
|
||||||
tt = cd_to_string (temp);
|
|
||||||
free (temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((tt == EXECUTION_SUCCESS))
|
|
||||||
dirs_builtin ((WORD_LIST *)NULL);
|
|
||||||
|
|
||||||
return (tt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Change to the directory in list->word->word. Save the current
|
|
||||||
directory on the top of the stack. */
|
|
||||||
current_directory = get_working_directory ("pushd");
|
|
||||||
if (!current_directory)
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
|
|
||||||
if (cd_builtin (list) == EXECUTION_SUCCESS)
|
|
||||||
{
|
|
||||||
if (directory_list_offset == directory_list_size)
|
|
||||||
{
|
|
||||||
pushd_directory_list = (char **)
|
|
||||||
xrealloc (pushd_directory_list,
|
|
||||||
(directory_list_size += 10) * sizeof (char *));
|
|
||||||
}
|
|
||||||
pushd_directory_list[directory_list_offset++] = current_directory;
|
|
||||||
|
|
||||||
dirs_builtin ((WORD_LIST *)NULL);
|
|
||||||
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
free (current_directory);
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* PUSHD_AND_POPD */
|
|
||||||
|
|
||||||
$BUILTIN dirs
|
|
||||||
$FUNCTION dirs_builtin
|
|
||||||
$DEPENDS_ON PUSHD_AND_POPD
|
|
||||||
$SHORT_DOC dirs [-l]
|
|
||||||
Display the list of currently remembered directories. Directories
|
|
||||||
find their way onto the list with the `pushd' command; you can get
|
|
||||||
back up through the list with the `popd' command.
|
|
||||||
|
|
||||||
The -l flag specifies that `dirs' should not print shorthand versions
|
|
||||||
of directories which are relative to your home directory. This means
|
|
||||||
that `~/bin' might be displayed as `/homes/bfox/bin'.
|
|
||||||
$END
|
|
||||||
|
|
||||||
#if defined (PUSHD_AND_POPD)
|
|
||||||
/* Print the current list of directories on the directory stack. */
|
|
||||||
dirs_builtin (list)
|
|
||||||
WORD_LIST *list;
|
|
||||||
{
|
|
||||||
int i, format, desired_index, index_flag;
|
|
||||||
char *temp, *w;
|
|
||||||
|
|
||||||
format = index_flag = 0;
|
|
||||||
desired_index = -1;
|
|
||||||
/* Maybe do long form or print specific dir stack entry? */
|
|
||||||
while (list)
|
|
||||||
{
|
|
||||||
if (strcmp (list->word->word, "-l") == 0)
|
|
||||||
{
|
|
||||||
format++;
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
else if (*list->word->word == '+' && all_digits (list->word->word + 1))
|
|
||||||
{
|
|
||||||
w = list->word->word + 1;
|
|
||||||
index_flag = 1;
|
|
||||||
i = atoi (w);
|
|
||||||
/* dirs +0 prints the current working directory. */
|
|
||||||
if (i == 0)
|
|
||||||
desired_index = i;
|
|
||||||
else if (i == directory_list_offset)
|
|
||||||
{
|
|
||||||
desired_index = 0;
|
|
||||||
index_flag = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
desired_index = directory_list_offset - i;
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
else if (*list->word->word == '-' && all_digits (list->word->word + 1))
|
|
||||||
{
|
|
||||||
w = list->word->word + 1;
|
|
||||||
i = atoi (w);
|
|
||||||
index_flag = 2;
|
|
||||||
/* dirs -X where X is directory_list_offset prints the current
|
|
||||||
working directory. */
|
|
||||||
if (i == directory_list_offset)
|
|
||||||
{
|
|
||||||
index_flag = 1;
|
|
||||||
desired_index = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
desired_index = i;
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bad_option (list->word->word);
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index_flag && (desired_index < 0 || desired_index > directory_list_offset))
|
|
||||||
{
|
|
||||||
if (directory_list_offset == 0)
|
|
||||||
builtin_error ("directory stack empty");
|
|
||||||
else
|
|
||||||
builtin_error ("%s: bad directory stack index", w);
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The first directory printed is always the current working directory. */
|
|
||||||
if (!index_flag || (index_flag == 1 && desired_index == 0))
|
|
||||||
{
|
|
||||||
temp = get_working_directory ("dirs");
|
|
||||||
if (!temp)
|
|
||||||
temp = savestring ("<no directory>");
|
|
||||||
printf ("%s", format ? temp : polite_directory_format (temp));
|
|
||||||
free (temp);
|
|
||||||
if (index_flag)
|
|
||||||
{
|
|
||||||
putchar ('\n');
|
|
||||||
return EXECUTION_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DIRSTACK_ENTRY(i) \
|
|
||||||
format ? pushd_directory_list[i] \
|
|
||||||
: polite_directory_format (pushd_directory_list[i])
|
|
||||||
|
|
||||||
/* Now print the requested directory stack entries. */
|
|
||||||
if (index_flag)
|
|
||||||
printf ("%s", DIRSTACK_ENTRY (desired_index));
|
|
||||||
else
|
|
||||||
for (i = (directory_list_offset - 1); i > -1; i--)
|
|
||||||
printf (" %s", DIRSTACK_ENTRY (i));
|
|
||||||
|
|
||||||
putchar ('\n');
|
|
||||||
fflush (stdout);
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
|
||||||
#endif /* PUSHD_AND_POPD */
|
|
||||||
|
|
||||||
$BUILTIN popd
|
|
||||||
$FUNCTION popd_builtin
|
|
||||||
$DEPENDS_ON PUSHD_AND_POPD
|
|
||||||
$SHORT_DOC popd [+n | -n]
|
|
||||||
Removes entries from the directory stack. With no arguments,
|
|
||||||
removes the top directory from the stack, and cd's to the new
|
|
||||||
top directory.
|
|
||||||
|
|
||||||
+n removes the Nth entry counting from the left of the list
|
|
||||||
shown by `dirs', starting with zero. For example: `popd +0'
|
|
||||||
removes the first directory, `popd +1' the second.
|
|
||||||
|
|
||||||
-n removes the Nth entry counting from the right of the list
|
|
||||||
shown by `dirs', starting with zero. For example: `popd -0'
|
|
||||||
removes the last directory, `popd -1' the next to last.
|
|
||||||
|
|
||||||
You can see the directory stack with the `dirs' command.
|
|
||||||
$END
|
|
||||||
|
|
||||||
#if defined (PUSHD_AND_POPD)
|
|
||||||
/* Pop the directory stack, and then change to the new top of the stack.
|
|
||||||
If LIST is non-null it should consist of a word +N or -N, which says
|
|
||||||
what element to delete from the stack. The default is the top one. */
|
|
||||||
popd_builtin (list)
|
|
||||||
WORD_LIST *list;
|
|
||||||
{
|
|
||||||
register int i;
|
|
||||||
int which = 0;
|
|
||||||
char direction = '+';
|
|
||||||
|
|
||||||
if (list)
|
|
||||||
{
|
|
||||||
direction = *(list->word->word);
|
|
||||||
|
|
||||||
if ((direction != '+' && direction != '-') ||
|
|
||||||
(1 != sscanf (&((list->word->word)[1]), "%d", &which)))
|
|
||||||
{
|
|
||||||
builtin_error ("bad arg `%s'", list->word->word);
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (which > directory_list_offset || (!directory_list_offset && !which))
|
|
||||||
{
|
|
||||||
if (!directory_list_offset)
|
|
||||||
builtin_error ("Directory stack empty");
|
|
||||||
else
|
|
||||||
builtin_error ("Stack contains only %d directories",
|
|
||||||
directory_list_offset + 1);
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle case of no specification, or top of stack specification. */
|
|
||||||
if ((direction == '+' && which == 0) ||
|
|
||||||
(direction == '-' && which == directory_list_offset))
|
|
||||||
{
|
|
||||||
i = cd_to_string (pushd_directory_list[directory_list_offset - 1]);
|
|
||||||
if (i != EXECUTION_SUCCESS)
|
|
||||||
return (i);
|
|
||||||
free (pushd_directory_list[--directory_list_offset]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Since an offset other than the top directory was specified,
|
|
||||||
remove that directory from the list and shift the remainder
|
|
||||||
of the list into place. */
|
|
||||||
|
|
||||||
if (direction == '+')
|
|
||||||
i = directory_list_offset - which;
|
|
||||||
else
|
|
||||||
i = which;
|
|
||||||
|
|
||||||
free (pushd_directory_list[i]);
|
|
||||||
directory_list_offset--;
|
|
||||||
|
|
||||||
/* Shift the remainder of the list into place. */
|
|
||||||
for (; i < directory_list_offset; i++)
|
|
||||||
pushd_directory_list[i] = pushd_directory_list[i + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
dirs_builtin ((WORD_LIST *)NULL);
|
|
||||||
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
|
||||||
#endif /* PUSHD_AND_POPD */
|
|
||||||
|
|
||||||
/* Do the work of changing to the directory NEWDIR. Handle symbolic
|
/* Do the work of changing to the directory NEWDIR. Handle symbolic
|
||||||
link following, etc. */
|
link following, etc. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
change_to_directory (newdir)
|
change_to_directory (newdir, nolinks)
|
||||||
char *newdir;
|
char *newdir;
|
||||||
|
int nolinks;
|
||||||
{
|
{
|
||||||
char *t;
|
char *t;
|
||||||
|
|
||||||
if (!no_symbolic_links)
|
if (nolinks == 0)
|
||||||
{
|
{
|
||||||
int chdir_return = 0;
|
int chdir_return = 0;
|
||||||
char *tdir = (char *)NULL;
|
char *tdir = (char *)NULL;
|
||||||
|
|
||||||
if (!the_current_working_directory)
|
if (the_current_working_directory == 0)
|
||||||
{
|
{
|
||||||
t = get_working_directory ("cd_links");
|
t = get_working_directory ("cd_links");
|
||||||
FREE (t);
|
FREE (t);
|
||||||
@@ -625,7 +382,6 @@ change_to_directory (newdir)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
FREE (tdir);
|
FREE (tdir);
|
||||||
|
|
||||||
tdir = t;
|
tdir = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,23 +423,171 @@ change_to_directory (newdir)
|
|||||||
return (chdir_return);
|
return (chdir_return);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
return (chdir (newdir) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code for cd spelling correction. Original patch submitted by
|
||||||
|
Neil Russel (caret@c-side.com). */
|
||||||
|
|
||||||
|
static char *
|
||||||
|
cdspell (dirname)
|
||||||
|
char *dirname;
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
char *guess;
|
||||||
|
|
||||||
|
n = (strlen (dirname) * 3 + 1) / 2 + 1;
|
||||||
|
guess = xmalloc (n);
|
||||||
|
|
||||||
|
switch (spname (dirname, guess))
|
||||||
{
|
{
|
||||||
if (chdir (newdir) < 0)
|
case -1:
|
||||||
return (0);
|
default:
|
||||||
else
|
free (guess);
|
||||||
return (1);
|
return (char *)NULL;
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
return guess;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Switch to the directory in NAME. This uses the cd_builtin to do the work,
|
/*
|
||||||
so if the result is EXECUTION_FAILURE then an error message has already
|
* `spname' and its helpers are inspired by the code in "The UNIX
|
||||||
been printed. */
|
* Programming Environment, Kernighan & Pike, Prentice-Hall 1984",
|
||||||
|
* pages 209 - 213.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `spname' -- return a correctly spelled filename
|
||||||
|
*
|
||||||
|
* int spname(char * oldname, char * newname)
|
||||||
|
* Returns: -1 if no reasonable match found
|
||||||
|
* 0 if exact match found
|
||||||
|
* 1 if corrected
|
||||||
|
* Stores corrected name in `newname'.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
cd_to_string (name)
|
spname(oldname, newname)
|
||||||
char *name;
|
char *oldname;
|
||||||
|
char *newname;
|
||||||
{
|
{
|
||||||
WORD_LIST *tlist = make_word_list (make_word (name), NULL);
|
char *op, *np, *p;
|
||||||
int result = (cd_builtin (tlist));
|
char guess[PATH_MAX + 1], best[PATH_MAX + 1];
|
||||||
dispose_words (tlist);
|
|
||||||
return (result);
|
op = oldname;
|
||||||
|
np = newname;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
while (*op == '/') /* Skip slashes */
|
||||||
|
*np++ = *op++;
|
||||||
|
*np = '\0';
|
||||||
|
|
||||||
|
if (*op == '\0') /* Exact or corrected */
|
||||||
|
{
|
||||||
|
/* `.' is rarely the right thing. */
|
||||||
|
if (oldname[1] == '\0' && newname[1] == '\0' &&
|
||||||
|
oldname[0] != '.' && newname[0] == '.')
|
||||||
|
return -1;
|
||||||
|
return strcmp(oldname, newname) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy next component into guess */
|
||||||
|
for (p = guess; *op != '/' && *op != '\0'; op++)
|
||||||
|
if (p < guess + PATH_MAX)
|
||||||
|
*p++ = *op;
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
if (mindist(newname, guess, best) >= 3)
|
||||||
|
return -1; /* Hopeless */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add to end of newname
|
||||||
|
*/
|
||||||
|
for (p = best; *np = *p++; np++)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search directory for a guess
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mindist(dir, guess, best)
|
||||||
|
char *dir;
|
||||||
|
char *guess;
|
||||||
|
char *best;
|
||||||
|
{
|
||||||
|
DIR *fd;
|
||||||
|
struct dirent *dp;
|
||||||
|
int dist, x;
|
||||||
|
|
||||||
|
dist = 3; /* Worst distance */
|
||||||
|
if (*dir == '\0')
|
||||||
|
dir = ".";
|
||||||
|
|
||||||
|
if ((fd = opendir(dir)) == NULL)
|
||||||
|
return dist;
|
||||||
|
|
||||||
|
while ((dp = readdir(fd)) != NULL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Look for a better guess. If the new guess is as
|
||||||
|
* good as the current one, we take it. This way,
|
||||||
|
* any single character match will be a better match
|
||||||
|
* than ".".
|
||||||
|
*/
|
||||||
|
x = spdist(dp->d_name, guess);
|
||||||
|
if (x <= dist && x != 3)
|
||||||
|
{
|
||||||
|
strcpy(best, dp->d_name);
|
||||||
|
dist = x;
|
||||||
|
if (dist == 0) /* Exact match */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(void)closedir(fd);
|
||||||
|
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `spdist' -- return the "distance" between two names.
|
||||||
|
*
|
||||||
|
* int spname(char * oldname, char * newname)
|
||||||
|
* Returns: 0 if strings are identical
|
||||||
|
* 1 if two characters are transposed
|
||||||
|
* 2 if one character is wrong, added or deleted
|
||||||
|
* 3 otherwise
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
spdist(cur, new)
|
||||||
|
char *cur, *new;
|
||||||
|
{
|
||||||
|
while (*cur == *new)
|
||||||
|
{
|
||||||
|
if (*cur == '\0')
|
||||||
|
return 0; /* Exact match */
|
||||||
|
cur++;
|
||||||
|
new++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*cur)
|
||||||
|
{
|
||||||
|
if (*new)
|
||||||
|
{
|
||||||
|
if (cur[1] && new[1] && cur[0] == new[1] && cur[1] == new[0] && strcmp (cur + 2, new + 2) == 0)
|
||||||
|
return 1; /* Transposition */
|
||||||
|
|
||||||
|
if (strcmp (cur + 1, new + 1) == 0)
|
||||||
|
return 2; /* One character mismatch */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(&cur[1], &new[0]) == 0)
|
||||||
|
return 2; /* Extra character */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*new && strcmp(cur, new + 1) == 0)
|
||||||
|
return 2; /* Missing character */
|
||||||
|
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,32 @@ $SHORT_DOC :
|
|||||||
No effect; the command does nothing. A zero exit code is returned.
|
No effect; the command does nothing. A zero exit code is returned.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
/* Do nothing. This command is a no-op. */
|
$BUILTIN true
|
||||||
|
$DOCNAME true_builtin
|
||||||
|
$FUNCTION colon_builtin
|
||||||
|
$SHORT_DOC true
|
||||||
|
Return a successful result.
|
||||||
|
$END
|
||||||
|
|
||||||
|
$BUILTIN false
|
||||||
|
$DOCNAME false_builtin
|
||||||
|
$FUNCTION false_builtin
|
||||||
|
$SHORT_DOC false
|
||||||
|
Return an unsuccessful result.
|
||||||
|
$END
|
||||||
|
|
||||||
|
/* Return a successful result. */
|
||||||
int
|
int
|
||||||
colon_builtin (ignore)
|
colon_builtin (ignore)
|
||||||
char *ignore;
|
char *ignore;
|
||||||
{
|
{
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return an unsuccessful result. */
|
||||||
|
int
|
||||||
|
false_builtin (ignore)
|
||||||
|
char *ignore;
|
||||||
|
{
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ $PRODUCES command.c
|
|||||||
|
|
||||||
$BUILTIN command
|
$BUILTIN command
|
||||||
$FUNCTION command_builtin
|
$FUNCTION command_builtin
|
||||||
$SHORT_DOC command [-pVv] [command [arg ...]]
|
$SHORT_DOC command [-pVv] command [arg ...]
|
||||||
Runs COMMAND with ARGS ignoring shell functions. If you have a shell
|
Runs COMMAND with ARGS ignoring shell functions. If you have a shell
|
||||||
function called `ls', and you wish to call the command `ls', you can
|
function called `ls', and you wish to call the command `ls', you can
|
||||||
say "command ls". If the -p option is given, a default value is used
|
say "command ls". If the -p option is given, a default value is used
|
||||||
@@ -32,14 +32,19 @@ the -V or -v option is given, a string is printed describing COMMAND.
|
|||||||
The -V option produces a more verbose description.
|
The -V option produces a more verbose description.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#if defined (HAVE_STRING_H)
|
#include <config.h>
|
||||||
# include <string.h>
|
|
||||||
#else /* !HAVE_STRING_H */
|
#if defined (HAVE_UNISTD_H)
|
||||||
# include <strings.h>
|
# include <unistd.h>
|
||||||
#endif /* !HAVE_STRING_H */
|
#endif
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
#include "../execute_cmd.h"
|
||||||
|
#include "../flags.h"
|
||||||
#include "bashgetopt.h"
|
#include "bashgetopt.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
extern int subshell_environment;
|
extern int subshell_environment;
|
||||||
|
|
||||||
@@ -52,9 +57,11 @@ int
|
|||||||
command_builtin (list)
|
command_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int result, verbose = 0, use_standard_path = 0, opt;
|
int result, verbose, use_standard_path, opt;
|
||||||
char *old_path;
|
char *old_path, *standard_path;
|
||||||
|
COMMAND *command;
|
||||||
|
|
||||||
|
verbose = use_standard_path = 0;
|
||||||
reset_internal_getopt ();
|
reset_internal_getopt ();
|
||||||
while ((opt = internal_getopt (list, "pvV")) != -1)
|
while ((opt = internal_getopt (list, "pvV")) != -1)
|
||||||
{
|
{
|
||||||
@@ -69,63 +76,70 @@ command_builtin (list)
|
|||||||
case 'v':
|
case 'v':
|
||||||
verbose = 4;
|
verbose = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
report_bad_option ();
|
builtin_usage ();
|
||||||
builtin_error ("usage: command [-pvV] [command [arg...]]");
|
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list = loptend;
|
list = loptend;
|
||||||
|
|
||||||
if (!list)
|
if (list == 0)
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
int found, any_found = 0;
|
int found, any_found;
|
||||||
|
|
||||||
while (list)
|
for (any_found = 0; list; list = list->next)
|
||||||
{
|
{
|
||||||
|
|
||||||
found = describe_command (list->word->word, verbose, 0);
|
found = describe_command (list->word->word, verbose, 0);
|
||||||
|
|
||||||
if (!found)
|
if (found == 0)
|
||||||
builtin_error ("%s: not found", list->word->word);
|
builtin_error ("%s: not found", list->word->word);
|
||||||
|
|
||||||
any_found += found;
|
any_found += found;
|
||||||
list = list->next;
|
|
||||||
}
|
}
|
||||||
return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined (RESTRICTED_SHELL)
|
||||||
|
if (use_standard_path && restricted)
|
||||||
|
{
|
||||||
|
builtin_error ("restricted: cannot use -p");
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
begin_unwind_frame ("command_builtin");
|
begin_unwind_frame ("command_builtin");
|
||||||
|
|
||||||
/* We don't want this to be reparsed (consider command echo 'foo &'), so
|
/* We don't want this to be reparsed (consider command echo 'foo &'), so
|
||||||
just make a simple_command structure and call execute_command with it. */
|
just make a simple_command structure and call execute_command with it. */
|
||||||
{
|
|
||||||
COMMAND *command;
|
|
||||||
|
|
||||||
if (use_standard_path)
|
if (use_standard_path)
|
||||||
{
|
{
|
||||||
char *standard_path;
|
|
||||||
|
|
||||||
old_path = get_string_value ("PATH");
|
old_path = get_string_value ("PATH");
|
||||||
if (old_path)
|
if (old_path)
|
||||||
old_path = savestring (old_path);
|
old_path = savestring (old_path);
|
||||||
else
|
else
|
||||||
old_path = savestring ("");
|
{
|
||||||
|
old_path = xmalloc (1);
|
||||||
|
old_path[0] = '\0';
|
||||||
|
}
|
||||||
add_unwind_protect ((Function *)restore_path, old_path);
|
add_unwind_protect ((Function *)restore_path, old_path);
|
||||||
|
|
||||||
standard_path = get_standard_path ();
|
standard_path = get_standard_path ();
|
||||||
bind_variable ("PATH", standard_path);
|
bind_variable ("PATH", standard_path ? standard_path : "");
|
||||||
free (standard_path);
|
FREE (standard_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
command = make_bare_simple_command ();
|
command = make_bare_simple_command ();
|
||||||
command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
|
command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
|
||||||
command->value.Simple->redirects = (REDIRECT *)NULL;
|
command->value.Simple->redirects = (REDIRECT *)NULL;
|
||||||
command->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
|
command->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
|
||||||
command->value.Simple->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
|
command->value.Simple->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
|
||||||
|
#if 0
|
||||||
|
/* This breaks for things like ( cd /tmp ; command z ababa ; echo next )
|
||||||
|
or $(command echo a ; command echo b;) or even
|
||||||
|
{ command echo a; command echo b; } & */
|
||||||
/* If we're in a subshell, see if we can get away without forking
|
/* If we're in a subshell, see if we can get away without forking
|
||||||
again, since we've already forked to run this builtin. */
|
again, since we've already forked to run this builtin. */
|
||||||
if (subshell_environment)
|
if (subshell_environment)
|
||||||
@@ -133,9 +147,9 @@ command_builtin (list)
|
|||||||
command->flags |= CMD_NO_FORK;
|
command->flags |= CMD_NO_FORK;
|
||||||
command->value.Simple->flags |= CMD_NO_FORK;
|
command->value.Simple->flags |= CMD_NO_FORK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
add_unwind_protect ((char *)dispose_command, command);
|
add_unwind_protect ((char *)dispose_command, command);
|
||||||
result = execute_command (command);
|
result = execute_command (command);
|
||||||
}
|
|
||||||
|
|
||||||
run_unwind_frame ("command_builtin");
|
run_unwind_frame ("command_builtin");
|
||||||
|
|
||||||
@@ -158,7 +172,7 @@ restore_path (var)
|
|||||||
static char *
|
static char *
|
||||||
get_standard_path ()
|
get_standard_path ()
|
||||||
{
|
{
|
||||||
#if defined (_CS_PATH) && !defined (hpux_7) && !defined (NetBSD)
|
#if defined (_CS_PATH) && defined (HAVE_CONFSTR)
|
||||||
char *p;
|
char *p;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
@@ -167,11 +181,11 @@ get_standard_path ()
|
|||||||
*p = '\0';
|
*p = '\0';
|
||||||
confstr (_CS_PATH, p, len);
|
confstr (_CS_PATH, p, len);
|
||||||
return (p);
|
return (p);
|
||||||
#else /* !_CSPATH || hpux_7 || NetBSD */
|
#else /* !_CSPATH || !HAVE_CONFSTR */
|
||||||
# if defined (CS_PATH)
|
# if defined (CS_PATH)
|
||||||
return (savestring (CS_PATH));
|
return (savestring (CS_PATH));
|
||||||
# else
|
# else
|
||||||
return (savestring (STANDARD_UTILS_PATH));
|
return (savestring (STANDARD_UTILS_PATH));
|
||||||
# endif /* !CS_PATH */
|
# endif /* !CS_PATH */
|
||||||
#endif /* !_CS_PATH || hpux_7 */
|
#endif /* !_CS_PATH || !HAVE_CONFSTR */
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -21,23 +21,23 @@
|
|||||||
#if !defined (__COMMON_H)
|
#if !defined (__COMMON_H)
|
||||||
# define __COMMON_H
|
# define __COMMON_H
|
||||||
|
|
||||||
|
#include "../stdc.h"
|
||||||
|
|
||||||
#define ISOPTION(s, c) (s[0] == '-' && !s[2] && s[1] == c)
|
#define ISOPTION(s, c) (s[0] == '-' && !s[2] && s[1] == c)
|
||||||
|
|
||||||
extern void builtin_error ();
|
extern void builtin_error __P((const char *, ...));
|
||||||
|
extern void builtin_usage ();
|
||||||
extern void bad_option ();
|
extern void bad_option ();
|
||||||
|
|
||||||
|
extern char **make_builtin_argv ();
|
||||||
|
|
||||||
extern int get_numeric_arg ();
|
extern int get_numeric_arg ();
|
||||||
|
|
||||||
extern void remember_args ();
|
extern void remember_args ();
|
||||||
|
|
||||||
extern void no_args ();
|
extern void no_args ();
|
||||||
|
extern int no_options ();
|
||||||
|
|
||||||
extern int read_octal ();
|
extern int read_octal ();
|
||||||
|
|
||||||
extern char *find_hashed_filename ();
|
|
||||||
extern void remove_hashed_filename ();
|
|
||||||
extern void remember_filename ();
|
|
||||||
|
|
||||||
extern void push_context (), pop_context ();
|
extern void push_context (), pop_context ();
|
||||||
extern void push_dollar_vars (), pop_dollar_vars ();
|
extern void push_dollar_vars (), pop_dollar_vars ();
|
||||||
extern void dispose_saved_dollar_vars ();
|
extern void dispose_saved_dollar_vars ();
|
||||||
@@ -53,17 +53,55 @@ extern void set_working_directory ();
|
|||||||
extern int get_job_spec ();
|
extern int get_job_spec ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int parse_and_execute ();
|
extern int display_signal_list ();
|
||||||
extern void parse_and_execute_cleanup ();
|
|
||||||
|
|
||||||
extern void initialize_shell_builtins ();
|
|
||||||
|
|
||||||
/* It's OK to declare a function as returning a Function * without
|
/* It's OK to declare a function as returning a Function * without
|
||||||
providing a definition of what a `Function' is. */
|
providing a definition of what a `Function' is. */
|
||||||
|
extern struct builtin *builtin_address_internal ();
|
||||||
extern Function *find_shell_builtin ();
|
extern Function *find_shell_builtin ();
|
||||||
extern Function *builtin_address ();
|
extern Function *builtin_address ();
|
||||||
|
extern Function *find_special_builtin ();
|
||||||
|
|
||||||
|
extern void initialize_shell_builtins ();
|
||||||
|
|
||||||
extern char *single_quote ();
|
extern char *single_quote ();
|
||||||
extern char *double_quote ();
|
extern char *double_quote ();
|
||||||
|
extern char *backslash_quote ();
|
||||||
|
extern int contains_shell_metas ();
|
||||||
|
|
||||||
|
/* Functions from hash.def */
|
||||||
|
extern void initialize_filename_hashing ();
|
||||||
|
extern void flush_hashed_filenames ();
|
||||||
|
extern char *find_hashed_filename ();
|
||||||
|
extern void remove_hashed_filename ();
|
||||||
|
extern void remember_filename ();
|
||||||
|
|
||||||
|
/* Functions from set.def */
|
||||||
|
extern void initialize_shell_options ();
|
||||||
|
extern void list_minus_o_opts ();
|
||||||
|
extern int set_minus_o_option ();
|
||||||
|
extern int minus_o_option_value ();
|
||||||
|
|
||||||
|
/* Functions from type.def */
|
||||||
|
extern int describe_command ();
|
||||||
|
|
||||||
|
/* Functions from setattr.def */
|
||||||
|
extern int set_or_show_attributes ();
|
||||||
|
extern int show_var_attributes ();
|
||||||
|
extern int show_name_attributes ();
|
||||||
|
extern void set_var_attribute ();
|
||||||
|
|
||||||
|
/* Functions from pushd.def */
|
||||||
|
extern char *get_dirstack_element ();
|
||||||
|
extern void set_dirstack_element ();
|
||||||
|
extern WORD_LIST *get_directory_stack ();
|
||||||
|
|
||||||
|
/* Functions from evalstring.c */
|
||||||
|
extern int parse_and_execute ();
|
||||||
|
extern void parse_and_execute_cleanup ();
|
||||||
|
|
||||||
|
/* Functions from evalfile.c */
|
||||||
|
extern int maybe_execute_file __P((char *, int));
|
||||||
|
extern int source_file __P((char *));
|
||||||
|
|
||||||
#endif /* !__COMMON_H */
|
#endif /* !__COMMON_H */
|
||||||
|
|||||||
@@ -23,39 +23,50 @@ $PRODUCES declare.c
|
|||||||
|
|
||||||
$BUILTIN declare
|
$BUILTIN declare
|
||||||
$FUNCTION declare_builtin
|
$FUNCTION declare_builtin
|
||||||
$SHORT_DOC declare [-[frxi]] name[=value] ...
|
$SHORT_DOC declare [-afFrxi] [-p] name[=value] ...
|
||||||
Declare variables and/or give them attributes. If no NAMEs are
|
Declare variables and/or give them attributes. If no NAMEs are
|
||||||
given, then display the values of variables instead.
|
given, then display the values of variables instead. The -p option
|
||||||
|
will display the attributes and values of each NAME.
|
||||||
|
|
||||||
The flags are:
|
The flags are:
|
||||||
|
|
||||||
-f to select from among function names only,
|
-a to make NAMEs arrays (if supported)
|
||||||
-r to make NAMEs readonly,
|
-f to select from among function names only
|
||||||
-x to make NAMEs export,
|
-F to display function names without definitions
|
||||||
-i to make NAMEs have the `integer' attribute set.
|
-r to make NAMEs readonly
|
||||||
|
-x to make NAMEs export
|
||||||
|
-i to make NAMEs have the `integer' attribute set
|
||||||
|
|
||||||
Variables with the integer attribute have arithmetic evaluation (see
|
Variables with the integer attribute have arithmetic evaluation (see
|
||||||
`let') done when the variable is assigned to.
|
`let') done when the variable is assigned to.
|
||||||
|
|
||||||
|
When displaying values of variables, -f displays a function's name
|
||||||
|
and definition. The -F option restricts the display to function
|
||||||
|
name only.
|
||||||
|
|
||||||
Using `+' instead of `-' turns off the given attribute instead. When
|
Using `+' instead of `-' turns off the given attribute instead. When
|
||||||
used in a function, makes NAMEs local, as with the `local' command.
|
used in a function, makes NAMEs local, as with the `local' command.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
$BUILTIN typeset
|
$BUILTIN typeset
|
||||||
$FUNCTION declare_builtin
|
$FUNCTION declare_builtin
|
||||||
$SHORT_DOC typeset [-[frxi]] name[=value] ...
|
$SHORT_DOC typeset [-afFrxi] [-p] name[=value] ...
|
||||||
Obsolete. See `declare'.
|
Obsolete. See `declare'.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if defined (HAVE_STRING_H)
|
#include "../bashansi.h"
|
||||||
# include <string.h>
|
|
||||||
#else /* !HAVE_STRING_H */
|
|
||||||
# include <strings.h>
|
|
||||||
#endif /* !HAVE_STRING_H */
|
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "builtext.h"
|
||||||
|
|
||||||
extern int variable_context, array_needs_making;
|
extern int variable_context, array_needs_making;
|
||||||
|
|
||||||
@@ -84,7 +95,7 @@ local_builtin (list)
|
|||||||
return (declare_internal (list, 1));
|
return (declare_internal (list, 1));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
builtin_error ("Can only be used in a function");
|
builtin_error ("can only be used in a function");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,14 +106,14 @@ declare_internal (list, local_var)
|
|||||||
register WORD_LIST *list;
|
register WORD_LIST *list;
|
||||||
int local_var;
|
int local_var;
|
||||||
{
|
{
|
||||||
int flags_on = 0, flags_off = 0;
|
int flags_on, flags_off, *flags, any_failed, assign_error, pflag, nodefs;
|
||||||
int any_failed = 0;
|
char *t;
|
||||||
|
SHELL_VAR *var;
|
||||||
|
|
||||||
|
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0;
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
register char *t = list->word->word;
|
t = list->word->word;
|
||||||
int *flags;
|
|
||||||
|
|
||||||
if (t[0] == '-' && t[1] == '-' && t[2] == '\0')
|
if (t[0] == '-' && t[1] == '-' && t[2] == '\0')
|
||||||
{
|
{
|
||||||
list = list->next;
|
list = list->next;
|
||||||
@@ -112,16 +123,18 @@ declare_internal (list, local_var)
|
|||||||
if (*t != '+' && *t != '-')
|
if (*t != '+' && *t != '-')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (*t == '+')
|
flags = (*t++ == '+') ? &flags_off : &flags_on;
|
||||||
flags = &flags_off;
|
|
||||||
else
|
|
||||||
flags = &flags_on;
|
|
||||||
|
|
||||||
t++;
|
|
||||||
|
|
||||||
while (*t)
|
while (*t)
|
||||||
{
|
{
|
||||||
if (*t == 'f')
|
if (*t == 'p' && local_var == 0)
|
||||||
|
pflag++, t++;
|
||||||
|
else if (*t == 'F')
|
||||||
|
{
|
||||||
|
nodefs++;
|
||||||
|
*flags |= att_function; t++;
|
||||||
|
}
|
||||||
|
else if (*t == 'f')
|
||||||
*flags |= att_function, t++;
|
*flags |= att_function, t++;
|
||||||
else if (*t == 'x')
|
else if (*t == 'x')
|
||||||
*flags |= att_exported, t++, array_needs_making = 1;
|
*flags |= att_exported, t++, array_needs_making = 1;
|
||||||
@@ -129,9 +142,14 @@ declare_internal (list, local_var)
|
|||||||
*flags |= att_readonly, t++;
|
*flags |= att_readonly, t++;
|
||||||
else if (*t == 'i')
|
else if (*t == 'i')
|
||||||
*flags |= att_integer, t++;
|
*flags |= att_integer, t++;
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
else if (*t == 'a')
|
||||||
|
*flags |= att_array, t++;
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
builtin_error ("unknown option: `-%c'", *t);
|
builtin_error ("unknown option: `-%c'", *t);
|
||||||
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,7 +159,7 @@ declare_internal (list, local_var)
|
|||||||
|
|
||||||
/* If there are no more arguments left, then we just want to show
|
/* If there are no more arguments left, then we just want to show
|
||||||
some variables. */
|
some variables. */
|
||||||
if (!list)
|
if (list == 0) /* declare -[afFirx] */
|
||||||
{
|
{
|
||||||
/* Show local variables defined at this context level if this is
|
/* Show local variables defined at this context level if this is
|
||||||
the `local' builtin. */
|
the `local' builtin. */
|
||||||
@@ -162,25 +180,45 @@ declare_internal (list, local_var)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!flags_on)
|
if (flags_on == 0)
|
||||||
set_builtin ((WORD_LIST *)NULL);
|
set_builtin ((WORD_LIST *)NULL);
|
||||||
else
|
else
|
||||||
set_or_show_attributes ((WORD_LIST *)NULL, flags_on);
|
set_or_show_attributes ((WORD_LIST *)NULL, flags_on, nodefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pflag) /* declare -p [-afFirx] name [name...] */
|
||||||
|
{
|
||||||
|
for (any_failed = 0; list; list = list->next)
|
||||||
|
{
|
||||||
|
pflag = show_name_attributes (list->word->word, nodefs);
|
||||||
|
if (pflag)
|
||||||
|
{
|
||||||
|
builtin_error ("%s: not found", list->word->word);
|
||||||
|
any_failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
#define NEXT_VARIABLE() free (name); list = list->next; continue
|
#define NEXT_VARIABLE() free (name); list = list->next; continue
|
||||||
|
|
||||||
/* There are arguments left, so we are making variables. */
|
/* There are arguments left, so we are making variables. */
|
||||||
while (list)
|
while (list) /* declare [-afFirx] name [name ...] */
|
||||||
{
|
{
|
||||||
char *value, *name = savestring (list->word->word);
|
char *value, *name;
|
||||||
int offset = assignment (name);
|
int offset;
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
int making_array_special, assigning_array_special;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (offset)
|
name = savestring (list->word->word);
|
||||||
|
offset = assignment (name);
|
||||||
|
|
||||||
|
if (offset) /* declare [-afFirx] name=value */
|
||||||
{
|
{
|
||||||
name[offset] = '\0';
|
name[offset] = '\0';
|
||||||
value = name + offset + 1;
|
value = name + offset + 1;
|
||||||
@@ -188,10 +226,21 @@ declare_internal (list, local_var)
|
|||||||
else
|
else
|
||||||
value = "";
|
value = "";
|
||||||
|
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
assigning_array_special = 0;
|
||||||
|
if (t = strchr (name, '['))
|
||||||
|
{
|
||||||
|
*t = '\0';
|
||||||
|
making_array_special = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
making_array_special = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (legal_identifier (name) == 0)
|
if (legal_identifier (name) == 0)
|
||||||
{
|
{
|
||||||
builtin_error ("%s: not a legal variable name", name);
|
builtin_error ("`%s': not a valid identifier", name);
|
||||||
any_failed++;
|
assign_error++;
|
||||||
NEXT_VARIABLE ();
|
NEXT_VARIABLE ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +249,14 @@ declare_internal (list, local_var)
|
|||||||
not global ones. */
|
not global ones. */
|
||||||
|
|
||||||
if (variable_context)
|
if (variable_context)
|
||||||
|
{
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
if ((flags_on & att_array) || making_array_special)
|
||||||
|
make_local_array_variable (name);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
make_local_variable (name);
|
make_local_variable (name);
|
||||||
|
}
|
||||||
|
|
||||||
/* If we are declaring a function, then complain about it in some way.
|
/* If we are declaring a function, then complain about it in some way.
|
||||||
We don't let people make functions by saying `typeset -f foo=bar'. */
|
We don't let people make functions by saying `typeset -f foo=bar'. */
|
||||||
@@ -210,36 +266,35 @@ declare_internal (list, local_var)
|
|||||||
|
|
||||||
if (flags_on & att_function)
|
if (flags_on & att_function)
|
||||||
{
|
{
|
||||||
if (offset)
|
if (offset) /* declare -f [-rix] foo=bar */
|
||||||
{
|
{
|
||||||
builtin_error ("Can't use `-f' to make functions");
|
builtin_error ("Can't use `-f' to make functions");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
else
|
else /* declare -f [-rx] name [name...] */
|
||||||
{
|
{
|
||||||
SHELL_VAR *find_function (), *funvar;
|
var = find_function (name);
|
||||||
|
|
||||||
funvar = find_function (name);
|
if (var)
|
||||||
|
|
||||||
if (funvar)
|
|
||||||
{
|
{
|
||||||
if (readonly_p (funvar) && (flags_off & att_readonly))
|
if (readonly_p (var) && (flags_off & att_readonly))
|
||||||
{
|
{
|
||||||
builtin_error ("%s: readonly function", name);
|
builtin_error ("%s: readonly function", name);
|
||||||
any_failed++;
|
any_failed++;
|
||||||
NEXT_VARIABLE ();
|
NEXT_VARIABLE ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* declare -[Ff] name [name...] */
|
||||||
if (flags_on == att_function && flags_off == 0)
|
if (flags_on == att_function && flags_off == 0)
|
||||||
{
|
{
|
||||||
char *result = named_function_string
|
t = nodefs ? var->name
|
||||||
(name, (COMMAND *)function_cell (funvar), 1);
|
: named_function_string (name, function_cell (var), 1);
|
||||||
printf ("%s\n", result);
|
printf ("%s\n", t);
|
||||||
}
|
}
|
||||||
else
|
else /* declare -[fF] -[rx] name [name...] */
|
||||||
{
|
{
|
||||||
funvar->attributes |= flags_on;
|
var->attributes |= flags_on;
|
||||||
funvar->attributes &= ~flags_off;
|
var->attributes &= ~flags_off;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -247,15 +302,21 @@ declare_internal (list, local_var)
|
|||||||
NEXT_VARIABLE ();
|
NEXT_VARIABLE ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else /* declare -[airx] name [name...] */
|
||||||
{
|
{
|
||||||
SHELL_VAR *var;
|
|
||||||
|
|
||||||
var = find_variable (name);
|
var = find_variable (name);
|
||||||
|
|
||||||
if (!var)
|
if (var == 0)
|
||||||
|
{
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
if ((flags_on & att_array) || making_array_special)
|
||||||
|
var = make_new_array_variable (name);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
var = bind_variable (name, "");
|
var = bind_variable (name, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cannot use declare +r to turn off readonly attribute. */
|
||||||
if (readonly_p (var) && (flags_off & att_readonly))
|
if (readonly_p (var) && (flags_off & att_readonly))
|
||||||
{
|
{
|
||||||
builtin_error ("%s: readonly variable", name);
|
builtin_error ("%s: readonly variable", name);
|
||||||
@@ -263,22 +324,55 @@ declare_internal (list, local_var)
|
|||||||
NEXT_VARIABLE ();
|
NEXT_VARIABLE ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cannot use declare to assign value to readonly variable. */
|
||||||
|
if (readonly_p (var) && offset)
|
||||||
|
{
|
||||||
|
builtin_error ("%s: readonly variable", name);
|
||||||
|
assign_error++;
|
||||||
|
NEXT_VARIABLE ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
/* declare -a name=value does not work; declare name=value when
|
||||||
|
name is already an array does not work. */
|
||||||
|
if ((making_array_special || (flags_on & att_array) || array_p (var)) && offset)
|
||||||
|
{
|
||||||
|
if (value[0] == '(' && strchr (value, ')'))
|
||||||
|
assigning_array_special = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builtin_error ("%s: cannot assign to array variables in this way", name);
|
||||||
|
assign_error++;
|
||||||
|
NEXT_VARIABLE ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cannot use declare +a name to remove an array variable. */
|
||||||
|
if ((flags_off & att_array) && array_p (var))
|
||||||
|
{
|
||||||
|
builtin_error ("%s: cannot destroy array variables in this way", name);
|
||||||
|
any_failed++;
|
||||||
|
NEXT_VARIABLE ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* declare -a name makes name an array variable. */
|
||||||
|
if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0)
|
||||||
|
var = convert_var_to_array (var);
|
||||||
|
#endif /* ARRAY_VARS */
|
||||||
|
|
||||||
var->attributes |= flags_on;
|
var->attributes |= flags_on;
|
||||||
var->attributes &= ~flags_off;
|
var->attributes &= ~flags_off;
|
||||||
|
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
if (offset && assigning_array_special)
|
||||||
|
assign_array_var_from_string (var, value);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if (offset)
|
if (offset)
|
||||||
{
|
{
|
||||||
free (var->value);
|
t = make_variable_value (var, value);
|
||||||
if (integer_p (var))
|
FREE (var->value);
|
||||||
{
|
var->value = t;
|
||||||
long val, evalexp ();
|
|
||||||
char *itos ();
|
|
||||||
|
|
||||||
val = evalexp (value);
|
|
||||||
var->value = itos ((int)val);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
var->value = savestring (value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,5 +380,8 @@ declare_internal (list, local_var)
|
|||||||
|
|
||||||
NEXT_VARIABLE ();
|
NEXT_VARIABLE ();
|
||||||
}
|
}
|
||||||
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
|
||||||
|
return (assign_error ? EX_BADASSIGN
|
||||||
|
: ((any_failed == 0) ? EXECUTION_SUCCESS
|
||||||
|
: EXECUTION_FAILURE));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ with Bash; see the file COPYING. If not, write to the Free Software
|
|||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
$PRODUCES echo.c
|
$PRODUCES echo.c
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
|
||||||
@@ -33,6 +39,7 @@ following backslash-escaped characters is turned on:
|
|||||||
\a alert (bell)
|
\a alert (bell)
|
||||||
\b backspace
|
\b backspace
|
||||||
\c suppress trailing newline
|
\c suppress trailing newline
|
||||||
|
\E escape character
|
||||||
\f form feed
|
\f form feed
|
||||||
\n new line
|
\n new line
|
||||||
\r carriage return
|
\r carriage return
|
||||||
@@ -60,109 +67,91 @@ $END
|
|||||||
|
|
||||||
/* Print the words in LIST to standard output. If the first word is
|
/* Print the words in LIST to standard output. If the first word is
|
||||||
`-n', then don't print a trailing newline. We also support the
|
`-n', then don't print a trailing newline. We also support the
|
||||||
echo syntax from Version 9 unix systems. */
|
echo syntax from Version 9 Unix systems. */
|
||||||
|
int
|
||||||
echo_builtin (list)
|
echo_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int display_return = 1, do_v9 = 0;
|
int display_return, do_v9, i;
|
||||||
|
char *temp;
|
||||||
|
|
||||||
#if defined (DEFAULT_ECHO_TO_USG)
|
#if defined (DEFAULT_ECHO_TO_USG)
|
||||||
/* System V machines already have a /bin/sh with a v9 behaviour. We
|
/* System V machines already have a /bin/sh with a v9 behaviour. We
|
||||||
give Bash the identical behaviour for these machines so that the
|
give Bash the identical behaviour for these machines so that the
|
||||||
existing system shells won't barf. */
|
existing system shells won't barf. */
|
||||||
do_v9 = 1;
|
do_v9 = 1;
|
||||||
|
#else
|
||||||
|
do_v9 = 0;
|
||||||
#endif /* DEFAULT_ECHO_TO_USG */
|
#endif /* DEFAULT_ECHO_TO_USG */
|
||||||
|
|
||||||
while (list && list->word->word[0] == '-')
|
display_return = 1;
|
||||||
{
|
|
||||||
register char *temp;
|
|
||||||
register int i;
|
|
||||||
|
|
||||||
|
for (; list && (temp = list->word->word) && *temp == '-'; list = list->next)
|
||||||
|
{
|
||||||
/* If it appears that we are handling options, then make sure that
|
/* If it appears that we are handling options, then make sure that
|
||||||
all of the options specified are actually valid. Otherwise, the
|
all of the options specified are actually valid. Otherwise, the
|
||||||
string should just be echoed. */
|
string should just be echoed. */
|
||||||
temp = &(list->word->word[1]);
|
temp++;
|
||||||
|
|
||||||
for (i = 0; temp[i]; i++)
|
for (i = 0; temp[i]; i++)
|
||||||
{
|
{
|
||||||
if (strchr (VALID_ECHO_OPTIONS, temp[i]) == 0)
|
if (strchr (VALID_ECHO_OPTIONS, temp[i]) == 0)
|
||||||
goto just_echo;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*temp)
|
/* echo - and echo -<nonopt> both mean to just echo the arguments. */
|
||||||
goto just_echo;
|
if (*temp == 0 || temp[i])
|
||||||
|
break;
|
||||||
|
|
||||||
/* All of the options in TEMP are valid options to ECHO.
|
/* All of the options in TEMP are valid options to ECHO.
|
||||||
Handle them. */
|
Handle them. */
|
||||||
while (*temp)
|
while (i = *temp++)
|
||||||
{
|
{
|
||||||
if (*temp == 'n')
|
switch (i)
|
||||||
|
{
|
||||||
|
case 'n':
|
||||||
display_return = 0;
|
display_return = 0;
|
||||||
|
break;
|
||||||
#if defined (V9_ECHO)
|
#if defined (V9_ECHO)
|
||||||
else if (*temp == 'e')
|
case 'e':
|
||||||
do_v9 = 1;
|
do_v9 = 1;
|
||||||
else if (*temp == 'E')
|
break;
|
||||||
|
case 'E':
|
||||||
do_v9 = 0;
|
do_v9 = 0;
|
||||||
|
break;
|
||||||
#endif /* V9_ECHO */
|
#endif /* V9_ECHO */
|
||||||
else
|
default:
|
||||||
goto just_echo;
|
goto just_echo; /* XXX */
|
||||||
|
}
|
||||||
temp++;
|
|
||||||
}
|
}
|
||||||
list = list->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
just_echo:
|
just_echo:
|
||||||
|
|
||||||
if (list)
|
|
||||||
{
|
|
||||||
#if defined (V9_ECHO)
|
|
||||||
if (do_v9)
|
|
||||||
{
|
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
register char *s = list->word->word;
|
i = 0;
|
||||||
register int c;
|
temp = do_v9 ? ansicstr (list->word->word, STRLEN (list->word->word), &i)
|
||||||
|
: list->word->word;
|
||||||
while (c = *s++)
|
if (temp)
|
||||||
{
|
{
|
||||||
if (c == '\\' && *s)
|
printf ("%s", temp);
|
||||||
{
|
fflush (stdout); /* Fix for bug in SunOS 5.5 printf(3) */
|
||||||
switch (c = *s++)
|
|
||||||
{
|
|
||||||
case 'a': c = '\007'; break;
|
|
||||||
case 'b': c = '\b'; break;
|
|
||||||
case 'c': display_return = 0; continue;
|
|
||||||
case 'f': c = '\f'; break;
|
|
||||||
case 'n': c = '\n'; break;
|
|
||||||
case 'r': c = '\r'; break;
|
|
||||||
case 't': c = '\t'; break;
|
|
||||||
case 'v': c = (int) 0x0B; break;
|
|
||||||
case '0': case '1': case '2': case '3':
|
|
||||||
case '4': case '5': case '6': case '7':
|
|
||||||
c -= '0';
|
|
||||||
if (*s >= '0' && *s <= '7')
|
|
||||||
c = c * 8 + (*s++ - '0');
|
|
||||||
if (*s >= '0' && *s <= '7')
|
|
||||||
c = c * 8 + (*s++ - '0');
|
|
||||||
break;
|
|
||||||
case '\\': break;
|
|
||||||
default: putchar ('\\'); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
putchar(c);
|
|
||||||
}
|
}
|
||||||
|
if (do_v9 && temp)
|
||||||
|
free (temp);
|
||||||
list = list->next;
|
list = list->next;
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
display_return = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (list)
|
if (list)
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif /* V9_ECHO */
|
|
||||||
print_word_list (list, " ");
|
|
||||||
}
|
|
||||||
if (display_return)
|
if (display_return)
|
||||||
printf ("\n");
|
putchar ('\n');
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,20 +23,54 @@ $PRODUCES enable.c
|
|||||||
|
|
||||||
$BUILTIN enable
|
$BUILTIN enable
|
||||||
$FUNCTION enable_builtin
|
$FUNCTION enable_builtin
|
||||||
$SHORT_DOC enable [-n] [name ...]
|
$SHORT_DOC enable [-pnds] [-a] [-f filename] [name ...]
|
||||||
Enable and disable builtin shell commands. This allows
|
Enable and disable builtin shell commands. This allows
|
||||||
you to use a disk command which has the same name as a shell
|
you to use a disk command which has the same name as a shell
|
||||||
builtin. If -n is used, the NAMEs become disabled. Otherwise
|
builtin. If -n is used, the NAMEs become disabled; otherwise
|
||||||
NAMEs are enabled. For example, to use the `test' found on your
|
NAMEs are enabled. For example, to use the `test' found on your
|
||||||
path instead of the shell builtin version, you type `enable -n test'.
|
path instead of the shell builtin version, type `enable -n test'.
|
||||||
|
On systems supporting dynamic loading, the -f option may be used
|
||||||
|
to load new builtins from the shared object FILENAME. The -d
|
||||||
|
option will delete a builtin previously loaded with -f. If no
|
||||||
|
non-option names are given, or the -p option is supplied, a list
|
||||||
|
of builtins is printed. The -a option means to print every builtin
|
||||||
|
with an indication of whether or not it is enabled. The -s option
|
||||||
|
restricts the output to the Posix.2 `special' builtins. The -n
|
||||||
|
option displays a list of all disabled builtins.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../bashansi.h"
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../builtins.h"
|
#include "../builtins.h"
|
||||||
|
#include "../flags.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
|
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
|
||||||
|
static int dyn_load_builtin ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (HAVE_DLCLOSE)
|
||||||
|
static int dyn_unload_builtin ();
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ENABLED 1
|
#define ENABLED 1
|
||||||
#define DISABLED 2
|
#define DISABLED 2
|
||||||
|
#define SPECIAL 4
|
||||||
|
|
||||||
|
#define AFLAG 0x01
|
||||||
|
#define DFLAG 0x02
|
||||||
|
#define FFLAG 0x04
|
||||||
|
#define NFLAG 0x08
|
||||||
|
#define PFLAG 0x10
|
||||||
|
#define SFLAG 0x20
|
||||||
|
|
||||||
static int enable_shell_command ();
|
static int enable_shell_command ();
|
||||||
static void list_some_builtins ();
|
static void list_some_builtins ();
|
||||||
@@ -44,61 +78,117 @@ static void list_some_builtins ();
|
|||||||
/* Enable/disable shell commands present in LIST. If list is not specified,
|
/* Enable/disable shell commands present in LIST. If list is not specified,
|
||||||
then print out a list of shell commands showing which are enabled and
|
then print out a list of shell commands showing which are enabled and
|
||||||
which are disabled. */
|
which are disabled. */
|
||||||
|
int
|
||||||
enable_builtin (list)
|
enable_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int result = 0, any_failed = 0;
|
int result, flags;
|
||||||
int disable_p, all_p;
|
int opt, filter;
|
||||||
|
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
|
||||||
|
char *filename;
|
||||||
|
#endif
|
||||||
|
|
||||||
disable_p = all_p = 0;
|
result = EXECUTION_SUCCESS;
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
while (list && list->word->word && list->word->word[0] == '-')
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "adnpsf:")) != -1)
|
||||||
{
|
{
|
||||||
char *arg = list->word->word;
|
switch (opt)
|
||||||
|
{
|
||||||
list = list->next;
|
case 'a':
|
||||||
|
flags |= AFLAG;
|
||||||
if (ISOPTION (arg, 'n'))
|
|
||||||
disable_p = 1;
|
|
||||||
else if (arg[1] == 'a' && (arg[2] == 0 || strcmp (arg + 2, "ll") == 0))
|
|
||||||
all_p = 1;
|
|
||||||
else if (ISOPTION (arg, '-'))
|
|
||||||
break;
|
break;
|
||||||
else
|
case 'n':
|
||||||
|
flags |= NFLAG;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
flags |= PFLAG;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
flags |= SFLAG;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
|
||||||
|
flags |= FFLAG;
|
||||||
|
filename = list_optarg;
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
builtin_error ("dynamic loading not available");
|
||||||
|
return (EX_USAGE);
|
||||||
|
#endif
|
||||||
|
#if defined (HAVE_DLCLOSE)
|
||||||
|
case 'd':
|
||||||
|
flags |= DFLAG;
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
builtin_error ("dynamic loading not available");
|
||||||
|
return (EX_USAGE);
|
||||||
|
#endif /* HAVE_DLCLOSE */
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
|
return (EX_USAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
|
#if defined (RESTRICTED_SHELL)
|
||||||
|
/* Restricted shells cannot load new builtins. */
|
||||||
|
if (restricted && (flags & (FFLAG|DFLAG)))
|
||||||
{
|
{
|
||||||
bad_option (arg);
|
builtin_error ("restricted");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
if (!list)
|
if (list == 0 || (flags & PFLAG))
|
||||||
{
|
{
|
||||||
int filter;
|
filter = (flags & AFLAG) ? (ENABLED | DISABLED)
|
||||||
|
: (flags & NFLAG) ? DISABLED : ENABLED;
|
||||||
|
|
||||||
if (all_p)
|
if (flags & SFLAG)
|
||||||
filter = ENABLED | DISABLED;
|
filter |= SPECIAL;
|
||||||
else if (disable_p)
|
|
||||||
filter = DISABLED;
|
|
||||||
else
|
|
||||||
filter = ENABLED;
|
|
||||||
|
|
||||||
list_some_builtins (filter);
|
list_some_builtins (filter);
|
||||||
}
|
}
|
||||||
|
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
|
||||||
|
else if (flags & FFLAG)
|
||||||
|
{
|
||||||
|
filter = (flags & NFLAG) ? DISABLED : ENABLED;
|
||||||
|
if (flags & SFLAG)
|
||||||
|
filter |= SPECIAL;
|
||||||
|
|
||||||
|
result = dyn_load_builtin (list, filter, filename);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined (HAVE_DLCLOSE)
|
||||||
|
else if (flags & DFLAG)
|
||||||
|
{
|
||||||
|
while (list)
|
||||||
|
{
|
||||||
|
opt = dyn_unload_builtin (list->word->word);
|
||||||
|
if (opt == EXECUTION_FAILURE)
|
||||||
|
result = EXECUTION_FAILURE;
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
result = enable_shell_command (list->word->word, disable_p);
|
opt = enable_shell_command (list->word->word, flags & NFLAG);
|
||||||
|
|
||||||
if (!result)
|
if (opt == EXECUTION_FAILURE)
|
||||||
{
|
{
|
||||||
builtin_error ("%s: not a shell builtin", list->word->word);
|
builtin_error ("%s: not a shell builtin", list->word->word);
|
||||||
any_failed++;
|
result = EXECUTION_FAILURE;
|
||||||
}
|
}
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* List some builtins.
|
/* List some builtins.
|
||||||
@@ -111,20 +201,19 @@ list_some_builtins (filter)
|
|||||||
|
|
||||||
for (i = 0; i < num_shell_builtins; i++)
|
for (i = 0; i < num_shell_builtins; i++)
|
||||||
{
|
{
|
||||||
if (!shell_builtins[i].function)
|
if (shell_builtins[i].function == 0 || (shell_builtins[i].flags & BUILTIN_DELETED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((filter & ENABLED) &&
|
if ((filter & SPECIAL) &&
|
||||||
(shell_builtins[i].flags & BUILTIN_ENABLED))
|
(shell_builtins[i].flags & SPECIAL_BUILTIN) == 0)
|
||||||
{
|
continue;
|
||||||
|
|
||||||
|
if ((filter & ENABLED) && (shell_builtins[i].flags & BUILTIN_ENABLED))
|
||||||
printf ("enable %s\n", shell_builtins[i].name);
|
printf ("enable %s\n", shell_builtins[i].name);
|
||||||
}
|
|
||||||
else if ((filter & DISABLED) &&
|
else if ((filter & DISABLED) &&
|
||||||
((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
|
((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
|
||||||
{
|
|
||||||
printf ("enable -n %s\n", shell_builtins[i].name);
|
printf ("enable -n %s\n", shell_builtins[i].name);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable the shell command NAME. If DISABLE_P is non-zero, then
|
/* Enable the shell command NAME. If DISABLE_P is non-zero, then
|
||||||
@@ -134,23 +223,202 @@ enable_shell_command (name, disable_p)
|
|||||||
char *name;
|
char *name;
|
||||||
int disable_p;
|
int disable_p;
|
||||||
{
|
{
|
||||||
register int i;
|
struct builtin *b;
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < num_shell_builtins; i++)
|
b = builtin_address_internal (name, 1);
|
||||||
{
|
if (b == 0)
|
||||||
if (!shell_builtins[i].function)
|
return (EXECUTION_FAILURE);
|
||||||
continue;
|
|
||||||
|
|
||||||
if (STREQ (name, shell_builtins[i].name))
|
|
||||||
{
|
|
||||||
found++;
|
|
||||||
|
|
||||||
if (disable_p)
|
if (disable_p)
|
||||||
shell_builtins[i].flags &= ~BUILTIN_ENABLED;
|
b->flags &= ~BUILTIN_ENABLED;
|
||||||
else
|
else
|
||||||
shell_builtins[i].flags |= BUILTIN_ENABLED;
|
b->flags |= BUILTIN_ENABLED;
|
||||||
}
|
|
||||||
}
|
return (EXECUTION_SUCCESS);
|
||||||
return (found);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
dyn_load_builtin (list, flags, filename)
|
||||||
|
WORD_LIST *list;
|
||||||
|
int flags;
|
||||||
|
char *filename;
|
||||||
|
{
|
||||||
|
WORD_LIST *l;
|
||||||
|
void *handle;
|
||||||
|
|
||||||
|
int total, size, new, replaced;
|
||||||
|
char *struct_name, *name;
|
||||||
|
struct builtin **new_builtins, *b, *new_shell_builtins, *old_builtin;
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
|
||||||
|
#ifndef RTLD_LAZY
|
||||||
|
#define RTLD_LAZY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (_AIX)
|
||||||
|
handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL);
|
||||||
|
#else
|
||||||
|
handle = dlopen (filename, RTLD_LAZY);
|
||||||
|
#endif /* !_AIX */
|
||||||
|
|
||||||
|
if (handle == 0)
|
||||||
|
{
|
||||||
|
builtin_error ("cannot open shared object %s: %s", filename, dlerror ());
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (new = 0, l = list; l; l = l->next, new++)
|
||||||
|
;
|
||||||
|
new_builtins = (struct builtin **)xmalloc (new * sizeof (struct builtin *));
|
||||||
|
|
||||||
|
/* For each new builtin in the shared object, find it and its describing
|
||||||
|
structure. If this is overwriting an existing builtin, do so, otherwise
|
||||||
|
save the loaded struct for creating the new list of builtins. */
|
||||||
|
for (replaced = new = 0; list; list = list->next)
|
||||||
|
{
|
||||||
|
name = list->word->word;
|
||||||
|
|
||||||
|
size = strlen (name);
|
||||||
|
struct_name = xmalloc (size + 8);
|
||||||
|
strcpy (struct_name, name);
|
||||||
|
strcpy (struct_name + size, "_struct");
|
||||||
|
|
||||||
|
b = (struct builtin *)dlsym (handle, struct_name);
|
||||||
|
if (b == 0)
|
||||||
|
{
|
||||||
|
builtin_error ("cannot find %s in shared object %s: %s", struct_name,
|
||||||
|
filename, dlerror ());
|
||||||
|
free (struct_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (struct_name);
|
||||||
|
|
||||||
|
b->flags &= ~STATIC_BUILTIN;
|
||||||
|
if (flags & SPECIAL)
|
||||||
|
b->flags |= SPECIAL_BUILTIN;
|
||||||
|
b->handle = handle;
|
||||||
|
|
||||||
|
if (old_builtin = builtin_address_internal (name, 1))
|
||||||
|
{
|
||||||
|
replaced++;
|
||||||
|
FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
new_builtins[new++] = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replaced == 0 && new == 0)
|
||||||
|
{
|
||||||
|
free (new_builtins);
|
||||||
|
dlclose (handle);
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new)
|
||||||
|
{
|
||||||
|
total = num_shell_builtins + new;
|
||||||
|
size = (total + 1) * sizeof (struct builtin);
|
||||||
|
|
||||||
|
new_shell_builtins = (struct builtin *)xmalloc (size);
|
||||||
|
FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
|
||||||
|
num_shell_builtins * sizeof (struct builtin));
|
||||||
|
for (replaced = 0; replaced < new; replaced++)
|
||||||
|
FASTCOPY ((char *)new_builtins[replaced],
|
||||||
|
(char *)&new_shell_builtins[num_shell_builtins + replaced],
|
||||||
|
sizeof (struct builtin));
|
||||||
|
|
||||||
|
new_shell_builtins[total].name = (char *)0;
|
||||||
|
new_shell_builtins[total].function = (Function *)0;
|
||||||
|
new_shell_builtins[total].flags = 0;
|
||||||
|
|
||||||
|
if (shell_builtins != static_shell_builtins)
|
||||||
|
free (shell_builtins);
|
||||||
|
|
||||||
|
shell_builtins = new_shell_builtins;
|
||||||
|
num_shell_builtins = total;
|
||||||
|
initialize_shell_builtins ();
|
||||||
|
}
|
||||||
|
|
||||||
|
free (new_builtins);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (HAVE_DLCLOSE)
|
||||||
|
static void
|
||||||
|
delete_builtin (b)
|
||||||
|
struct builtin *b;
|
||||||
|
{
|
||||||
|
int ind, size;
|
||||||
|
struct builtin *new_shell_builtins;
|
||||||
|
|
||||||
|
/* XXX - funky pointer arithmetic - XXX */
|
||||||
|
ind = ((int)b - (int)shell_builtins) / sizeof (struct builtin);
|
||||||
|
size = num_shell_builtins * sizeof (struct builtin);
|
||||||
|
new_shell_builtins = (struct builtin *)xmalloc (size);
|
||||||
|
|
||||||
|
/* Copy shell_builtins[0]...shell_builtins[ind - 1] to new_shell_builtins */
|
||||||
|
if (ind)
|
||||||
|
FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
|
||||||
|
ind * sizeof (struct builtin));
|
||||||
|
/* Copy shell_builtins[ind+1]...shell_builtins[num_shell_builtins to
|
||||||
|
new_shell_builtins, starting at ind. */
|
||||||
|
FASTCOPY ((char *)(&shell_builtins[ind+1]),
|
||||||
|
(char *)(&new_shell_builtins[ind]),
|
||||||
|
(num_shell_builtins - ind) * sizeof (struct builtin));
|
||||||
|
|
||||||
|
if (shell_builtins != static_shell_builtins)
|
||||||
|
free (shell_builtins);
|
||||||
|
|
||||||
|
/* The result is still sorted. */
|
||||||
|
num_shell_builtins--;
|
||||||
|
shell_builtins = new_shell_builtins;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dyn_unload_builtin (name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
struct builtin *b;
|
||||||
|
void *handle;
|
||||||
|
int ref, i;
|
||||||
|
|
||||||
|
b = builtin_address_internal (name, 1);
|
||||||
|
if (b == 0)
|
||||||
|
{
|
||||||
|
builtin_error ("%s: not a shell builtin", name);
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
if (b->flags & STATIC_BUILTIN)
|
||||||
|
{
|
||||||
|
builtin_error ("%s: not dynamically loaded", name);
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle = (void *)b->handle;
|
||||||
|
for (ref = i = 0; i < num_shell_builtins; i++)
|
||||||
|
{
|
||||||
|
if (shell_builtins[i].handle == b->handle)
|
||||||
|
ref++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't remove the shared object unless the reference count of builtins
|
||||||
|
using it drops to zero. */
|
||||||
|
if (ref == 1 && dlclose (handle) != 0)
|
||||||
|
{
|
||||||
|
builtin_error ("cannot delete %s: %s", name, dlerror ());
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now remove this entry from the builtin table and reinitialize. */
|
||||||
|
delete_builtin (b);
|
||||||
|
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -27,19 +27,24 @@ $SHORT_DOC eval [arg ...]
|
|||||||
Read ARGs as input to the shell and execute the resulting command(s).
|
Read ARGs as input to the shell and execute the resulting command(s).
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
|
extern int parse_and_execute ();
|
||||||
|
|
||||||
/* Parse the string that these words make, and execute the command found. */
|
/* Parse the string that these words make, and execute the command found. */
|
||||||
int
|
int
|
||||||
eval_builtin (list)
|
eval_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int result;
|
if (no_options (list))
|
||||||
|
return (EX_USAGE);
|
||||||
|
|
||||||
/* Note that parse_and_execute () frees the string it is passed. */
|
/* Note that parse_and_execute () frees the string it is passed. */
|
||||||
if (list)
|
return (list ? parse_and_execute (string_list (list), "eval", -1) : EXECUTION_SUCCESS);
|
||||||
result = parse_and_execute (string_list (list), "eval", -1);
|
|
||||||
else
|
|
||||||
result = EXECUTION_SUCCESS;
|
|
||||||
return (result);
|
|
||||||
}
|
}
|
||||||
|
|||||||
211
builtins/evalfile.c
Normal file
211
builtins/evalfile.c
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
/* Copyright (C) 1996 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include "../posixstat.h"
|
||||||
|
#include "../filecntl.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
|
#include "../shell.h"
|
||||||
|
#include "../jobs.h"
|
||||||
|
#include "../builtins.h"
|
||||||
|
#include "../flags.h"
|
||||||
|
#include "../input.h"
|
||||||
|
#include "../execute_cmd.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
|
||||||
|
|
||||||
|
extern int interactive, interactive_shell, 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)
|
||||||
|
char *filename;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
volatile int old_interactive;
|
||||||
|
procenv_t old_return_catch;
|
||||||
|
int return_val, fd, result;
|
||||||
|
char *string;
|
||||||
|
struct stat finfo;
|
||||||
|
VFunction *errfunc;
|
||||||
|
|
||||||
|
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 = (VFunction *)((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 (S_ISREG (finfo.st_mode) == 0)
|
||||||
|
{
|
||||||
|
(*errfunc) ("%s: not a regular file", filename);
|
||||||
|
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
string = xmalloc (1 + (int)finfo.st_size);
|
||||||
|
result = read (fd, string, finfo.st_size);
|
||||||
|
string[result] = '\0';
|
||||||
|
|
||||||
|
return_val = errno;
|
||||||
|
close (fd);
|
||||||
|
errno = return_val;
|
||||||
|
|
||||||
|
if (result != (int)finfo.st_size)
|
||||||
|
{
|
||||||
|
free (string);
|
||||||
|
goto file_error_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_binary_file ((unsigned char *)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 (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, -1);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((flags & FEVAL_BUILTIN) ? result : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
maybe_execute_file (fname, force_noninteractive)
|
||||||
|
char *fname;
|
||||||
|
int force_noninteractive;
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
int result, flags;
|
||||||
|
|
||||||
|
filename = bash_tilde_expand (fname);
|
||||||
|
flags = FEVAL_ENOENTOK;
|
||||||
|
if (force_noninteractive)
|
||||||
|
flags |= FEVAL_NONINT;
|
||||||
|
result = _evalfile (filename, flags);
|
||||||
|
free (filename);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
source_file (filename)
|
||||||
|
char *filename;
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;
|
||||||
|
/* POSIX shells exit if non-interactive and file error. */
|
||||||
|
if (posixly_correct && !interactive_shell)
|
||||||
|
flags |= FEVAL_LONGJMP;
|
||||||
|
return (_evalfile (filename, flags));
|
||||||
|
}
|
||||||
228
builtins/evalstring.c
Normal file
228
builtins/evalstring.c
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
/* Copyright (C) 1996 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
|
#include "../shell.h"
|
||||||
|
#include "../jobs.h"
|
||||||
|
#include "../builtins.h"
|
||||||
|
#include "../flags.h"
|
||||||
|
#include "../input.h"
|
||||||
|
#include "../execute_cmd.h"
|
||||||
|
|
||||||
|
#if defined (HISTORY)
|
||||||
|
# include "../bashhist.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
extern int interactive, interactive_shell;
|
||||||
|
extern int indirection_level, startup_state, subshell_environment;
|
||||||
|
extern int line_number;
|
||||||
|
extern int last_command_exit_value;
|
||||||
|
extern int running_trap;
|
||||||
|
extern COMMAND *global_command;
|
||||||
|
|
||||||
|
int parse_and_execute_level = 0;
|
||||||
|
|
||||||
|
/* How to force parse_and_execute () to clean up after itself. */
|
||||||
|
void
|
||||||
|
parse_and_execute_cleanup ()
|
||||||
|
{
|
||||||
|
if (running_trap)
|
||||||
|
{
|
||||||
|
run_trap_cleanup (running_trap - 1);
|
||||||
|
unfreeze_jobs_list ();
|
||||||
|
}
|
||||||
|
run_unwind_frame ("parse_and_execute_top");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse and execute the commands in STRING. Returns whatever
|
||||||
|
execute_command () returns. This frees STRING. INTERACT is
|
||||||
|
the new value for `interactive' while the commands are being
|
||||||
|
executed. A value of -1 means don't change it. */
|
||||||
|
int
|
||||||
|
parse_and_execute (string, from_file, interact)
|
||||||
|
char *string;
|
||||||
|
char *from_file;
|
||||||
|
int interact;
|
||||||
|
{
|
||||||
|
int code;
|
||||||
|
volatile int should_jump_to_top_level, last_result;
|
||||||
|
char *orig_string;
|
||||||
|
COMMAND *volatile command;
|
||||||
|
|
||||||
|
orig_string = string;
|
||||||
|
/* Unwind protect this invocation of parse_and_execute (). */
|
||||||
|
begin_unwind_frame ("parse_and_execute_top");
|
||||||
|
unwind_protect_int (parse_and_execute_level);
|
||||||
|
unwind_protect_jmp_buf (top_level);
|
||||||
|
unwind_protect_int (indirection_level);
|
||||||
|
unwind_protect_int (line_number);
|
||||||
|
if (interact != -1 && interactive != interact)
|
||||||
|
unwind_protect_int (interactive);
|
||||||
|
|
||||||
|
#if defined (HISTORY)
|
||||||
|
if (interactive_shell)
|
||||||
|
{
|
||||||
|
unwind_protect_int (remember_on_history);
|
||||||
|
# if defined (BANG_HISTORY)
|
||||||
|
unwind_protect_int (history_expansion_inhibited);
|
||||||
|
# endif /* BANG_HISTORY */
|
||||||
|
}
|
||||||
|
#endif /* HISTORY */
|
||||||
|
|
||||||
|
add_unwind_protect (pop_stream, (char *)NULL);
|
||||||
|
if (orig_string)
|
||||||
|
add_unwind_protect (xfree, orig_string);
|
||||||
|
end_unwind_frame ();
|
||||||
|
|
||||||
|
parse_and_execute_level++;
|
||||||
|
push_stream (1); /* reset the line number */
|
||||||
|
indirection_level++;
|
||||||
|
if (interact != -1)
|
||||||
|
interactive = interact;
|
||||||
|
|
||||||
|
#if defined (HISTORY)
|
||||||
|
bash_history_disable ();
|
||||||
|
#endif /* HISTORY */
|
||||||
|
|
||||||
|
code = should_jump_to_top_level = 0;
|
||||||
|
last_result = EXECUTION_SUCCESS;
|
||||||
|
command = (COMMAND *)NULL;
|
||||||
|
|
||||||
|
with_input_from_string (string, from_file);
|
||||||
|
while (*(bash_input.location.string))
|
||||||
|
{
|
||||||
|
if (interrupt_state)
|
||||||
|
{
|
||||||
|
last_result = EXECUTION_FAILURE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Provide a location for functions which `longjmp (top_level)' to
|
||||||
|
jump to. This prevents errors in substitution from restarting
|
||||||
|
the reader loop directly, for example. */
|
||||||
|
code = setjmp (top_level);
|
||||||
|
|
||||||
|
if (code)
|
||||||
|
{
|
||||||
|
should_jump_to_top_level = 0;
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case FORCE_EOF:
|
||||||
|
case EXITPROG:
|
||||||
|
run_unwind_frame ("pe_dispose");
|
||||||
|
/* Remember to call longjmp (top_level) after the old
|
||||||
|
value for it is restored. */
|
||||||
|
should_jump_to_top_level = 1;
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
case DISCARD:
|
||||||
|
run_unwind_frame ("pe_dispose");
|
||||||
|
last_command_exit_value = 1; /* XXX */
|
||||||
|
if (subshell_environment)
|
||||||
|
{
|
||||||
|
should_jump_to_top_level = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dispose_command (command); /* XXX */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
programming_error ("parse_and_execute: bad jump: code %d", code);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse_command () == 0)
|
||||||
|
{
|
||||||
|
if (interactive_shell == 0 && read_but_dont_execute)
|
||||||
|
{
|
||||||
|
last_result = EXECUTION_SUCCESS;
|
||||||
|
dispose_command (global_command);
|
||||||
|
global_command = (COMMAND *)NULL;
|
||||||
|
}
|
||||||
|
else if (command = global_command)
|
||||||
|
{
|
||||||
|
struct fd_bitmap *bitmap;
|
||||||
|
|
||||||
|
bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
|
||||||
|
begin_unwind_frame ("pe_dispose");
|
||||||
|
add_unwind_protect (dispose_fd_bitmap, bitmap);
|
||||||
|
|
||||||
|
global_command = (COMMAND *)NULL;
|
||||||
|
|
||||||
|
#if defined (ONESHOT)
|
||||||
|
if (startup_state == 2 && *bash_input.location.string == '\0' &&
|
||||||
|
command->type == cm_simple && !command->redirects &&
|
||||||
|
!command->value.Simple->redirects)
|
||||||
|
{
|
||||||
|
command->flags |= CMD_NO_FORK;
|
||||||
|
command->value.Simple->flags |= CMD_NO_FORK;
|
||||||
|
}
|
||||||
|
#endif /* ONESHOT */
|
||||||
|
|
||||||
|
last_result = execute_command_internal
|
||||||
|
(command, 0, NO_PIPE, NO_PIPE, bitmap);
|
||||||
|
|
||||||
|
dispose_command (command);
|
||||||
|
dispose_fd_bitmap (bitmap);
|
||||||
|
discard_unwind_frame ("pe_dispose");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last_result = EXECUTION_FAILURE;
|
||||||
|
|
||||||
|
/* Since we are shell compatible, syntax errors in a script
|
||||||
|
abort the execution of the script. Right? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
|
||||||
|
run_unwind_frame ("parse_and_execute_top");
|
||||||
|
|
||||||
|
if (interrupt_state && parse_and_execute_level == 0)
|
||||||
|
{
|
||||||
|
/* An interrupt during non-interactive execution in an
|
||||||
|
interactive shell (e.g. via $PROMPT_COMMAND) should
|
||||||
|
not cause the shell to exit. */
|
||||||
|
interactive = interactive_shell;
|
||||||
|
throw_to_top_level ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (should_jump_to_top_level)
|
||||||
|
jump_to_top_level (code);
|
||||||
|
|
||||||
|
return (last_result);
|
||||||
|
}
|
||||||
@@ -23,61 +23,104 @@ $PRODUCES exec.c
|
|||||||
|
|
||||||
$BUILTIN exec
|
$BUILTIN exec
|
||||||
$FUNCTION exec_builtin
|
$FUNCTION exec_builtin
|
||||||
$SHORT_DOC exec [ [-] file [redirection ...]]
|
$SHORT_DOC exec [-cl] [-a name] file [redirection ...]
|
||||||
Exec FILE, replacing this shell with the specified program.
|
Exec FILE, replacing this shell with the specified program.
|
||||||
If FILE is not specified, the redirections take effect in this
|
If FILE is not specified, the redirections take effect in this
|
||||||
shell. If the first argument is `-', then place a dash in the
|
shell. If the first argument is `-l', then place a dash in the
|
||||||
zeroth arg passed to FILE. If the file cannot be exec'ed and
|
zeroth arg passed to FILE, as login does. If the `-c' option
|
||||||
the shell is not interactive, then the shell exits, unless the
|
is supplied, FILE is executed with a null environment. The `-a'
|
||||||
shell variable "no_exit_on_failed_exec" exists.
|
option means to make set argv[0] of the executed process to NAME.
|
||||||
|
If the file cannot be executed and the shell is not interactive,
|
||||||
|
then the shell exits, unless the shell option `execfail' is set.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include "../shell.h"
|
#include <config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "../posixstat.h"
|
#include "../posixstat.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
|
#include "../shell.h"
|
||||||
#include "../execute_cmd.h"
|
#include "../execute_cmd.h"
|
||||||
#include "common.h"
|
#if defined (JOB_CONTROL)
|
||||||
|
# include "../jobs.h"
|
||||||
|
#endif
|
||||||
#include "../flags.h"
|
#include "../flags.h"
|
||||||
|
#include "../trap.h"
|
||||||
|
#if defined (HISTORY)
|
||||||
|
# include "../bashhist.h"
|
||||||
|
#endif
|
||||||
|
#include "common.h"
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
|
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
|
||||||
#if !defined (errno)
|
#if !defined (errno)
|
||||||
extern int errno;
|
extern int errno;
|
||||||
#endif /* !errno */
|
#endif /* !errno */
|
||||||
|
|
||||||
extern int interactive, subshell_environment;
|
extern int interactive, subshell_environment;
|
||||||
extern REDIRECT *redirection_undo_list;
|
extern REDIRECT *redirection_undo_list;
|
||||||
|
|
||||||
|
int no_exit_on_failed_exec;
|
||||||
|
|
||||||
|
/* If the user wants this to look like a login shell, then
|
||||||
|
prepend a `-' onto NAME and return the new name. */
|
||||||
|
static char *
|
||||||
|
mkdashname (name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
ret = xmalloc (2 + strlen (name));
|
||||||
|
ret[0] = '-';
|
||||||
|
strcpy (ret + 1, name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
exec_builtin (list)
|
exec_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int exit_value = EXECUTION_FAILURE;
|
int exit_value = EXECUTION_FAILURE;
|
||||||
|
int cleanenv, login, opt;
|
||||||
|
char *argv0, *command, **args, **env, *newname;
|
||||||
|
|
||||||
maybe_make_export_env ();
|
cleanenv = login = 0;
|
||||||
|
argv0 = (char *)NULL;
|
||||||
|
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "cla:")) != -1)
|
||||||
|
{
|
||||||
|
switch (opt)
|
||||||
|
{
|
||||||
|
case 'c':
|
||||||
|
cleanenv = 1;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
login = 1;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
argv0 = list_optarg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
|
return (EX_USAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
/* First, let the redirections remain. */
|
/* First, let the redirections remain. */
|
||||||
dispose_redirects (redirection_undo_list);
|
dispose_redirects (redirection_undo_list);
|
||||||
redirection_undo_list = (REDIRECT *)NULL;
|
redirection_undo_list = (REDIRECT *)NULL;
|
||||||
|
|
||||||
if (!list)
|
if (list == 0)
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Otherwise, execve the new command with args. */
|
|
||||||
char *command, **args;
|
|
||||||
int dash_name = 0;
|
|
||||||
|
|
||||||
if (list->word->word[0] == '-' && !list->word->word[1])
|
|
||||||
{
|
|
||||||
/* The user would like to exec this command as if it was a
|
|
||||||
login command. Do so. */
|
|
||||||
list = list->next;
|
|
||||||
dash_name++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!list)
|
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
|
|
||||||
#if defined (RESTRICTED_SHELL)
|
#if defined (RESTRICTED_SHELL)
|
||||||
@@ -88,15 +131,12 @@ exec_builtin (list)
|
|||||||
}
|
}
|
||||||
#endif /* RESTRICTED_SHELL */
|
#endif /* RESTRICTED_SHELL */
|
||||||
|
|
||||||
args = make_word_array (list);
|
args = word_list_to_argv (list, 1, 0, (int *)NULL);
|
||||||
|
|
||||||
/* A command with a slash anywhere in its name is not looked up in
|
/* A command with a slash anywhere in its name is not looked up in $PATH. */
|
||||||
the search path. */
|
command = absolute_program (args[0]) ? args[0] : search_for_command (args[0]);
|
||||||
if (absolute_program (args[0]))
|
|
||||||
command = args[0];
|
if (command == 0)
|
||||||
else
|
|
||||||
command = find_user_command (args[0]);
|
|
||||||
if (!command)
|
|
||||||
{
|
{
|
||||||
builtin_error ("%s: not found", args[0]);
|
builtin_error ("%s: not found", args[0]);
|
||||||
exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
|
exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
|
||||||
@@ -104,26 +144,37 @@ exec_builtin (list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
command = full_pathname (command);
|
command = full_pathname (command);
|
||||||
/* If the user wants this to look like a login shell, then
|
|
||||||
prepend a `-' onto the first argument (argv[0]). */
|
if (argv0)
|
||||||
if (dash_name)
|
|
||||||
{
|
{
|
||||||
char *new_name = xmalloc (2 + strlen (args[0]));
|
|
||||||
new_name[0] = '-';
|
|
||||||
strcpy (new_name + 1, args[0]);
|
|
||||||
free (args[0]);
|
free (args[0]);
|
||||||
args[0] = new_name;
|
args[0] = login ? mkdashname (argv0) : savestring (argv0);
|
||||||
|
}
|
||||||
|
else if (login)
|
||||||
|
{
|
||||||
|
newname = mkdashname (args[0]);
|
||||||
|
free (args[0]);
|
||||||
|
args[0] = newname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrement SHLVL by 1 so a new shell started here has the same value,
|
/* Decrement SHLVL by 1 so a new shell started here has the same value,
|
||||||
preserving the appearance. After we do that, we need to change the
|
preserving the appearance. After we do that, we need to change the
|
||||||
exported environment to include the new value. */
|
exported environment to include the new value. */
|
||||||
|
if (cleanenv == 0)
|
||||||
adjust_shell_level (-1);
|
adjust_shell_level (-1);
|
||||||
|
|
||||||
|
if (cleanenv)
|
||||||
|
env = (char **)NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
maybe_make_export_env ();
|
maybe_make_export_env ();
|
||||||
|
env = export_env;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined (HISTORY)
|
#if defined (HISTORY)
|
||||||
maybe_save_shell_history ();
|
maybe_save_shell_history ();
|
||||||
#endif /* HISTORY */
|
#endif /* HISTORY */
|
||||||
|
|
||||||
restore_original_signals ();
|
restore_original_signals ();
|
||||||
|
|
||||||
#if defined (JOB_CONTROL)
|
#if defined (JOB_CONTROL)
|
||||||
@@ -131,11 +182,11 @@ exec_builtin (list)
|
|||||||
end_job_control ();
|
end_job_control ();
|
||||||
#endif /* JOB_CONTROL */
|
#endif /* JOB_CONTROL */
|
||||||
|
|
||||||
shell_execve (command, args, export_env);
|
shell_execve (command, args, env);
|
||||||
|
if (cleanenv == 0)
|
||||||
adjust_shell_level (1);
|
adjust_shell_level (1);
|
||||||
|
|
||||||
if (!executable_file (command))
|
if (executable_file (command) == 0)
|
||||||
{
|
{
|
||||||
builtin_error ("%s: cannot execute: %s", command, strerror (errno));
|
builtin_error ("%s: cannot execute: %s", command, strerror (errno));
|
||||||
exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
|
exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
|
||||||
@@ -143,13 +194,12 @@ exec_builtin (list)
|
|||||||
else
|
else
|
||||||
file_error (command);
|
file_error (command);
|
||||||
|
|
||||||
failed_exec:
|
failed_exec:
|
||||||
if (command)
|
if (command)
|
||||||
free (command);
|
free (command);
|
||||||
|
|
||||||
if (subshell_environment ||
|
if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
|
||||||
(!interactive && !find_variable ("no_exit_on_failed_exec")))
|
exit_shell (exit_value);
|
||||||
exit (exit_value);
|
|
||||||
|
|
||||||
initialize_traps ();
|
initialize_traps ();
|
||||||
reinitialize_signals ();
|
reinitialize_signals ();
|
||||||
@@ -159,5 +209,4 @@ exec_builtin (list)
|
|||||||
#endif /* JOB_CONTROL */
|
#endif /* JOB_CONTROL */
|
||||||
|
|
||||||
return (exit_value);
|
return (exit_value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
This file is exit.def, from which is created exit.c.
|
This file is exit.def, from which is created exit.c.
|
||||||
It implements the builtins "exit" and "logout" in Bash.
|
It implements the builtins "exit", and "logout" in Bash.
|
||||||
|
|
||||||
Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
|
||||||
@@ -28,18 +28,26 @@ Exit the shell with a status of N. If N is omitted, the exit status
|
|||||||
is that of the last command executed.
|
is that of the last command executed.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../jobs.h"
|
#include "../jobs.h"
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "builtext.h" /* for jobs_builtin */
|
#include "builtext.h" /* for jobs_builtin */
|
||||||
|
|
||||||
extern int interactive, login_shell;
|
extern int interactive, login_shell;
|
||||||
extern int last_command_exit_value;
|
extern int last_command_exit_value;
|
||||||
|
|
||||||
static int exit_or_logout ();
|
static int exit_or_logout ();
|
||||||
static int sourced_logout = 0;
|
static int sourced_logout;
|
||||||
|
|
||||||
int
|
int
|
||||||
exit_builtin (list)
|
exit_builtin (list)
|
||||||
@@ -65,9 +73,9 @@ int
|
|||||||
logout_builtin (list)
|
logout_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
if (!login_shell && interactive)
|
if (login_shell == 0 && interactive)
|
||||||
{
|
{
|
||||||
builtin_error ("Not login shell: use `exit'");
|
builtin_error ("not login shell: use `exit'");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -87,7 +95,7 @@ exit_or_logout (list)
|
|||||||
#if defined (JOB_CONTROL)
|
#if defined (JOB_CONTROL)
|
||||||
int exit_immediate_okay;
|
int exit_immediate_okay;
|
||||||
|
|
||||||
exit_immediate_okay = (!interactive ||
|
exit_immediate_okay = (interactive == 0 ||
|
||||||
last_shell_builtin == exit_builtin ||
|
last_shell_builtin == exit_builtin ||
|
||||||
last_shell_builtin == logout_builtin ||
|
last_shell_builtin == logout_builtin ||
|
||||||
last_shell_builtin == jobs_builtin);
|
last_shell_builtin == jobs_builtin);
|
||||||
@@ -97,7 +105,7 @@ exit_or_logout (list)
|
|||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
for (i = 0; i < job_slots; i++)
|
for (i = 0; i < job_slots; i++)
|
||||||
if (jobs[i] && (jobs[i]->state == JSTOPPED))
|
if (jobs[i] && STOPPED (i))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "There are stopped jobs.\n");
|
fprintf (stderr, "There are stopped jobs.\n");
|
||||||
|
|
||||||
@@ -113,17 +121,20 @@ exit_or_logout (list)
|
|||||||
|
|
||||||
/* Get return value if present. This means that you can type
|
/* Get return value if present. This means that you can type
|
||||||
`logout 5' to a shell, and it returns 5. */
|
`logout 5' to a shell, and it returns 5. */
|
||||||
if (list)
|
exit_value = list ? get_numeric_arg (list) : last_command_exit_value;
|
||||||
exit_value = get_numeric_arg (list);
|
|
||||||
else
|
|
||||||
exit_value = last_command_exit_value;
|
|
||||||
|
|
||||||
/* Run our `~/.bash_logout' file if it exists, and this is a login shell. */
|
/* Run our `~/.bash_logout' file if it exists, and this is a login shell. */
|
||||||
if (login_shell && sourced_logout++ == 0)
|
if (login_shell && sourced_logout++ == 0)
|
||||||
|
{
|
||||||
maybe_execute_file ("~/.bash_logout", 1);
|
maybe_execute_file ("~/.bash_logout", 1);
|
||||||
|
#ifdef SYS_BASH_LOGOUT
|
||||||
|
maybe_execute_file (SYS_BASH_LOGOUT, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
last_command_exit_value = exit_value;
|
last_command_exit_value = exit_value;
|
||||||
|
|
||||||
/* Exit the program. */
|
/* Exit the program. */
|
||||||
longjmp (top_level, EXITPROG);
|
jump_to_top_level (EXITPROG);
|
||||||
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|||||||
183
builtins/fc.def
183
builtins/fc.def
@@ -46,23 +46,32 @@ runs the last command beginning with `cc' and typing `r' re-executes
|
|||||||
the last command.
|
the last command.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <config.h>
|
||||||
#include "../bashansi.h"
|
|
||||||
#include "../shell.h"
|
|
||||||
#if defined (HISTORY)
|
#if defined (HISTORY)
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/types.h>
|
#include "bashtypes.h"
|
||||||
#include <sys/stat.h>
|
#include "posixstat.h"
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "../shell.h"
|
||||||
#include "../builtins.h"
|
#include "../builtins.h"
|
||||||
#include "../flags.h"
|
#include "../flags.h"
|
||||||
#include "../maxpath.h"
|
#include "../maxpath.h"
|
||||||
#include "../bashhist.h"
|
#include "../bashhist.h"
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#include "bashgetopt.h"
|
#include "bashgetopt.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
|
|
||||||
#if !defined (errno)
|
#if !defined (errno)
|
||||||
extern int errno;
|
extern int errno;
|
||||||
#endif /* !errno */
|
#endif /* !errno */
|
||||||
@@ -100,8 +109,8 @@ extern int unlink ();
|
|||||||
Equivalent to !command:sg/pat/rep execpt there can be multiple PAT=REP's.
|
Equivalent to !command:sg/pat/rep execpt there can be multiple PAT=REP's.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *fc_dosubs (), *fc_replace (), *fc_gethist (), *fc_readline ();
|
static char *fc_dosubs (), *fc_gethist (), *fc_readline ();
|
||||||
static int fc_gethnum ();
|
static int fc_gethnum (), fc_number ();
|
||||||
static void fc_replhist (), fc_addhist ();
|
static void fc_replhist (), fc_addhist ();
|
||||||
|
|
||||||
/* Data structure describing a list of global replacements to perform. */
|
/* Data structure describing a list of global replacements to perform. */
|
||||||
@@ -111,8 +120,6 @@ typedef struct repl {
|
|||||||
char *rep;
|
char *rep;
|
||||||
} REPL;
|
} REPL;
|
||||||
|
|
||||||
#define USAGE "usage: fc [-e ename] [-nlr] [first] [last] or fc -s [pat=rep] [command]"
|
|
||||||
|
|
||||||
/* Accessors for HIST_ENTRY lists that are called HLIST. */
|
/* Accessors for HIST_ENTRY lists that are called HLIST. */
|
||||||
#define histline(i) (hlist[(i)]->line)
|
#define histline(i) (hlist[(i)]->line)
|
||||||
#define histdata(i) (hlist[(i)]->data)
|
#define histdata(i) (hlist[(i)]->data)
|
||||||
@@ -143,24 +150,20 @@ fc_builtin (list)
|
|||||||
int numbering, reverse, listing, execute;
|
int numbering, reverse, listing, execute;
|
||||||
int histbeg, histend, last_hist, retval, first, opt;
|
int histbeg, histend, last_hist, retval, first, opt;
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
REPL *rlist = (REPL *) NULL, *rl;
|
REPL *rlist, *rl;
|
||||||
char *ename = NULL, *command, *newcom, *line;
|
char *ename, *command, *newcom, *line;
|
||||||
HIST_ENTRY **hlist;
|
HIST_ENTRY **hlist;
|
||||||
char fn[MAXPATHLEN];
|
char fn[64];
|
||||||
|
|
||||||
numbering = 1;
|
numbering = 1;
|
||||||
reverse = listing = execute = 0;
|
reverse = listing = execute = 0;
|
||||||
|
ename = (char *)NULL;
|
||||||
|
|
||||||
/* Parse out the options and set which of the two forms we're in. */
|
/* Parse out the options and set which of the two forms we're in. */
|
||||||
|
reset_internal_getopt ();
|
||||||
while (list && *list->word->word == '-')
|
lcurrent = list; /* XXX */
|
||||||
{
|
while (fc_number (loptend = lcurrent) == 0 &&
|
||||||
register char *s = &((list->word->word)[1]);
|
(opt = internal_getopt (list, ":e:lnrs")) != -1)
|
||||||
|
|
||||||
if (!isletter (*s))
|
|
||||||
break;
|
|
||||||
|
|
||||||
while (opt = *s++)
|
|
||||||
{
|
{
|
||||||
switch (opt)
|
switch (opt)
|
||||||
{
|
{
|
||||||
@@ -181,22 +184,16 @@ fc_builtin (list)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
list = list->next;
|
ename = list_optarg;
|
||||||
if (list == NULL)
|
|
||||||
{
|
|
||||||
builtin_error (USAGE);
|
|
||||||
return (EX_USAGE);
|
|
||||||
}
|
|
||||||
ename = list->word->word;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
builtin_error (USAGE);
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list = list->next;
|
|
||||||
}
|
list = loptend;
|
||||||
|
|
||||||
if (ename && (*ename == '-') && (ename[1] == '\0'))
|
if (ename && (*ename == '-') && (ename[1] == '\0'))
|
||||||
execute = 1;
|
execute = 1;
|
||||||
@@ -205,6 +202,7 @@ fc_builtin (list)
|
|||||||
substitutions). */
|
substitutions). */
|
||||||
if (execute)
|
if (execute)
|
||||||
{
|
{
|
||||||
|
rlist = (REPL *)NULL;
|
||||||
while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL))
|
while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL))
|
||||||
{
|
{
|
||||||
*sep++ = '\0';
|
*sep++ = '\0';
|
||||||
@@ -227,16 +225,13 @@ fc_builtin (list)
|
|||||||
to get the replacements in the proper order. */
|
to get the replacements in the proper order. */
|
||||||
|
|
||||||
if (rlist && rlist->next)
|
if (rlist && rlist->next)
|
||||||
rlist = (REPL *) reverse_list ((GENERIC_LIST *) rlist);
|
rlist = (REPL *)reverse_list ((GENERIC_LIST *) rlist);
|
||||||
|
|
||||||
hlist = history_list ();
|
hlist = history_list ();
|
||||||
|
|
||||||
/* If we still have something in list, it is a command spec.
|
/* If we still have something in list, it is a command spec.
|
||||||
Otherwise, we use the most recent command in time. */
|
Otherwise, we use the most recent command in time. */
|
||||||
if (list)
|
command = fc_gethist (list ? list->word->word : (char *)NULL, hlist);
|
||||||
command = fc_gethist (list->word->word, hlist);
|
|
||||||
else
|
|
||||||
command = fc_gethist ((char *) NULL, hlist);
|
|
||||||
|
|
||||||
if (command == NULL)
|
if (command == NULL)
|
||||||
{
|
{
|
||||||
@@ -255,8 +250,8 @@ fc_builtin (list)
|
|||||||
command = newcom;
|
command = newcom;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("%s\n", command);
|
fprintf (stderr, "%s\n", command);
|
||||||
fc_replhist (command); /* replace `fc -e -' with command */
|
fc_replhist (command); /* replace `fc -s' with command */
|
||||||
return (parse_and_execute (command, "fc", -1));
|
return (parse_and_execute (command, "fc", -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,12 +278,7 @@ fc_builtin (list)
|
|||||||
if (list)
|
if (list)
|
||||||
histend = fc_gethnum (list->word->word, hlist);
|
histend = fc_gethnum (list->word->word, hlist);
|
||||||
else
|
else
|
||||||
{
|
histend = listing ? last_hist : histbeg;
|
||||||
if (listing)
|
|
||||||
histend = last_hist;
|
|
||||||
else
|
|
||||||
histend = histbeg;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -301,11 +291,9 @@ fc_builtin (list)
|
|||||||
histbeg = 0;
|
histbeg = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
/* For editing, it is the last history command. */
|
/* For editing, it is the last history command. */
|
||||||
histbeg = histend = last_hist;
|
histbeg = histend = last_hist;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* We print error messages for line specifications out of range. */
|
/* We print error messages for line specifications out of range. */
|
||||||
if ((histbeg < 0) || (histend < 0) ||
|
if ((histbeg < 0) || (histend < 0) ||
|
||||||
@@ -317,10 +305,10 @@ fc_builtin (list)
|
|||||||
|
|
||||||
if (histend < histbeg)
|
if (histend < histbeg)
|
||||||
{
|
{
|
||||||
int t = histend;
|
i = histend;
|
||||||
|
|
||||||
histend = histbeg;
|
histend = histbeg;
|
||||||
histbeg = t;
|
histbeg = i;
|
||||||
|
|
||||||
reverse = 1;
|
reverse = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,20 +317,18 @@ fc_builtin (list)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
numbering = 0;
|
numbering = 0;
|
||||||
sprintf (fn, "/tmp/bash%d", (int)time ((long *) 0) + (int)getpid ());
|
sprintf (fn, "/tmp/bash%d", (int)time ((time_t *) 0) + (int)getpid ());
|
||||||
|
|
||||||
stream = fopen (fn, "w");
|
stream = fopen (fn, "w");
|
||||||
|
|
||||||
if (!stream)
|
if (stream == 0)
|
||||||
{
|
{
|
||||||
builtin_error ("cannot open temp file %s", fn);
|
builtin_error ("cannot open temp file %s", fn);
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reverse)
|
for (i = reverse ? histend : histbeg; reverse ? i >= histbeg : i <= histend; reverse ? i-- : i++)
|
||||||
{
|
|
||||||
for (i = histbeg; i <= histend; i++)
|
|
||||||
{
|
{
|
||||||
QUIT;
|
QUIT;
|
||||||
if (numbering)
|
if (numbering)
|
||||||
@@ -351,19 +337,6 @@ fc_builtin (list)
|
|||||||
fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
|
fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
|
||||||
fprintf (stream, "%s\n", histline (i));
|
fprintf (stream, "%s\n", histline (i));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = histend; i >= histbeg; i--)
|
|
||||||
{
|
|
||||||
QUIT;
|
|
||||||
if (numbering)
|
|
||||||
fprintf (stream, "%d", i + history_base);
|
|
||||||
if (listing)
|
|
||||||
fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
|
|
||||||
fprintf (stream, "%s\n", histline (i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listing)
|
if (listing)
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
@@ -381,7 +354,12 @@ fc_builtin (list)
|
|||||||
command = (char *)xmalloc (3 + strlen (FC_EDIT_COMMAND) + strlen (fn));
|
command = (char *)xmalloc (3 + strlen (FC_EDIT_COMMAND) + strlen (fn));
|
||||||
sprintf (command, "%s %s", FC_EDIT_COMMAND, fn);
|
sprintf (command, "%s %s", FC_EDIT_COMMAND, fn);
|
||||||
}
|
}
|
||||||
parse_and_execute (command, "fc", -1);
|
retval = parse_and_execute (command, "fc", -1);
|
||||||
|
if (retval != EXECUTION_SUCCESS)
|
||||||
|
{
|
||||||
|
unlink (fn);
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Now reopen the file and execute the edited commands. */
|
/* Now reopen the file and execute the edited commands. */
|
||||||
|
|
||||||
@@ -435,6 +413,21 @@ fc_builtin (list)
|
|||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return 1 if LIST->word->word is a legal number for fc's use. */
|
||||||
|
static int
|
||||||
|
fc_number (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
return 0;
|
||||||
|
s = list->word->word;
|
||||||
|
if (*s == '-')
|
||||||
|
s++;
|
||||||
|
return (legal_number (s, (long *)NULL));
|
||||||
|
}
|
||||||
|
|
||||||
/* Return an absolute index into HLIST which corresponds to COMMAND. If
|
/* Return an absolute index into HLIST which corresponds to COMMAND. If
|
||||||
COMMAND is a number, then it was specified in relative terms. If it
|
COMMAND is a number, then it was specified in relative terms. If it
|
||||||
is a string, then it is the start of a command line present in HLIST. */
|
is a string, then it is the start of a command line present in HLIST. */
|
||||||
@@ -572,58 +565,18 @@ fc_dosubs (command, subs)
|
|||||||
char *command;
|
char *command;
|
||||||
REPL *subs;
|
REPL *subs;
|
||||||
{
|
{
|
||||||
register char *new = savestring (command);
|
register char *new, *t;
|
||||||
register REPL *r;
|
register REPL *r;
|
||||||
|
|
||||||
for (r = subs; r; r = r->next)
|
for (new = savestring (command), r = subs; r; r = r->next)
|
||||||
{
|
{
|
||||||
register char *t;
|
t = strsub (new, r->pat, r->rep, 1);
|
||||||
|
|
||||||
t = fc_replace (r->pat, r->rep, new);
|
|
||||||
free (new);
|
free (new);
|
||||||
new = t;
|
new = t;
|
||||||
}
|
}
|
||||||
return (new);
|
return (new);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Replace the occurrences of PAT with REP in COMMAND.
|
|
||||||
This returns a new string; the caller should free it. */
|
|
||||||
static char *
|
|
||||||
fc_replace (pat, rep, command)
|
|
||||||
char *pat, *rep, *command;
|
|
||||||
{
|
|
||||||
register int i;
|
|
||||||
int patlen, replen, templen;
|
|
||||||
char *new, *temp;
|
|
||||||
|
|
||||||
patlen = strlen (pat);
|
|
||||||
replen = strlen (rep);
|
|
||||||
|
|
||||||
temp = savestring (command);
|
|
||||||
templen = strlen (temp);
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for (; (i + patlen) <= templen; i++)
|
|
||||||
{
|
|
||||||
if (STREQN (temp + i, pat, patlen))
|
|
||||||
{
|
|
||||||
new = (char *) xmalloc (1 + (replen - patlen) + templen);
|
|
||||||
|
|
||||||
strncpy (new, temp, i);
|
|
||||||
strncpy (new + i, rep, replen);
|
|
||||||
strncpy (new + i + replen,
|
|
||||||
temp + i + patlen, templen - (i + patlen));
|
|
||||||
new[templen + (replen - patlen)] = '\0'; /* just in case */
|
|
||||||
|
|
||||||
free (temp);
|
|
||||||
temp = new;
|
|
||||||
i += replen;
|
|
||||||
templen = strlen (temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use `command' to replace the last entry in the history list, which,
|
/* Use `command' to replace the last entry in the history list, which,
|
||||||
by this time, is `fc blah...'. The intent is that the new command
|
by this time, is `fc blah...'. The intent is that the new command
|
||||||
become the history entry, and that `fc' should never appear in the
|
become the history entry, and that `fc' should never appear in the
|
||||||
@@ -634,10 +587,9 @@ fc_replhist (command)
|
|||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
HIST_ENTRY **hlist, *histent, *discard;
|
HIST_ENTRY **hlist, *histent, *discard;
|
||||||
char *data;
|
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (!command || !*command)
|
if (command == 0 || *command == '\0')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hlist = history_list ();
|
hlist = history_list ();
|
||||||
@@ -665,8 +617,7 @@ fc_replhist (command)
|
|||||||
discard = remove_history (i);
|
discard = remove_history (i);
|
||||||
if (discard)
|
if (discard)
|
||||||
{
|
{
|
||||||
if (discard->line)
|
FREE (discard->line);
|
||||||
free (discard->line);
|
|
||||||
free ((char *) discard);
|
free ((char *) discard);
|
||||||
}
|
}
|
||||||
maybe_add_history (command); /* Obeys HISTCONTROL setting. */
|
maybe_add_history (command); /* Obeys HISTCONTROL setting. */
|
||||||
|
|||||||
@@ -30,10 +30,18 @@ JOB_SPEC is not present, the shell's notion of the current job is
|
|||||||
used.
|
used.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../jobs.h"
|
#include "../jobs.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#if defined (JOB_CONTROL)
|
#if defined (JOB_CONTROL)
|
||||||
extern char *this_command_name;
|
extern char *this_command_name;
|
||||||
@@ -45,23 +53,23 @@ int
|
|||||||
fg_builtin (list)
|
fg_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int fg_bit = 1;
|
int fg_bit;
|
||||||
register WORD_LIST *t = list;
|
register WORD_LIST *t;
|
||||||
|
|
||||||
if (!job_control)
|
if (job_control == 0)
|
||||||
{
|
{
|
||||||
builtin_error ("no job control");
|
builtin_error ("no job control");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (no_options (list))
|
||||||
|
return (EX_USAGE);
|
||||||
|
|
||||||
/* If the last arg on the line is '&', then start this job in the
|
/* If the last arg on the line is '&', then start this job in the
|
||||||
background. Else, fg the job. */
|
background. Else, fg the job. */
|
||||||
|
for (t = list; t && t->next; t = t->next)
|
||||||
while (t && t->next)
|
;
|
||||||
t = t->next;
|
fg_bit = (t && t->word->word[0] == '&' && t->word->word[1] == '\0') == 0;
|
||||||
|
|
||||||
if (t && t->word->word[0] == '&' && !t->word->word[1])
|
|
||||||
fg_bit = 0;
|
|
||||||
|
|
||||||
return (fg_bg (list, fg_bit));
|
return (fg_bg (list, fg_bit));
|
||||||
}
|
}
|
||||||
@@ -82,12 +90,15 @@ int
|
|||||||
bg_builtin (list)
|
bg_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
if (!job_control)
|
if (job_control == 0)
|
||||||
{
|
{
|
||||||
builtin_error ("no job control");
|
builtin_error ("no job control");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (no_options (list))
|
||||||
|
return (EX_USAGE);
|
||||||
|
|
||||||
return (fg_bg (list, 0));
|
return (fg_bg (list, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,27 +109,27 @@ fg_bg (list, foreground)
|
|||||||
int foreground;
|
int foreground;
|
||||||
{
|
{
|
||||||
sigset_t set, oset;
|
sigset_t set, oset;
|
||||||
int job, status = EXECUTION_SUCCESS, old_async_pid;
|
int job, status, old_async_pid;
|
||||||
|
|
||||||
BLOCK_CHILD (set, oset);
|
BLOCK_CHILD (set, oset);
|
||||||
job = get_job_spec (list);
|
job = get_job_spec (list);
|
||||||
|
|
||||||
if (job < 0 || job >= job_slots || !jobs[job])
|
if (job < 0 || job >= job_slots || jobs[job] == 0)
|
||||||
{
|
{
|
||||||
if (job != DUP_JOB)
|
if (job != DUP_JOB)
|
||||||
builtin_error ("No such job %s", list ? list->word->word : "");
|
builtin_error ("%s: no such job", list ? list->word->word : "current");
|
||||||
|
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Or if jobs[job]->pgrp == shell_pgrp. */
|
/* Or if jobs[job]->pgrp == shell_pgrp. */
|
||||||
if (!(jobs[job]->flags & J_JOBCONTROL))
|
if (IS_JOBCONTROL (job) == 0)
|
||||||
{
|
{
|
||||||
builtin_error ("job %%%d started without job control", job + 1);
|
builtin_error ("job %%%d started without job control", job + 1);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foreground)
|
if (foreground == 0)
|
||||||
{
|
{
|
||||||
old_async_pid = last_asynchronous_pid;
|
old_async_pid = last_asynchronous_pid;
|
||||||
last_asynchronous_pid = jobs[job]->pgrp; /* As per Posix.2 5.4.2 */
|
last_asynchronous_pid = jobs[job]->pgrp; /* As per Posix.2 5.4.2 */
|
||||||
@@ -134,7 +145,7 @@ fg_bg (list, foreground)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!foreground)
|
if (foreground == 0)
|
||||||
last_asynchronous_pid = old_async_pid;
|
last_asynchronous_pid = old_async_pid;
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
|
|||||||
@@ -17,6 +17,12 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "../memalloc.h"
|
#include "../memalloc.h"
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
@@ -66,6 +72,9 @@ int sh_opterr = 1;
|
|||||||
|
|
||||||
int sh_optopt = '?';
|
int sh_optopt = '?';
|
||||||
|
|
||||||
|
/* Set to 1 when we see an illegal option; public so getopts can reset it. */
|
||||||
|
int sh_badopt = 0;
|
||||||
|
|
||||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||||
given in OPTSTRING.
|
given in OPTSTRING.
|
||||||
|
|
||||||
@@ -102,7 +111,6 @@ sh_getopt (argc, argv, optstring)
|
|||||||
char *const *argv;
|
char *const *argv;
|
||||||
const char *optstring;
|
const char *optstring;
|
||||||
{
|
{
|
||||||
int option_index;
|
|
||||||
char c, *temp;
|
char c, *temp;
|
||||||
|
|
||||||
sh_optarg = 0;
|
sh_optarg = 0;
|
||||||
@@ -124,10 +132,18 @@ sh_getopt (argc, argv, optstring)
|
|||||||
nextchar = (char *)NULL;
|
nextchar = (char *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do the increment of `sh_optind' we deferred because the last option
|
||||||
|
was illegal. */
|
||||||
|
if (sh_badopt && (nextchar == 0 || *nextchar == '\0'))
|
||||||
|
{
|
||||||
|
sh_badopt = 0;
|
||||||
|
sh_optind++;
|
||||||
|
nextchar = (char *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (nextchar == 0 || *nextchar == '\0')
|
if (nextchar == 0 || *nextchar == '\0')
|
||||||
{
|
{
|
||||||
/* If we have done all the ARGV-elements, stop the scan
|
/* If we have done all the ARGV-elements, stop the scan. */
|
||||||
and back over any non-options that we skipped and permuted. */
|
|
||||||
if (sh_optind == argc)
|
if (sh_optind == argc)
|
||||||
return EOF;
|
return EOF;
|
||||||
|
|
||||||
@@ -158,16 +174,11 @@ sh_getopt (argc, argv, optstring)
|
|||||||
c = *nextchar++; sh_charindex++;
|
c = *nextchar++; sh_charindex++;
|
||||||
temp = strchr (optstring, c);
|
temp = strchr (optstring, c);
|
||||||
|
|
||||||
/* Increment `sh_optind' when we start to process its last character. */
|
|
||||||
if (nextchar == 0 || *nextchar == '\0')
|
|
||||||
{
|
|
||||||
sh_optind++;
|
|
||||||
nextchar = (char *)NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
sh_optopt = c;
|
sh_optopt = c;
|
||||||
|
|
||||||
if (temp == NULL || c == ':')
|
/* If the option is illegal, return an error, but defer updating sh_optind
|
||||||
|
until the next call so $OPTIND is correct. */
|
||||||
|
if (sh_badopt = (temp == NULL || c == ':'))
|
||||||
{
|
{
|
||||||
if (sh_opterr)
|
if (sh_opterr)
|
||||||
BADOPT (c);
|
BADOPT (c);
|
||||||
@@ -175,6 +186,13 @@ sh_getopt (argc, argv, optstring)
|
|||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Increment `sh_optind' when we start to process its last character. */
|
||||||
|
if (nextchar == 0 || *nextchar == '\0')
|
||||||
|
{
|
||||||
|
sh_optind++;
|
||||||
|
nextchar = (char *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (temp[1] == ':')
|
if (temp[1] == ':')
|
||||||
{
|
{
|
||||||
if (nextchar && *nextchar)
|
if (nextchar && *nextchar)
|
||||||
@@ -191,6 +209,7 @@ sh_getopt (argc, argv, optstring)
|
|||||||
NEEDARG (c);
|
NEEDARG (c);
|
||||||
|
|
||||||
sh_optopt = c;
|
sh_optopt = c;
|
||||||
|
sh_optarg = ""; /* Needed by getopts. */
|
||||||
c = (optstring[0] == ':') ? ':' : '?';
|
c = (optstring[0] == ':') ? ':' : '?';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ extern int sh_opterr;
|
|||||||
|
|
||||||
extern int sh_optopt;
|
extern int sh_optopt;
|
||||||
|
|
||||||
|
/* Set to 1 when an unrecognized option is encountered. */
|
||||||
|
extern int sh_badopt;
|
||||||
|
|
||||||
extern int sh_getopt ();
|
extern int sh_getopt ();
|
||||||
extern void sh_getopt_restore_state ();
|
extern void sh_getopt_restore_state ();
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||||||
$PRODUCES getopts.c
|
$PRODUCES getopts.c
|
||||||
|
|
||||||
$BUILTIN getopts
|
$BUILTIN getopts
|
||||||
$DEPENDS_ON GETOPTS_BUILTIN
|
|
||||||
$FUNCTION getopts_builtin
|
$FUNCTION getopts_builtin
|
||||||
$SHORT_DOC getopts optstring name [arg]
|
$SHORT_DOC getopts optstring name [arg]
|
||||||
Getopts is used by shell procedures to parse positional parameters.
|
Getopts is used by shell procedures to parse positional parameters.
|
||||||
@@ -57,22 +56,24 @@ Getopts normally parses the positional parameters ($0 - $9), but if
|
|||||||
more arguments are given, they are parsed instead.
|
more arguments are given, they are parsed instead.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if defined (HAVE_STRING_H)
|
#if defined (HAVE_UNISTD_H)
|
||||||
# include <string.h>
|
# include <unistd.h>
|
||||||
#else /* !HAVE_STRING_H */
|
#endif
|
||||||
# include <strings.h>
|
|
||||||
#endif /* !HAVE_STRING_H */
|
#include "../bashansi.h"
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
#include "common.h"
|
||||||
#if defined (GETOPTS_BUILTIN)
|
#include "bashgetopt.h"
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
|
|
||||||
#define G_EOF (-1)
|
#define G_EOF -1
|
||||||
#define G_ILLEGAL_OPT (-2)
|
#define G_ILLEGAL_OPT -2
|
||||||
#define G_ARG_MISSING (-3)
|
#define G_ARG_MISSING -3
|
||||||
|
|
||||||
extern char *this_command_name;
|
extern char *this_command_name;
|
||||||
extern WORD_LIST *rest_of_args;
|
extern WORD_LIST *rest_of_args;
|
||||||
@@ -84,6 +85,25 @@ getopts_reset (newind)
|
|||||||
int newind;
|
int newind;
|
||||||
{
|
{
|
||||||
sh_optind = newind;
|
sh_optind = newind;
|
||||||
|
sh_badopt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
getopts_bind_variable (name, value)
|
||||||
|
char *name, *value;
|
||||||
|
{
|
||||||
|
SHELL_VAR *v;
|
||||||
|
|
||||||
|
if (legal_identifier (name))
|
||||||
|
{
|
||||||
|
v = bind_variable (name, value);
|
||||||
|
return (v && (readonly_p (v) == 0)) ? EXECUTION_SUCCESS : EXECUTION_FAILURE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builtin_error ("`%s': not a valid identifier", name);
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Error handling is now performed as specified by Posix.2, draft 11
|
/* Error handling is now performed as specified by Posix.2, draft 11
|
||||||
@@ -118,7 +138,7 @@ dogetopts (argc, argv)
|
|||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
{
|
{
|
||||||
int ret, special_error, old_opterr = 0, i, n;
|
int ret, special_error, old_opterr, i, n;
|
||||||
char strval[2], numval[16];
|
char strval[2], numval[16];
|
||||||
char *optstr; /* list of options */
|
char *optstr; /* list of options */
|
||||||
char *name; /* variable to get flag val */
|
char *name; /* variable to get flag val */
|
||||||
@@ -126,7 +146,7 @@ dogetopts (argc, argv)
|
|||||||
|
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
{
|
{
|
||||||
builtin_error("usage: getopts optstring name [arg]");
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,19 +176,19 @@ dogetopts (argc, argv)
|
|||||||
}
|
}
|
||||||
else if (rest_of_args == (WORD_LIST *)NULL)
|
else if (rest_of_args == (WORD_LIST *)NULL)
|
||||||
{
|
{
|
||||||
register int i;
|
for (i = 0; i < 10 && dollar_vars[i]; i++)
|
||||||
|
;
|
||||||
for (i = 0; i < 10 && dollar_vars[i]; i++);
|
|
||||||
ret = sh_getopt (i, dollar_vars, optstr);
|
ret = sh_getopt (i, dollar_vars, optstr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
register int i;
|
|
||||||
register WORD_LIST *words;
|
register WORD_LIST *words;
|
||||||
char **v;
|
char **v;
|
||||||
|
|
||||||
for (i = 0; i < 10 && dollar_vars[i]; i++);
|
for (i = 0; i < 10 && dollar_vars[i]; i++)
|
||||||
for (words = rest_of_args; words; words = words->next, i++);
|
;
|
||||||
|
for (words = rest_of_args; words; words = words->next, i++)
|
||||||
|
;
|
||||||
v = (char **)xmalloc ((i + 1) * sizeof (char *));
|
v = (char **)xmalloc ((i + 1) * sizeof (char *));
|
||||||
for (i = 0; i < 10 && dollar_vars[i]; i++)
|
for (i = 0; i < 10 && dollar_vars[i]; i++)
|
||||||
v[i] = dollar_vars[i];
|
v[i] = dollar_vars[i];
|
||||||
@@ -203,9 +223,9 @@ dogetopts (argc, argv)
|
|||||||
|
|
||||||
/* If an error occurred, decide which one it is and set the return
|
/* If an error occurred, decide which one it is and set the return
|
||||||
code appropriately. In all cases, the option character in error
|
code appropriately. In all cases, the option character in error
|
||||||
is in SH_OPTOPT. If an illegal option was encountered, OPTARG is
|
is in OPTOPT. If an illegal option was encountered, OPTARG is
|
||||||
NULL. If a required option argument was missing, OPTARG points
|
NULL. If a required option argument was missing, OPTARG points
|
||||||
to a NULL string (that is, optarg[0] == 0). */
|
to a NULL string (that is, sh_optarg[0] == 0). */
|
||||||
if (ret == '?')
|
if (ret == '?')
|
||||||
{
|
{
|
||||||
if (sh_optarg == NULL)
|
if (sh_optarg == NULL)
|
||||||
@@ -216,26 +236,25 @@ dogetopts (argc, argv)
|
|||||||
|
|
||||||
if (ret == G_EOF)
|
if (ret == G_EOF)
|
||||||
{
|
{
|
||||||
bind_variable (name, "?");
|
getopts_bind_variable (name, "?");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == G_ILLEGAL_OPT)
|
if (ret == G_ILLEGAL_OPT)
|
||||||
{
|
{
|
||||||
/* Illegal option encountered. */
|
/* Illegal option encountered. */
|
||||||
strval[0] = '?';
|
ret = getopts_bind_variable (name, "?");
|
||||||
strval[1] = '\0';
|
|
||||||
bind_variable (name, strval);
|
|
||||||
|
|
||||||
if (special_error)
|
if (special_error)
|
||||||
{
|
{
|
||||||
strval[0] = (char) sh_optopt;
|
strval[0] = (char)sh_optopt;
|
||||||
strval[1] = '\0';
|
strval[1] = '\0';
|
||||||
bind_variable ("OPTARG", strval);
|
bind_variable ("OPTARG", strval);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
makunbound ("OPTARG", shell_variables);
|
makunbound ("OPTARG", shell_variables);
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == G_ARG_MISSING)
|
if (ret == G_ARG_MISSING)
|
||||||
@@ -243,31 +262,25 @@ dogetopts (argc, argv)
|
|||||||
/* Required argument missing. */
|
/* Required argument missing. */
|
||||||
if (special_error)
|
if (special_error)
|
||||||
{
|
{
|
||||||
strval[0] = ':';
|
ret = getopts_bind_variable (name, ":");
|
||||||
strval[1] = '\0';
|
|
||||||
bind_variable (name, strval);
|
|
||||||
|
|
||||||
strval[0] = (char) sh_optopt;
|
strval[0] = (char)sh_optopt;
|
||||||
strval[1] = '\0';
|
strval[1] = '\0';
|
||||||
bind_variable ("OPTARG", strval);
|
bind_variable ("OPTARG", strval);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strval[0] = '?';
|
ret = getopts_bind_variable (name, "?");
|
||||||
strval[1] = '\0';
|
|
||||||
bind_variable (name, strval);
|
|
||||||
makunbound ("OPTARG", shell_variables);
|
makunbound ("OPTARG", shell_variables);
|
||||||
}
|
}
|
||||||
return (EXECUTION_SUCCESS);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
bind_variable ("OPTARG", sh_optarg);
|
bind_variable ("OPTARG", sh_optarg);
|
||||||
|
|
||||||
strval[0] = (char) ret;
|
strval[0] = (char) ret;
|
||||||
strval[1] = '\0';
|
strval[1] = '\0';
|
||||||
bind_variable (name, strval);
|
return (getopts_bind_variable (name, strval));
|
||||||
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The getopts builtin. Build an argv, and call dogetopts with it. */
|
/* The getopts builtin. Build an argv, and call dogetopts with it. */
|
||||||
@@ -275,26 +288,27 @@ int
|
|||||||
getopts_builtin (list)
|
getopts_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
register int i;
|
|
||||||
char **av;
|
char **av;
|
||||||
int ac, ret;
|
int ac, ret;
|
||||||
WORD_LIST *t;
|
|
||||||
|
|
||||||
if (list == 0)
|
if (list == 0)
|
||||||
return EXECUTION_FAILURE;
|
return EXECUTION_FAILURE;
|
||||||
|
|
||||||
for (t = list, ac = 0; t; t = t->next, ac++);
|
reset_internal_getopt ();
|
||||||
|
while ((ret = internal_getopt (list, "")) != -1)
|
||||||
ac++;
|
{
|
||||||
av = (char **)xmalloc ((1 + ac) * sizeof (char *));
|
switch (ret)
|
||||||
av[ac] = (char *) NULL;
|
{
|
||||||
av[0] = this_command_name;
|
default:
|
||||||
|
builtin_usage ();
|
||||||
for (t = list, i = 1; t; t = t->next, i++)
|
return (EX_USAGE);
|
||||||
av[i] = t->word->word;
|
}
|
||||||
|
}
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
|
av = make_builtin_argv (list, &ac);
|
||||||
ret = dogetopts (ac, av);
|
ret = dogetopts (ac, av);
|
||||||
free ((char *)av);
|
free ((char *)av);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
#endif /* GETOPTS_BUILTIN */
|
|
||||||
|
|||||||
@@ -23,182 +23,167 @@ $PRODUCES hash.c
|
|||||||
|
|
||||||
$BUILTIN hash
|
$BUILTIN hash
|
||||||
$FUNCTION hash_builtin
|
$FUNCTION hash_builtin
|
||||||
$SHORT_DOC hash [-r] [name ...]
|
$SHORT_DOC hash [-r] [-p pathname] [name ...]
|
||||||
For each NAME, the full pathname of the command is determined and
|
For each NAME, the full pathname of the command is determined and
|
||||||
remembered. The -r option causes the shell to forget all remembered
|
remembered. If the -p option is supplied, PATHNAME is used as the
|
||||||
locations. If no arguments are given, information about remembered
|
full pathname of NAME, and no path search is performed. The -r
|
||||||
commands is presented.
|
option causes the shell to forget all remembered locations. If no
|
||||||
|
arguments are given, information about remembered commands is displayed.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "../posixstat.h"
|
#include "../posixstat.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if defined (HAVE_STRING_H)
|
#if defined (HAVE_UNISTD_H)
|
||||||
# include <string.h>
|
# include <unistd.h>
|
||||||
#else /* !HAVE_STRING_H */
|
#endif
|
||||||
# include <strings.h>
|
|
||||||
#endif /* !HAVE_STRING_H */
|
#include "../bashansi.h"
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../builtins.h"
|
#include "../builtins.h"
|
||||||
#include "../flags.h"
|
#include "../flags.h"
|
||||||
|
#include "../execute_cmd.h"
|
||||||
#include "hashcom.h"
|
#include "hashcom.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "../execute_cmd.h"
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
extern int dot_found_in_search;
|
extern int dot_found_in_search;
|
||||||
|
extern char *this_command_name;
|
||||||
|
|
||||||
|
static int add_hashed_command ();
|
||||||
|
static int print_hashed_commands ();
|
||||||
|
|
||||||
|
static int hashing_initialized = 0;
|
||||||
|
|
||||||
|
HASH_TABLE *hashed_filenames;
|
||||||
|
|
||||||
void
|
void
|
||||||
initialize_filename_hashing ()
|
initialize_filename_hashing ()
|
||||||
{
|
{
|
||||||
|
if (hashing_initialized == 0)
|
||||||
|
{
|
||||||
hashed_filenames = make_hash_table (FILENAME_HASH_BUCKETS);
|
hashed_filenames = make_hash_table (FILENAME_HASH_BUCKETS);
|
||||||
|
hashing_initialized = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_filename_data (data)
|
||||||
|
char *data;
|
||||||
|
{
|
||||||
|
free (((PATH_DATA *)data)->path);
|
||||||
|
free (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
flush_hashed_filenames ()
|
||||||
|
{
|
||||||
|
flush_hash_table (hashed_filenames, free_filename_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove FILENAME from the table of hashed commands. */
|
||||||
|
void
|
||||||
|
remove_hashed_filename (filename)
|
||||||
|
char *filename;
|
||||||
|
{
|
||||||
|
register BUCKET_CONTENTS *item;
|
||||||
|
|
||||||
|
if (hashing_enabled == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
item = remove_hash_item (filename, hashed_filenames);
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
if (item->data)
|
||||||
|
free_filename_data (item->data);
|
||||||
|
free (item->key);
|
||||||
|
free (item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print statistics on the current state of hashed commands. If LIST is
|
/* Print statistics on the current state of hashed commands. If LIST is
|
||||||
not empty, then rehash (or hash in the first place) the specified
|
not empty, then rehash (or hash in the first place) the specified
|
||||||
commands. */
|
commands. */
|
||||||
|
int
|
||||||
hash_builtin (list)
|
hash_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int expunge_hash_table = 0;
|
int expunge_hash_table, opt;
|
||||||
int any_failed = 0;
|
char *word, *pathname;
|
||||||
|
|
||||||
if (hashing_disabled)
|
if (hashing_enabled == 0)
|
||||||
{
|
{
|
||||||
builtin_error ("hashing disabled");
|
builtin_error ("hashing disabled");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (list)
|
expunge_hash_table = 0;
|
||||||
|
pathname = (char *)NULL;
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "rp:")) != -1)
|
||||||
{
|
{
|
||||||
char *arg = list->word->word;
|
switch (opt)
|
||||||
|
|
||||||
if (ISOPTION (arg, 'r'))
|
|
||||||
{
|
{
|
||||||
|
case 'r':
|
||||||
expunge_hash_table = 1;
|
expunge_hash_table = 1;
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
else if (ISOPTION (arg, '-'))
|
|
||||||
{
|
|
||||||
list = list->next;
|
|
||||||
break;
|
break;
|
||||||
}
|
case 'p':
|
||||||
else if (*arg == '-')
|
pathname = list_optarg;
|
||||||
{
|
break;
|
||||||
bad_option (list->word->word);
|
default:
|
||||||
builtin_error ("usage: hash [-r] [command ...]");
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
/* We want hash -r to be silent, but hash -- to print hashing info. That
|
/* We want hash -r to be silent, but hash -- to print hashing info. That
|
||||||
is the reason for the !expunge_hash_table. */
|
is the reason for the test of expunge_hash_table. */
|
||||||
if (!list && !expunge_hash_table)
|
if (list == 0 && expunge_hash_table == 0)
|
||||||
{
|
{
|
||||||
/* Print information about current hashed info. */
|
if (print_hashed_commands () == 0)
|
||||||
int any_printed = 0;
|
printf ("%s: hash table empty\n", this_command_name);
|
||||||
int bucket = 0;
|
|
||||||
register BUCKET_CONTENTS *item_list;
|
|
||||||
|
|
||||||
while (bucket < hashed_filenames->nbuckets)
|
|
||||||
{
|
|
||||||
item_list = get_hash_bucket (bucket, hashed_filenames);
|
|
||||||
if (item_list)
|
|
||||||
{
|
|
||||||
if (!any_printed)
|
|
||||||
{
|
|
||||||
printf ("hits\tcommand\n");
|
|
||||||
any_printed++;
|
|
||||||
}
|
|
||||||
while (item_list)
|
|
||||||
{
|
|
||||||
printf ("%4d\t%s\n",
|
|
||||||
item_list->times_found, pathdata(item_list)->path);
|
|
||||||
item_list = item_list->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bucket++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!any_printed)
|
|
||||||
printf ("No commands in hash table.\n");
|
|
||||||
|
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expunge_hash_table)
|
if (expunge_hash_table)
|
||||||
{
|
flush_hashed_filenames ();
|
||||||
int bucket = 0;
|
|
||||||
register BUCKET_CONTENTS *item_list, *prev;
|
|
||||||
|
|
||||||
while (bucket < hashed_filenames->nbuckets)
|
for (opt = EXECUTION_SUCCESS; list; list = list->next)
|
||||||
{
|
|
||||||
item_list = get_hash_bucket (bucket, hashed_filenames);
|
|
||||||
if (item_list)
|
|
||||||
{
|
|
||||||
while (item_list)
|
|
||||||
{
|
|
||||||
prev = item_list;
|
|
||||||
free (item_list->key);
|
|
||||||
free (pathdata(item_list)->path);
|
|
||||||
free (item_list->data);
|
|
||||||
item_list = item_list->next;
|
|
||||||
free (prev);
|
|
||||||
}
|
|
||||||
hashed_filenames->bucket_array[bucket] = (BUCKET_CONTENTS *)NULL;
|
|
||||||
}
|
|
||||||
bucket++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (list)
|
|
||||||
{
|
{
|
||||||
/* Add or rehash the specified commands. */
|
/* Add or rehash the specified commands. */
|
||||||
char *word;
|
|
||||||
char *full_path;
|
|
||||||
SHELL_VAR *var;
|
|
||||||
|
|
||||||
word = list->word->word;
|
word = list->word->word;
|
||||||
|
if (pathname)
|
||||||
|
remember_filename (word, pathname, 0, 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
if (absolute_program (word))
|
if (absolute_program (word))
|
||||||
{
|
{
|
||||||
list = list->next;
|
list = list->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
full_path = find_user_command (word);
|
|
||||||
var = find_function (word);
|
|
||||||
|
|
||||||
if (!find_shell_builtin (word) && (!var))
|
if (add_hashed_command (word))
|
||||||
{
|
opt = EXECUTION_FAILURE;
|
||||||
if (full_path && executable_file (full_path))
|
|
||||||
remember_filename (word, full_path, dot_found_in_search, 0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
builtin_error ("%s: not found", word);
|
|
||||||
any_failed++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (full_path)
|
|
||||||
free (full_path);
|
|
||||||
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
|
|
||||||
if (any_failed)
|
return (opt);
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
else
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Place FILENAME (key) and FULL_PATHNAME (data->path) into the
|
/* Place FILENAME (key) and FULL_PATHNAME (data->path) into the
|
||||||
hash table. CHECK_DOT if non-null is for future calls to
|
hash table. CHECK_DOT if non-null is for future calls to
|
||||||
find_hashed_filename (). FOUND is the initial value for
|
find_hashed_filename (); it means that this file was found
|
||||||
times_found. */
|
in a directory in $PATH that is not an absolute pathname.
|
||||||
|
FOUND is the initial value for times_found. */
|
||||||
void
|
void
|
||||||
remember_filename (filename, full_pathname, check_dot, found)
|
remember_filename (filename, full_pathname, check_dot, found)
|
||||||
char *filename, *full_pathname;
|
char *filename, *full_pathname;
|
||||||
@@ -206,17 +191,74 @@ remember_filename (filename, full_pathname, check_dot, found)
|
|||||||
{
|
{
|
||||||
register BUCKET_CONTENTS *item;
|
register BUCKET_CONTENTS *item;
|
||||||
|
|
||||||
if (hashing_disabled)
|
if (hashing_enabled == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
item = add_hash_item (filename, hashed_filenames);
|
item = add_hash_item (filename, hashed_filenames);
|
||||||
if (item->data)
|
if (item->data)
|
||||||
free (pathdata(item)->path);
|
free (pathdata(item)->path);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->key = savestring (filename);
|
item->key = savestring (filename);
|
||||||
item->data = (char *)xmalloc (sizeof (PATH_DATA));
|
item->data = xmalloc (sizeof (PATH_DATA));
|
||||||
}
|
}
|
||||||
pathdata(item)->path = savestring (full_pathname);
|
pathdata(item)->path = savestring (full_pathname);
|
||||||
pathdata(item)->check_dot = check_dot;
|
pathdata(item)->flags = 0;
|
||||||
|
if (check_dot)
|
||||||
|
pathdata(item)->flags |= HASH_CHKDOT;
|
||||||
|
if (*full_pathname != '/')
|
||||||
|
pathdata(item)->flags |= HASH_RELPATH;
|
||||||
item->times_found = found;
|
item->times_found = found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
add_hashed_command (word, quiet)
|
||||||
|
char *word;
|
||||||
|
int quiet;
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
char *full_path;
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
if (find_function (word) == 0 && find_shell_builtin (word) == 0)
|
||||||
|
{
|
||||||
|
full_path = find_user_command (word);
|
||||||
|
if (full_path && executable_file (full_path))
|
||||||
|
remember_filename (word, full_path, dot_found_in_search, 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (quiet == 0)
|
||||||
|
builtin_error ("%s: not found", word);
|
||||||
|
rv++;
|
||||||
|
}
|
||||||
|
if (full_path)
|
||||||
|
free (full_path);
|
||||||
|
}
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print information about current hashed info. */
|
||||||
|
static int
|
||||||
|
print_hashed_commands ()
|
||||||
|
{
|
||||||
|
BUCKET_CONTENTS *item_list;
|
||||||
|
int bucket, any_printed;
|
||||||
|
|
||||||
|
for (bucket = any_printed = 0; bucket < hashed_filenames->nbuckets; bucket++)
|
||||||
|
{
|
||||||
|
item_list = get_hash_bucket (bucket, hashed_filenames);
|
||||||
|
if (item_list == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (any_printed == 0)
|
||||||
|
{
|
||||||
|
printf ("hits\tcommand\n");
|
||||||
|
any_printed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( ; item_list; item_list = item_list->next)
|
||||||
|
printf ("%4d\t%s\n", item_list->times_found, pathdata(item_list)->path);
|
||||||
|
|
||||||
|
}
|
||||||
|
return (any_printed);
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
with Bash; see the file COPYING. If not, write to the Free Software
|
with Bash; see the file COPYING. If not, write to the Free Software
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "../hash.h"
|
#include "../hashlib.h"
|
||||||
|
|
||||||
#define FILENAME_HASH_BUCKETS 631
|
#define FILENAME_HASH_BUCKETS 631
|
||||||
|
|
||||||
@@ -26,7 +26,10 @@ extern HASH_TABLE *hashed_filenames;
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *path; /* The full pathname of the file. */
|
char *path; /* The full pathname of the file. */
|
||||||
int check_dot; /* Whether `.' appeared before this one in $PATH. */
|
int flags;
|
||||||
} PATH_DATA;
|
} PATH_DATA;
|
||||||
|
|
||||||
|
#define HASH_RELPATH 0x01 /* this filename is a relative pathname. */
|
||||||
|
#define HASH_CHKDOT 0x02 /* check `.' since it was earlier in $PATH */
|
||||||
|
|
||||||
#define pathdata(x) ((PATH_DATA *)(x)->data)
|
#define pathdata(x) ((PATH_DATA *)(x)->data)
|
||||||
|
|||||||
@@ -23,36 +23,110 @@ $PRODUCES help.c
|
|||||||
|
|
||||||
$BUILTIN help
|
$BUILTIN help
|
||||||
$FUNCTION help_builtin
|
$FUNCTION help_builtin
|
||||||
|
$DEPENDS_ON HELP_BUILTIN
|
||||||
$SHORT_DOC help [pattern ...]
|
$SHORT_DOC help [pattern ...]
|
||||||
Display helpful information about builtin commands. If PATTERN is
|
Display helpful information about builtin commands. If PATTERN is
|
||||||
specified, gives detailed help on all commands matching PATTERN,
|
specified, gives detailed help on all commands matching PATTERN,
|
||||||
otherwise a list of the builtins is printed.
|
otherwise a list of the builtins is printed.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HELP_BUILTIN)
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../builtins.h"
|
#include "../builtins.h"
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
#if defined (USE_GLOB_LIBRARY)
|
#include <glob/fnmatch.h>
|
||||||
# include <glob/glob.h>
|
#include <glob/glob.h>
|
||||||
#else
|
|
||||||
# define FNM_NOMATCH 1
|
static void show_builtin_command_help ();
|
||||||
#endif /* USE_GLOB_LIBRARY */
|
|
||||||
|
|
||||||
/* Print out a list of the known functions in the shell, and what they do.
|
/* Print out a list of the known functions in the shell, and what they do.
|
||||||
If LIST is supplied, print out the list which matches for each pattern
|
If LIST is supplied, print out the list which matches for each pattern
|
||||||
specified. */
|
specified. */
|
||||||
|
int
|
||||||
help_builtin (list)
|
help_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
if (!list)
|
|
||||||
{
|
|
||||||
register int i, j;
|
register int i, j;
|
||||||
char blurb[256];
|
char *pattern, *name;
|
||||||
|
int plen, match_found;
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
{
|
||||||
|
show_shell_version (0);
|
||||||
|
show_builtin_command_help ();
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Placeholder for future options. */
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((i = internal_getopt (list, "")) != -1)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
|
return (EX_USAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
|
/* We should consider making `help bash' do something. */
|
||||||
|
|
||||||
|
if (glob_pattern_p (list->word->word))
|
||||||
|
{
|
||||||
|
printf ("Shell commands matching keyword%s `", list->next ? "s" : "");
|
||||||
|
print_word_list (list, ", ");
|
||||||
|
printf ("'\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (match_found = 0, pattern = ""; list; list = list->next)
|
||||||
|
{
|
||||||
|
pattern = list->word->word;
|
||||||
|
plen = strlen (pattern);
|
||||||
|
|
||||||
|
for (i = 0; name = shell_builtins[i].name; i++)
|
||||||
|
{
|
||||||
|
QUIT;
|
||||||
|
if ((strncmp (pattern, name, plen) == 0) ||
|
||||||
|
(fnmatch (pattern, name, 0) != FNM_NOMATCH))
|
||||||
|
{
|
||||||
|
printf ("%s: %s\n", name, shell_builtins[i].short_doc);
|
||||||
|
|
||||||
|
for (j = 0; shell_builtins[i].long_doc[j]; j++)
|
||||||
|
printf (" %s\n", shell_builtins[i].long_doc[j]);
|
||||||
|
|
||||||
|
match_found++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_found == 0)
|
||||||
|
{
|
||||||
|
builtin_error ("no help topics match `%s'. Try `help help'.", pattern);
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fflush (stdout);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
show_builtin_command_help ()
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
char blurb[36];
|
||||||
|
|
||||||
show_shell_version ();
|
|
||||||
printf (
|
printf (
|
||||||
"Shell commands that are defined internally. Type `help' to see this list.\n\
|
"These shell commands are defined internally. Type `help' to see this list.\n\
|
||||||
Type `help name' to find out more about the function `name'.\n\
|
Type `help name' to find out more about the function `name'.\n\
|
||||||
Use `info bash' to find out more about the shell in general.\n\
|
Use `info bash' to find out more about the shell in general.\n\
|
||||||
\n\
|
\n\
|
||||||
@@ -62,10 +136,8 @@ A star (*) next to a name means that the command is disabled.\n\
|
|||||||
for (i = 0; i < num_shell_builtins; i++)
|
for (i = 0; i < num_shell_builtins; i++)
|
||||||
{
|
{
|
||||||
QUIT;
|
QUIT;
|
||||||
sprintf (blurb, "%c%s",
|
blurb[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
|
||||||
(shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*',
|
strncpy (blurb + 1, shell_builtins[i].short_doc, 34);
|
||||||
shell_builtins[i].short_doc);
|
|
||||||
|
|
||||||
blurb[35] = '\0';
|
blurb[35] = '\0';
|
||||||
printf ("%s", blurb);
|
printf ("%s", blurb);
|
||||||
|
|
||||||
@@ -74,61 +146,8 @@ A star (*) next to a name means that the command is disabled.\n\
|
|||||||
else
|
else
|
||||||
for (j = strlen (blurb); j < 35; j++)
|
for (j = strlen (blurb); j < 35; j++)
|
||||||
putc (' ', stdout);
|
putc (' ', stdout);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (i % 2)
|
if (i % 2)
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int match_found = 0;
|
|
||||||
char *pattern = "";
|
|
||||||
|
|
||||||
if (glob_pattern_p (list->word->word))
|
|
||||||
{
|
|
||||||
printf ("Shell commands matching keyword%s `",
|
|
||||||
list->next ? "s" : "");
|
|
||||||
print_word_list (list, ", ");
|
|
||||||
printf ("'\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (list)
|
|
||||||
{
|
|
||||||
register int i = 0, plen;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
pattern = list->word->word;
|
|
||||||
plen = strlen (pattern);
|
|
||||||
|
|
||||||
while (name = shell_builtins[i].name)
|
|
||||||
{
|
|
||||||
int doc_index;
|
|
||||||
|
|
||||||
QUIT;
|
|
||||||
if ((strncmp (pattern, name, plen) == 0) ||
|
|
||||||
(fnmatch (pattern, name, 0) != FNM_NOMATCH))
|
|
||||||
{
|
|
||||||
printf ("%s: %s\n", name, shell_builtins[i].short_doc);
|
|
||||||
|
|
||||||
for (doc_index = 0;
|
|
||||||
shell_builtins[i].long_doc[doc_index]; doc_index++)
|
|
||||||
printf (" %s\n", shell_builtins[i].long_doc[doc_index]);
|
|
||||||
|
|
||||||
match_found++;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!match_found)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "No help topics match `%s'. Try `help help'.\n",
|
|
||||||
pattern);
|
|
||||||
fflush (stderr);
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fflush (stdout);
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
#endif /* HELP_BUILTIN */
|
||||||
|
|||||||
@@ -24,156 +24,277 @@ $PRODUCES history.c
|
|||||||
$BUILTIN history
|
$BUILTIN history
|
||||||
$FUNCTION history_builtin
|
$FUNCTION history_builtin
|
||||||
$DEPENDS_ON HISTORY
|
$DEPENDS_ON HISTORY
|
||||||
$SHORT_DOC history [n] [ [-awrn] [filename]]
|
$SHORT_DOC history [-c] [n] or history -awrn [filename] or history -ps arg [arg...]
|
||||||
Display the history list with line numbers. Lines listed with
|
Display the history list with line numbers. Lines listed with
|
||||||
with a `*' have been modified. Argument of N says to list only
|
with a `*' have been modified. Argument of N says to list only
|
||||||
the last N lines. Argument `-w' means to write out the current
|
the last N lines. The -c option causes the history list to be
|
||||||
history file; `-r' means to read it instead. Argument `-a' means
|
cleared by deleting all of the entries. The `-w' option writes out the
|
||||||
|
current history to the history file; `-r' means to read the file and
|
||||||
|
append the contents to the history list instead. `-a' means
|
||||||
to append history lines from this session to the history file.
|
to append history lines from this session to the history file.
|
||||||
Argument `-n' means to read all history lines not already read
|
Argument `-n' means to read all history lines not already read
|
||||||
from the history file. If FILENAME is given, then use that file,
|
from the history file and append them to the history list. If
|
||||||
else if $HISTFILE has a value, use that, else use ~/.bash_history.
|
FILENAME is given, then that is used as the history file else
|
||||||
|
if $HISTFILE has a value, that is used, else ~/.bash_history.
|
||||||
|
If the -s option is supplied, the non-option ARGs are appended to
|
||||||
|
the history list as a single entry. The -p option means to perform
|
||||||
|
history expansion on each ARG and display the result, without storing
|
||||||
|
anything in the history list.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include "../shell.h"
|
#include <config.h>
|
||||||
|
|
||||||
#if defined (HISTORY)
|
#if defined (HISTORY)
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include "../filecntl.h"
|
|
||||||
#include "../posixstat.h"
|
#include "../posixstat.h"
|
||||||
|
#include "../filecntl.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
|
#include "../shell.h"
|
||||||
#include "../bashhist.h"
|
#include "../bashhist.h"
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
/* History. Arg of -w FILENAME means write file, arg of -r FILENAME
|
#if !defined (errno)
|
||||||
means read file. Arg of N means only display that many items. */
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void display_history ();
|
||||||
|
static void push_history ();
|
||||||
|
static int expand_and_print_history ();
|
||||||
|
|
||||||
|
#define AFLAG 0x01
|
||||||
|
#define RFLAG 0x02
|
||||||
|
#define WFLAG 0x04
|
||||||
|
#define NFLAG 0x08
|
||||||
|
#define SFLAG 0x10
|
||||||
|
#define PFLAG 0x20
|
||||||
|
#define CFLAG 0x40
|
||||||
|
|
||||||
|
int
|
||||||
history_builtin (list)
|
history_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
register int i;
|
int flags, opt, result;
|
||||||
int limited = 0, limit = 0;
|
char *filename;
|
||||||
HIST_ENTRY **hlist;
|
|
||||||
|
|
||||||
while (list)
|
flags = 0;
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "acnpsrw")) != -1)
|
||||||
{
|
{
|
||||||
char *arg = list->word->word;
|
switch (opt)
|
||||||
|
|
||||||
if ((arg[0] == '-') &&
|
|
||||||
(strlen (arg) == 2) &&
|
|
||||||
(member (arg[1], "rwan")))
|
|
||||||
{
|
{
|
||||||
char *file;
|
case 'a':
|
||||||
int result = EXECUTION_SUCCESS;
|
flags |= AFLAG;
|
||||||
|
|
||||||
if (list->next)
|
|
||||||
file = list->next->word->word;
|
|
||||||
else
|
|
||||||
file = get_string_value ("HISTFILE");
|
|
||||||
|
|
||||||
switch (arg[1])
|
|
||||||
{
|
|
||||||
case 'a': /* Append `new' lines to file. */
|
|
||||||
{
|
|
||||||
if (history_lines_this_session)
|
|
||||||
{
|
|
||||||
void using_history ();
|
|
||||||
|
|
||||||
if (history_lines_this_session < where_history ())
|
|
||||||
{
|
|
||||||
/* If the filename was supplied, then create it
|
|
||||||
if it doesn't already exist. */
|
|
||||||
if (file)
|
|
||||||
{
|
|
||||||
struct stat buf;
|
|
||||||
|
|
||||||
if (stat (file, &buf) == -1)
|
|
||||||
{
|
|
||||||
int tem;
|
|
||||||
|
|
||||||
tem = open (file, O_CREAT, 0666);
|
|
||||||
close (tem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result =
|
|
||||||
append_history (history_lines_this_session, file);
|
|
||||||
history_lines_in_file += history_lines_this_session;
|
|
||||||
history_lines_this_session = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
case 'c':
|
||||||
|
flags |= CFLAG;
|
||||||
case 'w': /* Write entire history. */
|
|
||||||
{
|
|
||||||
result = write_history (file);
|
|
||||||
break;
|
break;
|
||||||
}
|
case 'n':
|
||||||
|
flags |= NFLAG;
|
||||||
case 'r': /* Read entire file. */
|
|
||||||
{
|
|
||||||
result = read_history (file);
|
|
||||||
break;
|
break;
|
||||||
}
|
case 'r':
|
||||||
|
flags |= RFLAG;
|
||||||
case 'n': /* Read `new' history from file. */
|
|
||||||
{
|
|
||||||
/* Read all of the lines in the file that we haven't
|
|
||||||
already read. */
|
|
||||||
using_history ();
|
|
||||||
result = read_history_range (file, history_lines_in_file, -1);
|
|
||||||
using_history ();
|
|
||||||
history_lines_in_file = where_history ();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
case 'w':
|
||||||
}
|
flags |= WFLAG;
|
||||||
return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
|
||||||
}
|
|
||||||
else if (strcmp (list->word->word, "--") == 0)
|
|
||||||
{
|
|
||||||
list = list->next;
|
|
||||||
break;
|
break;
|
||||||
}
|
case 's':
|
||||||
else if (*list->word->word == '-')
|
flags |= SFLAG;
|
||||||
{
|
break;
|
||||||
bad_option (list->word->word);
|
case 'p':
|
||||||
builtin_error ("usage: history [n] [-rwan [filename]]");
|
#if defined (BANG_HISTORY)
|
||||||
|
flags |= PFLAG;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
|
opt = flags & (AFLAG|RFLAG|WFLAG|NFLAG);
|
||||||
|
if (opt && opt != AFLAG && opt != RFLAG && opt != WFLAG && opt != NFLAG)
|
||||||
|
{
|
||||||
|
builtin_error ("cannot use more than one of -anrw");
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear the history, but allow other arguments to add to it again. */
|
||||||
|
if (flags & CFLAG)
|
||||||
|
{
|
||||||
|
clear_history ();
|
||||||
|
if (list == 0)
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & SFLAG)
|
||||||
|
{
|
||||||
|
if (list)
|
||||||
|
push_history (list);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
#if defined (BANG_HISTORY)
|
||||||
|
else if (flags & PFLAG)
|
||||||
|
{
|
||||||
|
if (list)
|
||||||
|
return (expand_and_print_history (list));
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if ((flags & (AFLAG|RFLAG|NFLAG|WFLAG|CFLAG)) == 0)
|
||||||
|
{
|
||||||
|
display_history (list);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = list ? list->word->word : get_string_value ("HISTFILE");
|
||||||
|
result = EXECUTION_SUCCESS;
|
||||||
|
|
||||||
|
if (flags & AFLAG) /* Append session's history to file. */
|
||||||
|
result = maybe_append_history (filename);
|
||||||
|
else if (flags & WFLAG) /* Write entire history. */
|
||||||
|
result = write_history (filename);
|
||||||
|
else if (flags & RFLAG) /* Read entire file. */
|
||||||
|
result = read_history (filename);
|
||||||
|
else if (flags & NFLAG) /* Read `new' history from file. */
|
||||||
|
{
|
||||||
|
/* Read all of the lines in the file that we haven't already read. */
|
||||||
|
using_history ();
|
||||||
|
result = read_history_range (filename, history_lines_in_file, -1);
|
||||||
|
using_history ();
|
||||||
|
history_lines_in_file = where_history ();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accessors for HIST_ENTRY lists that are called HLIST. */
|
||||||
|
#define histline(i) (hlist[(i)]->line)
|
||||||
|
#define histdata(i) (hlist[(i)]->data)
|
||||||
|
|
||||||
|
static void
|
||||||
|
display_history (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
int limited, limit;
|
||||||
|
HIST_ENTRY **hlist;
|
||||||
|
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
limited = 1;
|
limited = 1;
|
||||||
limit = get_numeric_arg (list);
|
limit = get_numeric_arg (list);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
limited = limit = 0;
|
||||||
|
|
||||||
hlist = history_list ();
|
hlist = history_list ();
|
||||||
|
|
||||||
if (hlist)
|
if (hlist)
|
||||||
{
|
{
|
||||||
for (i = 0; hlist[i]; i++);
|
for (i = 0; hlist[i]; i++)
|
||||||
|
;
|
||||||
|
|
||||||
if (limit < 0)
|
if (limit < 0)
|
||||||
limit = -limit;
|
limit = -limit;
|
||||||
|
|
||||||
if (!limited)
|
if ((limited == 0) || ((i -= limit) < 0))
|
||||||
i = 0;
|
|
||||||
else
|
|
||||||
if ((i -= limit) < 0)
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
while (hlist[i])
|
while (hlist[i])
|
||||||
{
|
{
|
||||||
QUIT;
|
QUIT;
|
||||||
printf ("%5d%c %s\n", i + history_base,
|
printf ("%5d%c %s\n", i + history_base,
|
||||||
hlist[i]->data ? '*' : ' ', hlist[i]->line);
|
histdata(i) ? '*' : ' ',
|
||||||
|
histline(i));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
delete_last_history ()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
HIST_ENTRY **hlist, *histent, *discard;
|
||||||
|
|
||||||
|
hlist = history_list ();
|
||||||
|
if (hlist == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; hlist[i]; i++)
|
||||||
|
;
|
||||||
|
i--;
|
||||||
|
|
||||||
|
/* History_get () takes a parameter that must be offset by history_base. */
|
||||||
|
histent = history_get (history_base + i); /* Don't free this */
|
||||||
|
if (histent == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
discard = remove_history (i);
|
||||||
|
if (discard)
|
||||||
|
{
|
||||||
|
if (discard->line)
|
||||||
|
free (discard->line);
|
||||||
|
free ((char *) discard);
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the last entry in the history list and add each argument in
|
||||||
|
LIST to the history. */
|
||||||
|
static void
|
||||||
|
push_history (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if (delete_last_history () == 0)
|
||||||
|
return;
|
||||||
|
s = string_list (list);
|
||||||
|
maybe_add_history (s); /* Obeys HISTCONTROL setting. */
|
||||||
|
free (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (BANG_HISTORY)
|
||||||
|
static int
|
||||||
|
expand_and_print_history (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
int r, result;
|
||||||
|
|
||||||
|
if (delete_last_history () == 0)
|
||||||
|
return EXECUTION_FAILURE;
|
||||||
|
result = EXECUTION_SUCCESS;
|
||||||
|
while (list)
|
||||||
|
{
|
||||||
|
r = history_expand (list->word->word, &s);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
builtin_error ("%s: history expansion failed", list->word->word);
|
||||||
|
result = EXECUTION_FAILURE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fputs (s, stdout);
|
||||||
|
putchar ('\n');
|
||||||
|
}
|
||||||
|
FREE (s);
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
fflush (stdout);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif /* BANG_HISTORY */
|
||||||
#endif /* HISTORY */
|
#endif /* HISTORY */
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ with Bash; see the file COPYING. If not, write to the Free Software
|
|||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
$PRODUCES inlib.c
|
$PRODUCES inlib.c
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
This file is jobs.def, from which is created jobs.c.
|
This file is jobs.def, from which is created jobs.c.
|
||||||
It implements the builtin "jobs" in Bash.
|
It implements the builtins "jobs" and "disown" in Bash.
|
||||||
|
|
||||||
Copyright (C) 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
|
Copyright (C) 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
|
||||||
|
|
||||||
@@ -24,24 +24,38 @@ $PRODUCES jobs.c
|
|||||||
$BUILTIN jobs
|
$BUILTIN jobs
|
||||||
$FUNCTION jobs_builtin
|
$FUNCTION jobs_builtin
|
||||||
$DEPENDS_ON JOB_CONTROL
|
$DEPENDS_ON JOB_CONTROL
|
||||||
$SHORT_DOC jobs [-lnp] [jobspec ...] | jobs -x command [args]
|
$SHORT_DOC jobs [-lnprs] [jobspec ...] or jobs -x command [args]
|
||||||
Lists the active jobs. The -l option lists process id's in addition
|
Lists the active jobs. The -l option lists process id's in addition
|
||||||
to the normal information; the -p option lists process id's only.
|
to the normal information; the -p option lists process id's only.
|
||||||
If -n is given, only processes that have changed status since the last
|
If -n is given, only processes that have changed status since the last
|
||||||
notification are printed. JOBSPEC restricts output to that job.
|
notification are printed. JOBSPEC restricts output to that job. The
|
||||||
If -x is given, COMMAND is run after all job specifications that appear
|
-r and -s options restrict output to running and stopped jobs only,
|
||||||
in ARGS have been replaced with the process ID of that job's process group
|
respectively. Without options, the status of all active jobs is
|
||||||
leader.
|
printed. If -x is given, COMMAND is run after all job specifications
|
||||||
|
that appear in ARGS have been replaced with the process ID of that job's
|
||||||
|
process group leader.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include "../shell.h"
|
#include <config.h>
|
||||||
|
|
||||||
#if defined (JOB_CONTROL)
|
#if defined (JOB_CONTROL)
|
||||||
#include <sys/types.h>
|
#include "../bashtypes.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "../jobs.h"
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
|
#include "../shell.h"
|
||||||
|
#include "../jobs.h"
|
||||||
|
#include "../execute_cmd.h"
|
||||||
#include "bashgetopt.h"
|
#include "bashgetopt.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#define JSTATE_ANY 0x0
|
||||||
|
#define JSTATE_RUNNING 0x1
|
||||||
|
#define JSTATE_STOPPED 0x2
|
||||||
|
|
||||||
extern int job_control, interactive_shell;
|
extern int job_control, interactive_shell;
|
||||||
static int execute_list_with_replacements ();
|
static int execute_list_with_replacements ();
|
||||||
@@ -52,20 +66,24 @@ static int execute_list_with_replacements ();
|
|||||||
pid only. If `-n' is given, only processes that have changed
|
pid only. If `-n' is given, only processes that have changed
|
||||||
status since the last notification are printed. If -x is given,
|
status since the last notification are printed. If -x is given,
|
||||||
replace all job specs with the pid of the appropriate process
|
replace all job specs with the pid of the appropriate process
|
||||||
group leader and execute the command. */
|
group leader and execute the command. The -r and -s options mean
|
||||||
|
to print info about running and stopped jobs only, respectively. */
|
||||||
int
|
int
|
||||||
jobs_builtin (list)
|
jobs_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int form = JLIST_STANDARD, execute = 0;
|
int form, execute, state, opt, any_failed, job;
|
||||||
int opt;
|
sigset_t set, oset;
|
||||||
int any_failed = 0;
|
|
||||||
|
|
||||||
if (!job_control && !interactive_shell)
|
if (job_control == 0 && interactive_shell == 0)
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
|
|
||||||
|
execute = any_failed = 0;
|
||||||
|
form = JLIST_STANDARD;
|
||||||
|
state = JSTATE_ANY;
|
||||||
|
|
||||||
reset_internal_getopt ();
|
reset_internal_getopt ();
|
||||||
while ((opt = internal_getopt (list, "lpnx")) != -1)
|
while ((opt = internal_getopt (list, "lpnxrs")) != -1)
|
||||||
{
|
{
|
||||||
switch (opt)
|
switch (opt)
|
||||||
{
|
{
|
||||||
@@ -86,9 +104,15 @@ jobs_builtin (list)
|
|||||||
}
|
}
|
||||||
execute++;
|
execute++;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
state = JSTATE_RUNNING;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
state = JSTATE_STOPPED;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
builtin_error ("usage: jobs [-lpn [jobspec]] [-x command [args]]");
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,21 +124,29 @@ jobs_builtin (list)
|
|||||||
|
|
||||||
if (!list)
|
if (!list)
|
||||||
{
|
{
|
||||||
list_jobs (form);
|
switch (state)
|
||||||
|
{
|
||||||
|
case JSTATE_ANY:
|
||||||
|
list_all_jobs (form);
|
||||||
|
break;
|
||||||
|
case JSTATE_RUNNING:
|
||||||
|
list_running_jobs (form);
|
||||||
|
break;
|
||||||
|
case JSTATE_STOPPED:
|
||||||
|
list_stopped_jobs (form);
|
||||||
|
break;
|
||||||
|
}
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
int job;
|
|
||||||
sigset_t set, oset;
|
|
||||||
|
|
||||||
BLOCK_CHILD (set, oset);
|
BLOCK_CHILD (set, oset);
|
||||||
job = get_job_spec (list);
|
job = get_job_spec (list);
|
||||||
|
|
||||||
if ((job == NO_JOB) || !jobs || !jobs[job])
|
if ((job == NO_JOB) || !jobs || !jobs[job])
|
||||||
{
|
{
|
||||||
builtin_error ("No such job %s", list->word->word);
|
builtin_error ("no such job %s", list->word->word);
|
||||||
any_failed++;
|
any_failed++;
|
||||||
}
|
}
|
||||||
else if (job != DUP_JOB)
|
else if (job != DUP_JOB)
|
||||||
@@ -169,3 +201,62 @@ execute_list_with_replacements (list)
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
#endif /* JOB_CONTROL */
|
#endif /* JOB_CONTROL */
|
||||||
|
|
||||||
|
$BUILTIN disown
|
||||||
|
$FUNCTION disown_builtin
|
||||||
|
$DEPENDS_ON JOB_CONTROL
|
||||||
|
$SHORT_DOC disown [-h] [jobspec ...]
|
||||||
|
By default, removes each JOBSPEC argument from the table of active jobs.
|
||||||
|
If the -h option is given, the job is not removed from the table, but is
|
||||||
|
marked so that SIGHUP is not sent to the job if the shell receives a
|
||||||
|
SIGHUP.
|
||||||
|
$END
|
||||||
|
|
||||||
|
#if defined (JOB_CONTROL)
|
||||||
|
int
|
||||||
|
disown_builtin (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
int opt, job, retval, nohup_only;
|
||||||
|
sigset_t set, oset;
|
||||||
|
|
||||||
|
nohup_only = 0;
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "h")) != -1)
|
||||||
|
{
|
||||||
|
switch (opt)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
nohup_only = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
|
return (EX_USAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = loptend;
|
||||||
|
retval = EXECUTION_SUCCESS;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
BLOCK_CHILD (set, oset);
|
||||||
|
job = get_job_spec (list);
|
||||||
|
|
||||||
|
if (job == NO_JOB || jobs == 0 || jobs[job] == 0)
|
||||||
|
{
|
||||||
|
builtin_error ("no such job %s", list->word->word);
|
||||||
|
retval = EXECUTION_FAILURE;
|
||||||
|
}
|
||||||
|
else if (nohup_only)
|
||||||
|
nohup_job (job);
|
||||||
|
else
|
||||||
|
delete_job (job);
|
||||||
|
UNBLOCK_CHILD (oset);
|
||||||
|
|
||||||
|
if (list)
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
while (list);
|
||||||
|
return (retval);
|
||||||
|
}
|
||||||
|
#endif /* JOB_CONTROL */
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ $PRODUCES kill.c
|
|||||||
$BUILTIN kill
|
$BUILTIN kill
|
||||||
$FUNCTION kill_builtin
|
$FUNCTION kill_builtin
|
||||||
$DEPENDS_ON JOB_CONTROL
|
$DEPENDS_ON JOB_CONTROL
|
||||||
$SHORT_DOC kill [-s sigspec | -sigspec] [pid | job]... | -l [signum]
|
$SHORT_DOC kill [-s sigspec | -n signum | -sigspec] [pid | job]... or kill -l [sigspec]
|
||||||
Send the processes named by PID (or JOB) the signal SIGSPEC. If
|
Send the processes named by PID (or JOB) the signal SIGSPEC. If
|
||||||
SIGSPEC is not present, then SIGTERM is assumed. An argument of `-l'
|
SIGSPEC is not present, then SIGTERM is assumed. An argument of `-l'
|
||||||
lists the signal names; if arguments follow `-l' they are assumed to
|
lists the signal names; if arguments follow `-l' they are assumed to
|
||||||
@@ -34,17 +34,25 @@ process IDs, and, if you have reached the limit on processes that
|
|||||||
you can create, you don't have to start a process to kill another one.
|
you can create, you don't have to start a process to kill another one.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
|
#include <config.h>
|
||||||
#if !defined (errno)
|
|
||||||
extern int errno;
|
#include <stdio.h>
|
||||||
#endif /* !errno */
|
#include <errno.h>
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
#include "../bashtypes.h"
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../trap.h"
|
#include "../trap.h"
|
||||||
#include "../jobs.h"
|
#include "../jobs.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <errno.h>
|
|
||||||
|
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
|
||||||
|
#if !defined (errno)
|
||||||
|
extern int errno;
|
||||||
|
#endif /* !errno */
|
||||||
|
|
||||||
#if defined (JOB_CONTROL)
|
#if defined (JOB_CONTROL)
|
||||||
extern int interactive;
|
extern int interactive;
|
||||||
@@ -63,14 +71,17 @@ int
|
|||||||
kill_builtin (list)
|
kill_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int signal = SIGTERM;
|
int signal, any_succeeded, listing, saw_signal;
|
||||||
int any_succeeded = 0, listing = 0, saw_signal = 0;
|
char *sigspec, *word;
|
||||||
char *sigspec = "TERM", *word;
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
if (!list)
|
if (list == 0)
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
|
|
||||||
|
any_succeeded = listing = saw_signal = 0;
|
||||||
|
signal = SIGTERM;
|
||||||
|
sigspec = "TERM";
|
||||||
|
|
||||||
/* Process options. */
|
/* Process options. */
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
@@ -81,13 +92,13 @@ kill_builtin (list)
|
|||||||
listing++;
|
listing++;
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
else if (ISOPTION (word, 's'))
|
else if (ISOPTION (word, 's') || ISOPTION (word, 'n'))
|
||||||
{
|
{
|
||||||
list = list->next;
|
list = list->next;
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
sigspec = list->word->word;
|
sigspec = list->word->word;
|
||||||
if (sigspec[0] == '0' && !sigspec[1])
|
if (sigspec[0] == '0' && sigspec[1] == '\0')
|
||||||
signal = 0;
|
signal = 0;
|
||||||
else
|
else
|
||||||
signal = decode_signal (sigspec);
|
signal = decode_signal (sigspec);
|
||||||
@@ -95,7 +106,7 @@ kill_builtin (list)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
builtin_error ("-s requires an argument");
|
builtin_error ("%s requires an argument", word);
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,6 +115,11 @@ kill_builtin (list)
|
|||||||
list = list->next;
|
list = list->next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (ISOPTION (word, '?'))
|
||||||
|
{
|
||||||
|
builtin_usage ();
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
/* If this is a signal specification then process it. We only process
|
/* If this is a signal specification then process it. We only process
|
||||||
the first one seen; other arguments may signify process groups (e.g,
|
the first one seen; other arguments may signify process groups (e.g,
|
||||||
-num == process group num). */
|
-num == process group num). */
|
||||||
@@ -119,75 +135,7 @@ kill_builtin (list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (listing)
|
if (listing)
|
||||||
{
|
return (display_signal_list (list, 0));
|
||||||
if (!list)
|
|
||||||
{
|
|
||||||
register int i;
|
|
||||||
register int column = 0;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
for (i = 1; i < NSIG; i++)
|
|
||||||
{
|
|
||||||
name = signal_name (i);
|
|
||||||
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (posixly_correct)
|
|
||||||
printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf ("%2d) %s", i, name);
|
|
||||||
|
|
||||||
if (++column < 4)
|
|
||||||
printf ("\t");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf ("\n");
|
|
||||||
column = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (posixly_correct || column != 0)
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* List individual signal names. */
|
|
||||||
while (list)
|
|
||||||
{
|
|
||||||
int signum;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
if ((sscanf (list->word->word, "%d", &signum) != 1) ||
|
|
||||||
(signum <= 0))
|
|
||||||
{
|
|
||||||
list_error:
|
|
||||||
builtin_error ("bad signal number: %s", list->word->word);
|
|
||||||
list = list->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is specified by Posix.2 so that exit statuses can be
|
|
||||||
mapped into signal numbers. */
|
|
||||||
if (signum > 128)
|
|
||||||
signum -= 128;
|
|
||||||
|
|
||||||
if (signum >= NSIG)
|
|
||||||
goto list_error;
|
|
||||||
|
|
||||||
name = signal_name (signum);
|
|
||||||
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
|
|
||||||
{
|
|
||||||
list = list->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
printf ("%s\n", name);
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OK, we are killing processes. */
|
/* OK, we are killing processes. */
|
||||||
if (signal == NO_SIG)
|
if (signal == NO_SIG)
|
||||||
@@ -215,15 +163,11 @@ kill_builtin (list)
|
|||||||
}
|
}
|
||||||
else if (*list->word->word != '%')
|
else if (*list->word->word != '%')
|
||||||
{
|
{
|
||||||
builtin_error ("No such pid %s", list->word->word);
|
builtin_error ("%s: no such pid", list->word->word);
|
||||||
CONTINUE_OR_FAIL;
|
CONTINUE_OR_FAIL;
|
||||||
}
|
}
|
||||||
#if 1
|
|
||||||
else if (interactive)
|
else if (interactive)
|
||||||
/* Posix.2 says you can kill without job control active (4.32.4) */
|
/* Posix.2 says you can kill without job control active (4.32.4) */
|
||||||
#else
|
|
||||||
else if (job_control) /* can't kill jobs if not using job control */
|
|
||||||
#endif
|
|
||||||
{ /* Must be a job spec. Check it out. */
|
{ /* Must be a job spec. Check it out. */
|
||||||
int job;
|
int job;
|
||||||
sigset_t set, oset;
|
sigset_t set, oset;
|
||||||
@@ -234,7 +178,7 @@ kill_builtin (list)
|
|||||||
if (job < 0 || job >= job_slots || !jobs[job])
|
if (job < 0 || job >= job_slots || !jobs[job])
|
||||||
{
|
{
|
||||||
if (job != DUP_JOB)
|
if (job != DUP_JOB)
|
||||||
builtin_error ("No such job %s", list->word->word);
|
builtin_error ("%s: no such job", list->word->word);
|
||||||
UNBLOCK_CHILD (oset);
|
UNBLOCK_CHILD (oset);
|
||||||
CONTINUE_OR_FAIL;
|
CONTINUE_OR_FAIL;
|
||||||
}
|
}
|
||||||
@@ -243,10 +187,7 @@ kill_builtin (list)
|
|||||||
without job control, then its pgrp == shell_pgrp, so we have
|
without job control, then its pgrp == shell_pgrp, so we have
|
||||||
to be careful. We take the pid of the first job in the pipeline
|
to be careful. We take the pid of the first job in the pipeline
|
||||||
in that case. */
|
in that case. */
|
||||||
if (jobs[job]->flags & J_JOBCONTROL)
|
pid = IS_JOBCONTROL (job) ? jobs[job]->pgrp : jobs[job]->pipe->pid;
|
||||||
pid = jobs[job]->pgrp;
|
|
||||||
else
|
|
||||||
pid = jobs[job]->pipe->pid;
|
|
||||||
|
|
||||||
UNBLOCK_CHILD (oset);
|
UNBLOCK_CHILD (oset);
|
||||||
|
|
||||||
@@ -266,16 +207,13 @@ kill_builtin (list)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
builtin_error ("bad process specification `%s'", list->word->word);
|
builtin_error ("`%s' is not a pid or valid job spec", list->word->word);
|
||||||
CONTINUE_OR_FAIL;
|
CONTINUE_OR_FAIL;
|
||||||
}
|
}
|
||||||
continue_killing:
|
continue_killing:
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (any_succeeded)
|
return (any_succeeded ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
else
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
}
|
}
|
||||||
#endif /* JOB_CONTROL */
|
#endif /* JOB_CONTROL */
|
||||||
|
|||||||
@@ -29,13 +29,23 @@ by 0 is trapped and flagged as an error. The following list of
|
|||||||
operators is grouped into levels of equal-precedence operators.
|
operators is grouped into levels of equal-precedence operators.
|
||||||
The levels are listed in order of decreasing precedence.
|
The levels are listed in order of decreasing precedence.
|
||||||
|
|
||||||
- unary minus
|
-, + unary minus, plus
|
||||||
! logical NOT
|
!, ~ logical and bitwise negation
|
||||||
* / % multiplication, division, remainder
|
*, /, % multiplication, division, remainder
|
||||||
+ - addition, subtraction
|
+, - addition, subtraction
|
||||||
<= >= < > comparison
|
<<, >> left and right bitwise shifts
|
||||||
== != equality inequality
|
<=, >=, <, > comparison
|
||||||
= assignment
|
==, != equality, inequality
|
||||||
|
& bitwise AND
|
||||||
|
^ bitwise XOR
|
||||||
|
| bitwise OR
|
||||||
|
&& logical AND
|
||||||
|
|| logical OR
|
||||||
|
expr ? expr : expr
|
||||||
|
conditional expression
|
||||||
|
=, *=, /=, %=,
|
||||||
|
+=, -=, <<=, >>=,
|
||||||
|
&=, ^=, |= assignment
|
||||||
|
|
||||||
Shell variables are allowed as operands. The name of the variable
|
Shell variables are allowed as operands. The name of the variable
|
||||||
is replaced by its value (coerced to a long integer) within
|
is replaced by its value (coerced to a long integer) within
|
||||||
@@ -50,28 +60,49 @@ If the last ARG evaluates to 0, let returns 1; 0 is returned
|
|||||||
otherwise.
|
otherwise.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
/* Arithmetic LET function. */
|
/* Arithmetic LET function. */
|
||||||
|
int
|
||||||
let_builtin (list)
|
let_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
long ret = 0L;
|
long ret;
|
||||||
|
|
||||||
if (!list)
|
if (list == 0)
|
||||||
{
|
{
|
||||||
builtin_error ("argument (expression) expected");
|
builtin_error ("expression expected");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (list)
|
for (; list; list = list->next)
|
||||||
{
|
|
||||||
ret = evalexp (list->word->word);
|
ret = evalexp (list->word->word);
|
||||||
list = list->next;
|
|
||||||
|
return ((ret == 0L) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
exp_builtin (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
char *exp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
{
|
||||||
|
builtin_error ("expression expected");
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0L)
|
exp = string_list (list);
|
||||||
return (EXECUTION_FAILURE);
|
ret = evalexp (exp);
|
||||||
else
|
free (exp);
|
||||||
return (EXECUTION_SUCCESS);
|
return ((ret == 0L) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,12 @@ 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
|
with Bash; see the file COPYING. If not, write to the Free Software
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../bashansi.h"
|
#include "../bashansi.h"
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -50,6 +56,7 @@ extern char *strcpy ();
|
|||||||
|
|
||||||
/* Flag values that builtins can have. */
|
/* Flag values that builtins can have. */
|
||||||
#define BUILTIN_FLAG_SPECIAL 0x01
|
#define BUILTIN_FLAG_SPECIAL 0x01
|
||||||
|
#define BUILTIN_FLAG_ASSIGNMENT 0x02
|
||||||
|
|
||||||
/* If this stream descriptor is non-zero, then write
|
/* If this stream descriptor is non-zero, then write
|
||||||
texinfo documentation to it. */
|
texinfo documentation to it. */
|
||||||
@@ -115,12 +122,41 @@ char *special_builtins[] =
|
|||||||
"export", "readonly", "return", "set", "shift", "trap", "unset",
|
"export", "readonly", "return", "set", "shift", "trap", "unset",
|
||||||
(char *)NULL
|
(char *)NULL
|
||||||
};
|
};
|
||||||
static int is_special_builtin ();
|
|
||||||
|
|
||||||
|
/* The builtin commands that take assignment statements as arguments. */
|
||||||
|
char *assignment_builtins[] =
|
||||||
|
{
|
||||||
|
"alias", "declare", "export", "local", "readonly", "typeset",
|
||||||
|
(char *)NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Forward declarations. */
|
||||||
|
static int is_special_builtin ();
|
||||||
|
static int is_assignment_builtin ();
|
||||||
|
|
||||||
|
void extract_info ();
|
||||||
|
|
||||||
|
void file_error ();
|
||||||
|
void line_error ();
|
||||||
|
|
||||||
|
void write_file_headers ();
|
||||||
|
void write_file_footers ();
|
||||||
|
void write_ifdefs ();
|
||||||
|
void write_endifs ();
|
||||||
|
void write_documentation ();
|
||||||
|
void write_longdocs ();
|
||||||
|
void write_builtins ();
|
||||||
|
|
||||||
|
void free_defs ();
|
||||||
|
void add_documentation ();
|
||||||
|
|
||||||
|
void must_be_building ();
|
||||||
|
void remove_trailing_whitespace ();
|
||||||
|
|
||||||
/* For each file mentioned on the command line, process it and
|
/* For each file mentioned on the command line, process it and
|
||||||
write the information to STRUCTFILE and EXTERNFILE, while
|
write the information to STRUCTFILE and EXTERNFILE, while
|
||||||
creating the production file if neccessary. */
|
creating the production file if neccessary. */
|
||||||
|
int
|
||||||
main (argc, argv)
|
main (argc, argv)
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
@@ -305,6 +341,7 @@ copy_string_array (array)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add ELEMENT to ARRAY, growing the array if neccessary. */
|
/* Add ELEMENT to ARRAY, growing the array if neccessary. */
|
||||||
|
void
|
||||||
array_add (element, array)
|
array_add (element, array)
|
||||||
char *element;
|
char *element;
|
||||||
ARRAY *array;
|
ARRAY *array;
|
||||||
@@ -324,6 +361,7 @@ array_add (element, array)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Free an allocated array and data pointer. */
|
/* Free an allocated array and data pointer. */
|
||||||
|
void
|
||||||
array_free (array)
|
array_free (array)
|
||||||
ARRAY *array;
|
ARRAY *array;
|
||||||
{
|
{
|
||||||
@@ -397,6 +435,7 @@ int output_cpp_line_info = 0;
|
|||||||
target. After the file has been processed, write out the names of
|
target. After the file has been processed, write out the names of
|
||||||
builtins found in each $BUILTIN. Plain text found before the $PRODUCES
|
builtins found in each $BUILTIN. Plain text found before the $PRODUCES
|
||||||
is ignored, as is "$$ comment text". */
|
is ignored, as is "$$ comment text". */
|
||||||
|
void
|
||||||
extract_info (filename, structfile, externfile)
|
extract_info (filename, structfile, externfile)
|
||||||
char *filename;
|
char *filename;
|
||||||
FILE *structfile, *externfile;
|
FILE *structfile, *externfile;
|
||||||
@@ -548,6 +587,7 @@ free_builtin (builtin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Free all of the memory allocated to a DEF_FILE. */
|
/* Free all of the memory allocated to a DEF_FILE. */
|
||||||
|
void
|
||||||
free_defs (defs)
|
free_defs (defs)
|
||||||
DEF_FILE *defs;
|
DEF_FILE *defs;
|
||||||
{
|
{
|
||||||
@@ -592,6 +632,7 @@ strip_whitespace (string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove only the trailing whitespace from STRING. */
|
/* Remove only the trailing whitespace from STRING. */
|
||||||
|
void
|
||||||
remove_trailing_whitespace (string)
|
remove_trailing_whitespace (string)
|
||||||
char *string;
|
char *string;
|
||||||
{
|
{
|
||||||
@@ -625,6 +666,7 @@ get_arg (for_whom, defs, string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Error if not building a builtin. */
|
/* Error if not building a builtin. */
|
||||||
|
void
|
||||||
must_be_building (directive, defs)
|
must_be_building (directive, defs)
|
||||||
char *directive;
|
char *directive;
|
||||||
DEF_FILE *defs;
|
DEF_FILE *defs;
|
||||||
@@ -645,6 +687,7 @@ current_builtin (directive, defs)
|
|||||||
|
|
||||||
/* Add LINE to the long documentation for the current builtin.
|
/* Add LINE to the long documentation for the current builtin.
|
||||||
Ignore blank lines until the first non-blank line has been seen. */
|
Ignore blank lines until the first non-blank line has been seen. */
|
||||||
|
void
|
||||||
add_documentation (defs, line)
|
add_documentation (defs, line)
|
||||||
DEF_FILE *defs;
|
DEF_FILE *defs;
|
||||||
char *line;
|
char *line;
|
||||||
@@ -670,17 +713,19 @@ builtin_handler (self, defs, arg)
|
|||||||
char *self, *arg;
|
char *self, *arg;
|
||||||
DEF_FILE *defs;
|
DEF_FILE *defs;
|
||||||
{
|
{
|
||||||
|
BUILTIN_DESC *new;
|
||||||
|
char *name;
|
||||||
|
|
||||||
/* If we are already building a builtin, we cannot start a new one. */
|
/* If we are already building a builtin, we cannot start a new one. */
|
||||||
if (building_builtin)
|
if (building_builtin)
|
||||||
return (line_error (defs, "%s found before $END", self));
|
{
|
||||||
|
line_error (defs, "%s found before $END", self);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
output_cpp_line_info++;
|
output_cpp_line_info++;
|
||||||
|
|
||||||
/* Get the name of this builtin, and stick it in the array. */
|
/* Get the name of this builtin, and stick it in the array. */
|
||||||
{
|
|
||||||
BUILTIN_DESC *new;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
name = get_arg (self, defs, arg);
|
name = get_arg (self, defs, arg);
|
||||||
|
|
||||||
/* If this is the first builtin, create the array to hold them. */
|
/* If this is the first builtin, create the array to hold them. */
|
||||||
@@ -698,10 +743,12 @@ builtin_handler (self, defs, arg)
|
|||||||
|
|
||||||
if (is_special_builtin (name))
|
if (is_special_builtin (name))
|
||||||
new->flags |= BUILTIN_FLAG_SPECIAL;
|
new->flags |= BUILTIN_FLAG_SPECIAL;
|
||||||
|
if (is_assignment_builtin (name))
|
||||||
|
new->flags |= BUILTIN_FLAG_ASSIGNMENT;
|
||||||
|
|
||||||
array_add ((char *)new, defs->builtins);
|
array_add ((char *)new, defs->builtins);
|
||||||
building_builtin = 1;
|
building_builtin = 1;
|
||||||
}
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,6 +791,7 @@ docname_handler (self, defs, arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* How to handle the $SHORT_DOC directive. */
|
/* How to handle the $SHORT_DOC directive. */
|
||||||
|
int
|
||||||
short_doc_handler (self, defs, arg)
|
short_doc_handler (self, defs, arg)
|
||||||
char *self, *arg;
|
char *self, *arg;
|
||||||
DEF_FILE *defs;
|
DEF_FILE *defs;
|
||||||
@@ -762,13 +810,16 @@ short_doc_handler (self, defs, arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* How to handle the $COMMENT directive. */
|
/* How to handle the $COMMENT directive. */
|
||||||
|
int
|
||||||
comment_handler (self, defs)
|
comment_handler (self, defs)
|
||||||
char *self;
|
char *self;
|
||||||
DEF_FILE *defs;
|
DEF_FILE *defs;
|
||||||
{
|
{
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* How to handle the $DEPENDS_ON directive. */
|
/* How to handle the $DEPENDS_ON directive. */
|
||||||
|
int
|
||||||
depends_on_handler (self, defs, arg)
|
depends_on_handler (self, defs, arg)
|
||||||
char *self, *arg;
|
char *self, *arg;
|
||||||
DEF_FILE *defs;
|
DEF_FILE *defs;
|
||||||
@@ -788,6 +839,7 @@ depends_on_handler (self, defs, arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* How to handle the $PRODUCES directive. */
|
/* How to handle the $PRODUCES directive. */
|
||||||
|
int
|
||||||
produces_handler (self, defs, arg)
|
produces_handler (self, defs, arg)
|
||||||
char *self, *arg;
|
char *self, *arg;
|
||||||
DEF_FILE *defs;
|
DEF_FILE *defs;
|
||||||
@@ -820,12 +872,14 @@ produces_handler (self, defs, arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* How to handle the $END directive. */
|
/* How to handle the $END directive. */
|
||||||
|
int
|
||||||
end_handler (self, defs, arg)
|
end_handler (self, defs, arg)
|
||||||
char *self, *arg;
|
char *self, *arg;
|
||||||
DEF_FILE *defs;
|
DEF_FILE *defs;
|
||||||
{
|
{
|
||||||
must_be_building (self, defs);
|
must_be_building (self, defs);
|
||||||
building_builtin = 0;
|
building_builtin = 0;
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* **************************************************************** */
|
/* **************************************************************** */
|
||||||
@@ -835,6 +889,7 @@ end_handler (self, defs, arg)
|
|||||||
/* **************************************************************** */
|
/* **************************************************************** */
|
||||||
|
|
||||||
/* Produce an error for DEFS with FORMAT and ARGS. */
|
/* Produce an error for DEFS with FORMAT and ARGS. */
|
||||||
|
void
|
||||||
line_error (defs, format, arg1, arg2)
|
line_error (defs, format, arg1, arg2)
|
||||||
DEF_FILE *defs;
|
DEF_FILE *defs;
|
||||||
char *format, *arg1, *arg2;
|
char *format, *arg1, *arg2;
|
||||||
@@ -848,6 +903,7 @@ line_error (defs, format, arg1, arg2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Print error message for FILENAME. */
|
/* Print error message for FILENAME. */
|
||||||
|
void
|
||||||
file_error (filename)
|
file_error (filename)
|
||||||
char *filename;
|
char *filename;
|
||||||
{
|
{
|
||||||
@@ -895,7 +951,7 @@ xrealloc (pointer, bytes)
|
|||||||
static void
|
static void
|
||||||
memory_error_and_abort ()
|
memory_error_and_abort ()
|
||||||
{
|
{
|
||||||
fprintf (stderr, "mkbuiltins: Out of virtual memory!\n");
|
fprintf (stderr, "mkbuiltins: out of virtual memory\n");
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -929,6 +985,7 @@ copy_builtin (builtin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* How to save away a builtin. */
|
/* How to save away a builtin. */
|
||||||
|
void
|
||||||
save_builtin (builtin)
|
save_builtin (builtin)
|
||||||
BUILTIN_DESC *builtin;
|
BUILTIN_DESC *builtin;
|
||||||
{
|
{
|
||||||
@@ -972,7 +1029,7 @@ char *structfile_header[] = {
|
|||||||
" along with Bash; see the file COPYING. If not, write to the Free",
|
" along with Bash; see the file COPYING. If not, write to the Free",
|
||||||
" Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */",
|
" Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */",
|
||||||
"",
|
"",
|
||||||
"/* The list of shell builtins. Each element is name, function, enabled-p,",
|
"/* The list of shell builtins. Each element is name, function, flags,",
|
||||||
" long-doc, short-doc. The long-doc field contains a pointer to an array",
|
" long-doc, short-doc. The long-doc field contains a pointer to an array",
|
||||||
" of help lines. The function takes a WORD_LIST *; the first word in the",
|
" of help lines. The function takes a WORD_LIST *; the first word in the",
|
||||||
" list is the first arg to the command. The list has already had word",
|
" list is the first arg to the command. The list has already had word",
|
||||||
@@ -992,13 +1049,17 @@ char *structfile_footer[] = {
|
|||||||
" { (char *)0x0, (Function *)0x0, 0, (char **)0x0, (char *)0x0 }",
|
" { (char *)0x0, (Function *)0x0, 0, (char **)0x0, (char *)0x0 }",
|
||||||
"};",
|
"};",
|
||||||
"",
|
"",
|
||||||
|
"struct builtin *shell_builtins = static_shell_builtins;",
|
||||||
|
"struct builtin *current_builtin;",
|
||||||
|
"",
|
||||||
"int num_shell_builtins =",
|
"int num_shell_builtins =",
|
||||||
"\tsizeof (shell_builtins) / sizeof (struct builtin) - 1;",
|
"\tsizeof (static_shell_builtins) / sizeof (struct builtin) - 1;",
|
||||||
(char *)NULL
|
(char *)NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Write out any neccessary opening information for
|
/* Write out any neccessary opening information for
|
||||||
STRUCTFILE and EXTERNFILE. */
|
STRUCTFILE and EXTERNFILE. */
|
||||||
|
void
|
||||||
write_file_headers (structfile, externfile)
|
write_file_headers (structfile, externfile)
|
||||||
FILE *structfile, *externfile;
|
FILE *structfile, *externfile;
|
||||||
{
|
{
|
||||||
@@ -1011,7 +1072,7 @@ write_file_headers (structfile, externfile)
|
|||||||
|
|
||||||
fprintf (structfile, "#include \"%s\"\n",
|
fprintf (structfile, "#include \"%s\"\n",
|
||||||
extern_filename ? extern_filename : "builtext.h");
|
extern_filename ? extern_filename : "builtext.h");
|
||||||
fprintf (structfile, "\nstruct builtin shell_builtins[] = {\n");
|
fprintf (structfile, "\nstruct builtin static_shell_builtins[] = {\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (externfile)
|
if (externfile)
|
||||||
@@ -1022,6 +1083,7 @@ write_file_headers (structfile, externfile)
|
|||||||
|
|
||||||
/* Write out any necessary closing information for
|
/* Write out any necessary closing information for
|
||||||
STRUCTFILE and EXTERNFILE. */
|
STRUCTFILE and EXTERNFILE. */
|
||||||
|
void
|
||||||
write_file_footers (structfile, externfile)
|
write_file_footers (structfile, externfile)
|
||||||
FILE *structfile, *externfile;
|
FILE *structfile, *externfile;
|
||||||
{
|
{
|
||||||
@@ -1037,6 +1099,7 @@ write_file_footers (structfile, externfile)
|
|||||||
|
|
||||||
/* Write out the information accumulated in DEFS to
|
/* Write out the information accumulated in DEFS to
|
||||||
STRUCTFILE and EXTERNFILE. */
|
STRUCTFILE and EXTERNFILE. */
|
||||||
|
void
|
||||||
write_builtins (defs, structfile, externfile)
|
write_builtins (defs, structfile, externfile)
|
||||||
DEF_FILE *defs;
|
DEF_FILE *defs;
|
||||||
FILE *structfile, *externfile;
|
FILE *structfile, *externfile;
|
||||||
@@ -1057,7 +1120,6 @@ write_builtins (defs, structfile, externfile)
|
|||||||
{
|
{
|
||||||
if (builtin->dependencies)
|
if (builtin->dependencies)
|
||||||
{
|
{
|
||||||
if (builtin->function)
|
|
||||||
write_ifdefs (externfile, builtin->dependencies->array);
|
write_ifdefs (externfile, builtin->dependencies->array);
|
||||||
write_ifdefs (structfile, builtin->dependencies->array);
|
write_ifdefs (structfile, builtin->dependencies->array);
|
||||||
}
|
}
|
||||||
@@ -1083,20 +1145,14 @@ write_builtins (defs, structfile, externfile)
|
|||||||
else
|
else
|
||||||
fprintf (structfile, "(Function *)0x0, ");
|
fprintf (structfile, "(Function *)0x0, ");
|
||||||
|
|
||||||
#define SPECIAL_FLAG_STRING "BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN"
|
fprintf (structfile, "%s%s%s, %s_doc,\n",
|
||||||
#define NORMAL_FLAG_STRING "BUILTIN_ENABLED | STATIC_BUILTIN"
|
"BUILTIN_ENABLED | STATIC_BUILTIN",
|
||||||
|
(builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
|
||||||
fprintf (structfile, "%s, %s_doc,\n",
|
(builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
|
||||||
(builtin->flags & BUILTIN_FLAG_SPECIAL) ?
|
|
||||||
SPECIAL_FLAG_STRING :
|
|
||||||
NORMAL_FLAG_STRING,
|
|
||||||
builtin->docname ? builtin->docname : builtin->name);
|
builtin->docname ? builtin->docname : builtin->name);
|
||||||
|
|
||||||
#undef SPECIAL_FLAG_STRING
|
|
||||||
#undef NORMAL_FLAG_STRING
|
|
||||||
|
|
||||||
fprintf
|
fprintf
|
||||||
(structfile, " \"%s\" },\n",
|
(structfile, " \"%s\", (char *)NULL },\n",
|
||||||
builtin->shortdoc ? builtin->shortdoc : builtin->name);
|
builtin->shortdoc ? builtin->shortdoc : builtin->name);
|
||||||
|
|
||||||
/* Save away this builtin for later writing of the
|
/* Save away this builtin for later writing of the
|
||||||
@@ -1126,6 +1182,7 @@ write_builtins (defs, structfile, externfile)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write out the long documentation strings in BUILTINS to STREAM. */
|
/* Write out the long documentation strings in BUILTINS to STREAM. */
|
||||||
|
void
|
||||||
write_longdocs (stream, builtins)
|
write_longdocs (stream, builtins)
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
ARRAY *builtins;
|
ARRAY *builtins;
|
||||||
@@ -1157,6 +1214,7 @@ write_longdocs (stream, builtins)
|
|||||||
DEFINES is a null terminated array of define names.
|
DEFINES is a null terminated array of define names.
|
||||||
If a define is preceded by an `!', then the sense of the test is
|
If a define is preceded by an `!', then the sense of the test is
|
||||||
reversed. */
|
reversed. */
|
||||||
|
void
|
||||||
write_ifdefs (stream, defines)
|
write_ifdefs (stream, defines)
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
char **defines;
|
char **defines;
|
||||||
@@ -1187,6 +1245,7 @@ write_ifdefs (stream, defines)
|
|||||||
of the immediately preceding code.
|
of the immediately preceding code.
|
||||||
STREAM is the stream to write the information to.
|
STREAM is the stream to write the information to.
|
||||||
DEFINES is a null terminated array of define names. */
|
DEFINES is a null terminated array of define names. */
|
||||||
|
void
|
||||||
write_endifs (stream, defines)
|
write_endifs (stream, defines)
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
char **defines;
|
char **defines;
|
||||||
@@ -1211,6 +1270,7 @@ write_endifs (stream, defines)
|
|||||||
|
|
||||||
/* Write DOCUMENTAION to STREAM, perhaps surrounding it with double-quotes
|
/* Write DOCUMENTAION to STREAM, perhaps surrounding it with double-quotes
|
||||||
and quoting special characters in the string. */
|
and quoting special characters in the string. */
|
||||||
|
void
|
||||||
write_documentation (stream, documentation, indentation, flags)
|
write_documentation (stream, documentation, indentation, flags)
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
char **documentation;
|
char **documentation;
|
||||||
@@ -1218,14 +1278,14 @@ write_documentation (stream, documentation, indentation, flags)
|
|||||||
{
|
{
|
||||||
register int i, j;
|
register int i, j;
|
||||||
register char *line;
|
register char *line;
|
||||||
int string_array = (flags & STRING_ARRAY); /* Mutually exclusive. */
|
int string_array, texinfo;
|
||||||
int texinfo = (flags & TEXINFO);
|
|
||||||
|
|
||||||
if (!stream)
|
if (!stream)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
string_array = flags & STRING_ARRAY;
|
||||||
if (string_array)
|
if (string_array)
|
||||||
fprintf (stream, " {\n");
|
fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n");
|
||||||
|
|
||||||
#if !defined (OLDCODE)
|
#if !defined (OLDCODE)
|
||||||
/* XXX -- clean me up; for experiment only */
|
/* XXX -- clean me up; for experiment only */
|
||||||
@@ -1233,7 +1293,7 @@ write_documentation (stream, documentation, indentation, flags)
|
|||||||
goto end_of_document;
|
goto end_of_document;
|
||||||
#endif /* !OLDCODE */
|
#endif /* !OLDCODE */
|
||||||
|
|
||||||
for (i = 0; line = documentation[i]; i++)
|
for (i = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
|
||||||
{
|
{
|
||||||
/* Allow #ifdef's to be written out verbatim. */
|
/* Allow #ifdef's to be written out verbatim. */
|
||||||
if (*line == '#')
|
if (*line == '#')
|
||||||
@@ -1295,17 +1355,31 @@ end_of_document:
|
|||||||
#endif /* !OLDCODE */
|
#endif /* !OLDCODE */
|
||||||
|
|
||||||
if (string_array)
|
if (string_array)
|
||||||
fprintf (stream, " (char *)NULL\n};\n");
|
fprintf (stream, "#endif /* HELP_BUILTIN */\n (char *)NULL\n};\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_find_in_table (name, name_table)
|
||||||
|
char *name, *name_table[];
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
for (i = 0; name_table[i]; i++)
|
||||||
|
if (strcmp (name, name_table[i]) == 0)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
is_special_builtin (name)
|
is_special_builtin (name)
|
||||||
char *name;
|
char *name;
|
||||||
{
|
{
|
||||||
register int i;
|
return (_find_in_table (name, special_builtins));
|
||||||
|
}
|
||||||
for (i = 0; special_builtins[i]; i++)
|
|
||||||
if (strcmp (name, special_builtins[i]) == 0)
|
static int
|
||||||
return 1;
|
is_assignment_builtin (name)
|
||||||
return 0;
|
char *name;
|
||||||
|
{
|
||||||
|
return (_find_in_table (name, assignment_builtins));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@
|
|||||||
/* Write output in 128-byte chunks until we get a sigpipe or write gets an
|
/* Write output in 128-byte chunks until we get a sigpipe or write gets an
|
||||||
EPIPE. Then report how many bytes we wrote. We assume that this is the
|
EPIPE. Then report how many bytes we wrote. We assume that this is the
|
||||||
pipe size. */
|
pipe size. */
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -29,6 +34,7 @@
|
|||||||
|
|
||||||
#include "../command.h"
|
#include "../command.h"
|
||||||
#include "../general.h"
|
#include "../general.h"
|
||||||
|
#include "../sig.h"
|
||||||
extern int errno;
|
extern int errno;
|
||||||
|
|
||||||
int nw;
|
int nw;
|
||||||
|
|||||||
604
builtins/pushd.def
Normal file
604
builtins/pushd.def
Normal file
@@ -0,0 +1,604 @@
|
|||||||
|
This file is pushd.def, from which is created pushd.c. It implements the
|
||||||
|
builtins "pushd", "popd", and "dirs" in Bash.
|
||||||
|
|
||||||
|
Copyright (C) 1987, 1989, 1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
$PRODUCES pushd.c
|
||||||
|
|
||||||
|
$BUILTIN pushd
|
||||||
|
$FUNCTION pushd_builtin
|
||||||
|
$DEPENDS_ON PUSHD_AND_POPD
|
||||||
|
$SHORT_DOC pushd [dir | +N | -N] [-n]
|
||||||
|
Adds a directory to the top of the directory stack, or rotates
|
||||||
|
the stack, making the new top of the stack the current working
|
||||||
|
directory. With no arguments, exchanges the top two directories.
|
||||||
|
|
||||||
|
+N Rotates the stack so that the Nth directory (counting
|
||||||
|
from the left of the list shown by `dirs') is at the top.
|
||||||
|
|
||||||
|
-N Rotates the stack so that the Nth directory (counting
|
||||||
|
from the right) is at the top.
|
||||||
|
|
||||||
|
-n suppress the normal change of directory when adding directories
|
||||||
|
to the stack, so only the stack is manipulated.
|
||||||
|
|
||||||
|
dir adds DIR to the directory stack at the top, making it the
|
||||||
|
new current working directory.
|
||||||
|
|
||||||
|
You can see the directory stack with the `dirs' command.
|
||||||
|
$END
|
||||||
|
|
||||||
|
$BUILTIN popd
|
||||||
|
$FUNCTION popd_builtin
|
||||||
|
$DEPENDS_ON PUSHD_AND_POPD
|
||||||
|
$SHORT_DOC popd [+N | -N] [-n]
|
||||||
|
Removes entries from the directory stack. With no arguments,
|
||||||
|
removes the top directory from the stack, and cd's to the new
|
||||||
|
top directory.
|
||||||
|
|
||||||
|
+N removes the Nth entry counting from the left of the list
|
||||||
|
shown by `dirs', starting with zero. For example: `popd +0'
|
||||||
|
removes the first directory, `popd +1' the second.
|
||||||
|
|
||||||
|
-N removes the Nth entry counting from the right of the list
|
||||||
|
shown by `dirs', starting with zero. For example: `popd -0'
|
||||||
|
removes the last directory, `popd -1' the next to last.
|
||||||
|
|
||||||
|
-n suppress the normal change of directory when removing directories
|
||||||
|
from the stack, so only the stack is manipulated.
|
||||||
|
|
||||||
|
You can see the directory stack with the `dirs' command.
|
||||||
|
$END
|
||||||
|
|
||||||
|
$BUILTIN dirs
|
||||||
|
$FUNCTION dirs_builtin
|
||||||
|
$DEPENDS_ON PUSHD_AND_POPD
|
||||||
|
$SHORT_DOC dirs [-clpv] [+N] [-N]
|
||||||
|
Display the list of currently remembered directories. Directories
|
||||||
|
find their way onto the list with the `pushd' command; you can get
|
||||||
|
back up through the list with the `popd' command.
|
||||||
|
|
||||||
|
The -l flag specifies that `dirs' should not print shorthand versions
|
||||||
|
of directories which are relative to your home directory. This means
|
||||||
|
that `~/bin' might be displayed as `/homes/bfox/bin'. The -v flag
|
||||||
|
causes `dirs' to print the directory stack with one entry per line,
|
||||||
|
prepending the directory name with its position in the stack. The -p
|
||||||
|
flag does the same thing, but the stack position is not prepended.
|
||||||
|
The -c flag clears the directory stack by deleting all of the elements.
|
||||||
|
|
||||||
|
+N displays the Nth entry counting from the left of the list shown by
|
||||||
|
dirs when invoked without options, starting with zero.
|
||||||
|
|
||||||
|
-N displays the Nth entry counting from the right of the list shown by
|
||||||
|
dirs when invoked without options, starting with zero.
|
||||||
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (PUSHD_AND_POPD)
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <tilde/tilde.h>
|
||||||
|
|
||||||
|
#include "../shell.h"
|
||||||
|
#include "../maxpath.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "builtext.h"
|
||||||
|
|
||||||
|
#if !defined (errno)
|
||||||
|
extern int errno;
|
||||||
|
#endif /* !errno */
|
||||||
|
|
||||||
|
static char *m_badarg = "%s: bad argument";
|
||||||
|
|
||||||
|
/* The list of remembered directories. */
|
||||||
|
static char **pushd_directory_list = (char **)NULL;
|
||||||
|
|
||||||
|
/* Number of existing slots in this list. */
|
||||||
|
static int directory_list_size;
|
||||||
|
|
||||||
|
/* Offset to the end of the list. */
|
||||||
|
static int directory_list_offset;
|
||||||
|
|
||||||
|
static void pushd_error ();
|
||||||
|
static void clear_directory_stack ();
|
||||||
|
static int cd_to_string ();
|
||||||
|
static int change_to_temp ();
|
||||||
|
static int get_dirstack_index ();
|
||||||
|
static void add_dirstack_element ();
|
||||||
|
|
||||||
|
#define NOCD 0x01
|
||||||
|
#define ROTATE 0x02
|
||||||
|
#define LONGFORM 0x04
|
||||||
|
#define CLEARSTAK 0x08
|
||||||
|
|
||||||
|
int
|
||||||
|
pushd_builtin (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
char *temp, *current_directory, *top;
|
||||||
|
int j, flags;
|
||||||
|
long num;
|
||||||
|
char direction;
|
||||||
|
|
||||||
|
/* If there is no argument list then switch current and
|
||||||
|
top of list. */
|
||||||
|
if (list == 0)
|
||||||
|
{
|
||||||
|
if (directory_list_offset == 0)
|
||||||
|
{
|
||||||
|
builtin_error ("no other directory");
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_directory = get_working_directory ("pushd");
|
||||||
|
if (current_directory == 0)
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
|
||||||
|
j = directory_list_offset - 1;
|
||||||
|
temp = pushd_directory_list[j];
|
||||||
|
pushd_directory_list[j] = current_directory;
|
||||||
|
j = change_to_temp (temp);
|
||||||
|
free (temp);
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (flags = 0; list; list = list->next)
|
||||||
|
{
|
||||||
|
if (ISOPTION (list->word->word, 'n'))
|
||||||
|
{
|
||||||
|
flags |= NOCD;
|
||||||
|
}
|
||||||
|
else if (ISOPTION (list->word->word, '-'))
|
||||||
|
{
|
||||||
|
list = list->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
|
||||||
|
/* Let `pushd -' work like it used to. */
|
||||||
|
break;
|
||||||
|
else if (((direction = list->word->word[0]) == '+') || direction == '-')
|
||||||
|
{
|
||||||
|
if (legal_number (list->word->word + 1, &num) == 0)
|
||||||
|
{
|
||||||
|
builtin_error (m_badarg, list->word->word);
|
||||||
|
builtin_usage ();
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction == '-')
|
||||||
|
num = directory_list_offset - num;
|
||||||
|
|
||||||
|
if (num > directory_list_offset || num < 0)
|
||||||
|
{
|
||||||
|
pushd_error (directory_list_offset, list->word->word);
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
flags |= ROTATE;
|
||||||
|
}
|
||||||
|
else if (*list->word->word == '-')
|
||||||
|
{
|
||||||
|
bad_option (list->word->word);
|
||||||
|
builtin_usage ();
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & ROTATE)
|
||||||
|
{
|
||||||
|
/* Rotate the stack num times. Remember, the current
|
||||||
|
directory acts like it is part of the stack. */
|
||||||
|
temp = get_working_directory ("pushd");
|
||||||
|
|
||||||
|
if (num == 0)
|
||||||
|
{
|
||||||
|
j = ((flags & NOCD) == 0) ? change_to_temp (temp) : EXECUTION_SUCCESS;
|
||||||
|
free (temp);
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
top = pushd_directory_list[directory_list_offset - 1];
|
||||||
|
|
||||||
|
for (j = directory_list_offset - 2; j > -1; j--)
|
||||||
|
pushd_directory_list[j + 1] = pushd_directory_list[j];
|
||||||
|
|
||||||
|
pushd_directory_list[j + 1] = temp;
|
||||||
|
|
||||||
|
temp = top;
|
||||||
|
num--;
|
||||||
|
}
|
||||||
|
while (num);
|
||||||
|
|
||||||
|
j = ((flags & NOCD) == 0) ? change_to_temp (temp) : EXECUTION_SUCCESS;
|
||||||
|
free (temp);
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
|
||||||
|
/* Change to the directory in list->word->word. Save the current
|
||||||
|
directory on the top of the stack. */
|
||||||
|
current_directory = get_working_directory ("pushd");
|
||||||
|
if (current_directory == 0)
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
|
||||||
|
j = ((flags & NOCD) == 0) ? cd_builtin (list) : EXECUTION_SUCCESS;
|
||||||
|
if (j == EXECUTION_SUCCESS)
|
||||||
|
{
|
||||||
|
add_dirstack_element ((flags & NOCD) ? savestring (list->word->word) : current_directory);
|
||||||
|
dirs_builtin ((WORD_LIST *)NULL);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free (current_directory);
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pop the directory stack, and then change to the new top of the stack.
|
||||||
|
If LIST is non-null it should consist of a word +N or -N, which says
|
||||||
|
what element to delete from the stack. The default is the top one. */
|
||||||
|
int
|
||||||
|
popd_builtin (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
long which;
|
||||||
|
int flags;
|
||||||
|
char direction;
|
||||||
|
|
||||||
|
for (flags = 0, which = 0L, direction = '+'; list; list = list->next)
|
||||||
|
{
|
||||||
|
if (ISOPTION (list->word->word, 'n'))
|
||||||
|
{
|
||||||
|
flags |= NOCD;
|
||||||
|
}
|
||||||
|
else if (ISOPTION (list->word->word, '-'))
|
||||||
|
{
|
||||||
|
list = list->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (((direction = list->word->word[0]) == '+') || direction == '-')
|
||||||
|
{
|
||||||
|
if (legal_number (list->word->word + 1, &which) == 0)
|
||||||
|
{
|
||||||
|
builtin_error (m_badarg, list->word->word);
|
||||||
|
builtin_usage ();
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*list->word->word == '-')
|
||||||
|
{
|
||||||
|
bad_option (list->word->word);
|
||||||
|
builtin_usage ();
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (which > directory_list_offset || (directory_list_offset == 0 && which == 0))
|
||||||
|
{
|
||||||
|
pushd_error (directory_list_offset, list ? list->word->word : "");
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle case of no specification, or top of stack specification. */
|
||||||
|
if ((direction == '+' && which == 0) ||
|
||||||
|
(direction == '-' && which == directory_list_offset))
|
||||||
|
{
|
||||||
|
i = ((flags & NOCD) == 0) ? cd_to_string (pushd_directory_list[directory_list_offset - 1])
|
||||||
|
: EXECUTION_SUCCESS;
|
||||||
|
if (i != EXECUTION_SUCCESS)
|
||||||
|
return (i);
|
||||||
|
free (pushd_directory_list[--directory_list_offset]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Since an offset other than the top directory was specified,
|
||||||
|
remove that directory from the list and shift the remainder
|
||||||
|
of the list into place. */
|
||||||
|
i = (direction == '+') ? directory_list_offset - which : which;
|
||||||
|
free (pushd_directory_list[i]);
|
||||||
|
directory_list_offset--;
|
||||||
|
|
||||||
|
/* Shift the remainder of the list into place. */
|
||||||
|
for (; i < directory_list_offset; i++)
|
||||||
|
pushd_directory_list[i] = pushd_directory_list[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
dirs_builtin ((WORD_LIST *)NULL);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the current list of directories on the directory stack. */
|
||||||
|
int
|
||||||
|
dirs_builtin (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
int flags, desired_index, index_flag, vflag;
|
||||||
|
long i;
|
||||||
|
char *temp, *w;
|
||||||
|
|
||||||
|
for (flags = vflag = index_flag = 0, desired_index = -1, w = ""; list; list = list->next)
|
||||||
|
{
|
||||||
|
if (ISOPTION (list->word->word, 'l'))
|
||||||
|
{
|
||||||
|
flags |= LONGFORM;
|
||||||
|
}
|
||||||
|
else if (ISOPTION (list->word->word, 'c'))
|
||||||
|
{
|
||||||
|
flags |= CLEARSTAK;
|
||||||
|
}
|
||||||
|
else if (ISOPTION (list->word->word, 'v'))
|
||||||
|
{
|
||||||
|
vflag |= 2;
|
||||||
|
}
|
||||||
|
else if (ISOPTION (list->word->word, 'p'))
|
||||||
|
{
|
||||||
|
vflag |= 1;
|
||||||
|
}
|
||||||
|
else if (ISOPTION (list->word->word, '-'))
|
||||||
|
{
|
||||||
|
list = list->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (*list->word->word == '+' || *list->word->word == '-')
|
||||||
|
{
|
||||||
|
int sign;
|
||||||
|
if (legal_number (w = list->word->word + 1, &i) == 0)
|
||||||
|
{
|
||||||
|
builtin_error (m_badarg, list->word->word);
|
||||||
|
builtin_usage ();
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
sign = (*list->word->word == '+') ? 1 : -1;
|
||||||
|
desired_index = get_dirstack_index (i, sign, &index_flag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bad_option (list->word->word);
|
||||||
|
builtin_usage ();
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & CLEARSTAK)
|
||||||
|
{
|
||||||
|
clear_directory_stack ();
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index_flag && (desired_index < 0 || desired_index > directory_list_offset))
|
||||||
|
{
|
||||||
|
pushd_error (directory_list_offset, w);
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DIRSTACK_FORMAT(temp) \
|
||||||
|
(flags & LONGFORM) ? temp : polite_directory_format (temp)
|
||||||
|
|
||||||
|
/* The first directory printed is always the current working directory. */
|
||||||
|
if (index_flag == 0 || (index_flag == 1 && desired_index == 0))
|
||||||
|
{
|
||||||
|
temp = get_working_directory ("dirs");
|
||||||
|
if (temp == 0)
|
||||||
|
temp = savestring ("<no current directory>");
|
||||||
|
if (vflag & 2)
|
||||||
|
printf ("%2d %s", 0, DIRSTACK_FORMAT (temp));
|
||||||
|
else
|
||||||
|
printf ("%s", DIRSTACK_FORMAT (temp));
|
||||||
|
free (temp);
|
||||||
|
if (index_flag)
|
||||||
|
{
|
||||||
|
putchar ('\n');
|
||||||
|
return EXECUTION_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DIRSTACK_ENTRY(i) \
|
||||||
|
(flags & LONGFORM) ? pushd_directory_list[i] \
|
||||||
|
: polite_directory_format (pushd_directory_list[i])
|
||||||
|
|
||||||
|
/* Now print the requested directory stack entries. */
|
||||||
|
if (index_flag)
|
||||||
|
{
|
||||||
|
if (vflag & 2)
|
||||||
|
printf ("%2d %s", directory_list_offset - desired_index,
|
||||||
|
DIRSTACK_ENTRY (desired_index));
|
||||||
|
else
|
||||||
|
printf ("%s", DIRSTACK_ENTRY (desired_index));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (i = directory_list_offset - 1; i >= 0; i--)
|
||||||
|
if (vflag >= 2)
|
||||||
|
printf ("\n%2d %s", directory_list_offset - (int)i, DIRSTACK_ENTRY (i));
|
||||||
|
else
|
||||||
|
printf ("%s%s", (vflag & 1) ? "\n" : " ", DIRSTACK_ENTRY (i));
|
||||||
|
|
||||||
|
putchar ('\n');
|
||||||
|
fflush (stdout);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pushd_error (offset, arg)
|
||||||
|
int offset;
|
||||||
|
char *arg;
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
builtin_error ("directory stack empty");
|
||||||
|
else if (arg)
|
||||||
|
builtin_error ("%s: bad directory stack index", arg);
|
||||||
|
else
|
||||||
|
builtin_error ("bad directory stack index");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_directory_stack ()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
for (i = 0; i < directory_list_offset; i++)
|
||||||
|
free (pushd_directory_list[i]);
|
||||||
|
directory_list_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Switch to the directory in NAME. This uses the cd_builtin to do the work,
|
||||||
|
so if the result is EXECUTION_FAILURE then an error message has already
|
||||||
|
been printed. */
|
||||||
|
static int
|
||||||
|
cd_to_string (name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
WORD_LIST *tlist;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
tlist = make_word_list (make_word (name), NULL);
|
||||||
|
result = cd_builtin (tlist);
|
||||||
|
dispose_words (tlist);
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
change_to_temp (temp)
|
||||||
|
char *temp;
|
||||||
|
{
|
||||||
|
int tt;
|
||||||
|
|
||||||
|
tt = temp ? cd_to_string (temp) : EXECUTION_FAILURE;
|
||||||
|
|
||||||
|
if (tt == EXECUTION_SUCCESS)
|
||||||
|
dirs_builtin ((WORD_LIST *)NULL);
|
||||||
|
|
||||||
|
return (tt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_dirstack_element (dir)
|
||||||
|
char *dir;
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if (directory_list_offset == directory_list_size)
|
||||||
|
{
|
||||||
|
j = (directory_list_size += 10) * sizeof (char *);
|
||||||
|
pushd_directory_list = (char **)xrealloc (pushd_directory_list, j);
|
||||||
|
}
|
||||||
|
pushd_directory_list[directory_list_offset++] = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_dirstack_index (ind, sign, indexp)
|
||||||
|
int ind, sign, *indexp;
|
||||||
|
{
|
||||||
|
if (indexp)
|
||||||
|
*indexp = sign > 0 ? 1 : 2;
|
||||||
|
|
||||||
|
/* dirs +0 prints the current working directory. */
|
||||||
|
/* dirs -0 prints last element in directory stack */
|
||||||
|
if (ind == 0 && sign > 0)
|
||||||
|
return 0;
|
||||||
|
else if (ind == directory_list_offset)
|
||||||
|
{
|
||||||
|
if (indexp)
|
||||||
|
*indexp = sign > 0 ? 2 : 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return (sign > 0 ? directory_list_offset - ind : ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
get_dirstack_element (ind, sign)
|
||||||
|
int ind, sign;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = get_dirstack_index (ind, sign, (int *)NULL);
|
||||||
|
return (i < 0 || i > directory_list_offset) ? (char *)NULL
|
||||||
|
: pushd_directory_list[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_dirstack_element (ind, sign, value)
|
||||||
|
int ind, sign;
|
||||||
|
char *value;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = get_dirstack_index (ind, sign, (int *)NULL);
|
||||||
|
if (ind == 0 || i < 0 || i > directory_list_offset)
|
||||||
|
return;
|
||||||
|
free (pushd_directory_list[i]);
|
||||||
|
pushd_directory_list[i] = savestring (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
WORD_LIST *
|
||||||
|
get_directory_stack ()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
WORD_LIST *ret;
|
||||||
|
char *d, *t;
|
||||||
|
|
||||||
|
for (ret = (WORD_LIST *)NULL, i = 0; i < directory_list_offset; i++)
|
||||||
|
{
|
||||||
|
d = polite_directory_format (pushd_directory_list[i]);
|
||||||
|
ret = make_word_list (make_word (d), ret);
|
||||||
|
}
|
||||||
|
/* Now the current directory. */
|
||||||
|
d = get_working_directory ("dirstack");
|
||||||
|
i = 0; /* sentinel to decide whether or not to free d */
|
||||||
|
if (d == 0)
|
||||||
|
d = ".";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t = polite_directory_format (d);
|
||||||
|
/* polite_directory_format sometimes returns its argument unchanged.
|
||||||
|
If it does not, we can free d right away. If it does, we need to
|
||||||
|
mark d to be deleted later. */
|
||||||
|
if (t != d)
|
||||||
|
{
|
||||||
|
free (d);
|
||||||
|
d = t;
|
||||||
|
}
|
||||||
|
else /* t == d, so d is what we want */
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
ret = make_word_list (make_word (d), ret);
|
||||||
|
if (i)
|
||||||
|
free (d);
|
||||||
|
return ret; /* was (REVERSE_LIST (ret, (WORD_LIST *)); */
|
||||||
|
}
|
||||||
|
#endif /* PUSHD_AND_POPD */
|
||||||
@@ -23,101 +23,170 @@ $PRODUCES read.c
|
|||||||
|
|
||||||
$BUILTIN read
|
$BUILTIN read
|
||||||
$FUNCTION read_builtin
|
$FUNCTION read_builtin
|
||||||
$SHORT_DOC read [-r] [name ...]
|
$SHORT_DOC read [-r] [-p prompt] [-a array] [-e] [name ...]
|
||||||
One line is read from the standard input, and the first word is
|
One line is read from the standard input, and the first word is
|
||||||
assigned to the first NAME, the second word to the second NAME, etc.
|
assigned to the first NAME, the second word to the second NAME, and so
|
||||||
with leftover words assigned to the last NAME. Only the characters
|
on, with leftover words assigned to the last NAME. Only the characters
|
||||||
found in $IFS are recognized as word delimiters. The return code is
|
found in $IFS are recognized as word delimiters. The return code is
|
||||||
zero, unless end-of-file is encountered. If the -r option is given,
|
zero, unless end-of-file is encountered. If no NAMEs are supplied, the
|
||||||
this signifies `raw' input, and backslash processing is disabled.
|
line read is stored in the REPLY variable. If the -r option is given,
|
||||||
|
this signifies `raw' input, and backslash escaping is disabled. If
|
||||||
|
the `-p' option is supplied, the string supplied as an argument is
|
||||||
|
output without a trailing newline before attempting to read. If -a is
|
||||||
|
supplied, the words read are assigned to sequential indices of ARRAY,
|
||||||
|
starting at zero. If -e is supplied and the shell is interactive,
|
||||||
|
readline is used to obtain the line.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
#define issep(c) (strchr (ifs_chars, (c)) != (char *)0)
|
#if defined (READLINE)
|
||||||
|
#include "../bashline.h"
|
||||||
|
#include <readline/readline.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static int stream_close ();
|
#define issep(c) (strchr (ifs_chars, (c)))
|
||||||
|
|
||||||
extern int interrupt_immediately;
|
extern int interrupt_immediately;
|
||||||
|
|
||||||
|
#if defined (READLINE)
|
||||||
|
static char *edit_line ();
|
||||||
|
#endif
|
||||||
|
static SHELL_VAR *bind_read_variable ();
|
||||||
|
|
||||||
/* Read the value of the shell variables whose names follow.
|
/* Read the value of the shell variables whose names follow.
|
||||||
The reading is done from the current input stream, whatever
|
The reading is done from the current input stream, whatever
|
||||||
that may be. Successive words of the input line are assigned
|
that may be. Successive words of the input line are assigned
|
||||||
to the variables mentioned in LIST. The last variable in LIST
|
to the variables mentioned in LIST. The last variable in LIST
|
||||||
gets the remainder of the words on the line. If no variables
|
gets the remainder of the words on the line. If no variables
|
||||||
are mentioned in LIST, then the default variable is $REPLY.
|
are mentioned in LIST, then the default variable is $REPLY. */
|
||||||
|
int
|
||||||
S. R. Bourne's shell complains if you don't name a variable
|
|
||||||
to receive the stuff that is read. GNU's shell doesn't. This
|
|
||||||
allows you to let the user type random things. */
|
|
||||||
read_builtin (list)
|
read_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
register char *varname;
|
register char *varname;
|
||||||
int size, c, i, fildes, raw_mode, pass_next, saw_escape, retval;
|
int size, i, raw, pass_next, saw_escape, eof, opt, retval, edit;
|
||||||
char *input_string, *orig_input_string, *ifs_chars, *t;
|
char c;
|
||||||
FILE *input_stream;
|
char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
|
||||||
|
char *e, *t, *t1;
|
||||||
SHELL_VAR *var;
|
SHELL_VAR *var;
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
WORD_LIST *alist;
|
||||||
|
#endif
|
||||||
|
#if defined (READLINE)
|
||||||
|
char *rlbuf;
|
||||||
|
int rlind;
|
||||||
|
#endif
|
||||||
|
|
||||||
i = 0; /* Index into the string that we are reading. */
|
i = 0; /* Index into the string that we are reading. */
|
||||||
raw_mode = 0; /* Not reading raw input be default. */
|
raw = edit = 0; /* Not reading raw input by default. */
|
||||||
|
arrayname = prompt = (char *)NULL;
|
||||||
|
|
||||||
while (list)
|
#if defined (READLINE)
|
||||||
|
rlbuf = (char *)0;
|
||||||
|
rlind = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "erp:a:")) != -1)
|
||||||
{
|
{
|
||||||
if (ISOPTION (list->word->word, 'r'))
|
switch (opt)
|
||||||
{
|
{
|
||||||
raw_mode = 1;
|
case 'r':
|
||||||
list = list->next;
|
raw = 1;
|
||||||
}
|
|
||||||
else if (ISOPTION (list->word->word, '-'))
|
|
||||||
{
|
|
||||||
list = list->next;
|
|
||||||
break;
|
break;
|
||||||
}
|
case 'p':
|
||||||
else if (*list->word->word == '-')
|
prompt = list_optarg;
|
||||||
{
|
break;
|
||||||
bad_option (list->word->word);
|
case 'e':
|
||||||
builtin_error ("usage: read [-r] [name ...]");
|
#if defined (READLINE)
|
||||||
|
edit = 1;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
case 'a':
|
||||||
|
arrayname = list_optarg;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We need unbuffered input from stdin. So we make a new stream with
|
|
||||||
the same file descriptor as stdin, then unbuffer it. */
|
|
||||||
fildes = dup (fileno (stdin));
|
|
||||||
|
|
||||||
if (fildes == -1)
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
|
|
||||||
input_stream = fdopen (fildes, "r");
|
|
||||||
|
|
||||||
if (!input_stream)
|
|
||||||
{
|
|
||||||
close (fildes);
|
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
|
/* IF IFS is unset, we use the default of " \t\n". */
|
||||||
var = find_variable ("IFS");
|
var = find_variable ("IFS");
|
||||||
ifs_chars = var ? value_cell (var) : " \t\n";
|
ifs_chars = var ? value_cell (var) : " \t\n";
|
||||||
|
if (ifs_chars == 0) /* XXX */
|
||||||
|
ifs_chars = ""; /* XXX */
|
||||||
|
|
||||||
input_string = xmalloc (size = 128);
|
input_string = xmalloc (size = 128);
|
||||||
|
|
||||||
setbuf (input_stream, (char *)NULL);
|
|
||||||
|
|
||||||
begin_unwind_frame ("read_builtin");
|
begin_unwind_frame ("read_builtin");
|
||||||
add_unwind_protect (xfree, input_string);
|
add_unwind_protect (xfree, input_string);
|
||||||
add_unwind_protect (stream_close, input_stream);
|
#if defined (READLINE)
|
||||||
|
add_unwind_protect (xfree, rlbuf);
|
||||||
|
#endif
|
||||||
interrupt_immediately++;
|
interrupt_immediately++;
|
||||||
|
|
||||||
|
/* If the -p or -e flags were given, but input is not coming from the
|
||||||
|
terminal, turn them off. */
|
||||||
|
if ((prompt || edit) && (isatty (0) == 0))
|
||||||
|
{
|
||||||
|
prompt = (char *)NULL;
|
||||||
|
edit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prompt && edit == 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s", prompt);
|
||||||
|
fflush (stderr);
|
||||||
|
}
|
||||||
|
|
||||||
pass_next = 0; /* Non-zero signifies last char was backslash. */
|
pass_next = 0; /* Non-zero signifies last char was backslash. */
|
||||||
saw_escape = 0; /* Non-zero signifies that we saw an escape char */
|
saw_escape = 0; /* Non-zero signifies that we saw an escape char */
|
||||||
|
|
||||||
while ((c = getc (input_stream)) != EOF)
|
for (eof = 0;;)
|
||||||
{
|
{
|
||||||
|
#if defined (READLINE)
|
||||||
|
if (edit)
|
||||||
|
{
|
||||||
|
if (rlbuf && rlbuf[rlind] == '\0')
|
||||||
|
{
|
||||||
|
free (rlbuf);
|
||||||
|
rlbuf = (char *)0;
|
||||||
|
}
|
||||||
|
if (rlbuf == 0)
|
||||||
|
{
|
||||||
|
rlbuf = edit_line (prompt ? prompt : "");
|
||||||
|
rlind = 0;
|
||||||
|
}
|
||||||
|
if (rlbuf == 0)
|
||||||
|
{
|
||||||
|
eof = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c = rlbuf[rlind++];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (read (0, &c, 1) != 1)
|
||||||
|
{
|
||||||
|
eof = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (i + 2 >= size)
|
if (i + 2 >= size)
|
||||||
input_string = xrealloc (input_string, size += 128);
|
input_string = xrealloc (input_string, size += 128);
|
||||||
|
|
||||||
@@ -133,7 +202,7 @@ read_builtin (list)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == '\\' && !raw_mode)
|
if (c == '\\' && raw == 0)
|
||||||
{
|
{
|
||||||
pass_next++;
|
pass_next++;
|
||||||
saw_escape++;
|
saw_escape++;
|
||||||
@@ -157,15 +226,31 @@ read_builtin (list)
|
|||||||
interrupt_immediately--;
|
interrupt_immediately--;
|
||||||
discard_unwind_frame ("read_builtin");
|
discard_unwind_frame ("read_builtin");
|
||||||
|
|
||||||
fclose (input_stream);
|
retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
|
||||||
|
|
||||||
if (c == EOF)
|
#if defined (ARRAY_VARS)
|
||||||
|
/* If -a was given, take the string read, break it into a list of words,
|
||||||
|
an assign them to `arrayname' in turn. */
|
||||||
|
if (arrayname)
|
||||||
{
|
{
|
||||||
retval = EXECUTION_FAILURE;
|
var = find_variable (arrayname);
|
||||||
/* input_string[0] = '\0'; */
|
if (var == 0)
|
||||||
|
var = make_new_array_variable (arrayname);
|
||||||
|
else if (array_p (var) == 0)
|
||||||
|
var = convert_var_to_array (var);
|
||||||
|
|
||||||
|
empty_array (array_cell (var));
|
||||||
|
|
||||||
|
alist = list_string (input_string, ifs_chars, 0);
|
||||||
|
if (alist)
|
||||||
|
{
|
||||||
|
assign_array_var_from_word_list (var, alist);
|
||||||
|
dispose_words (alist);
|
||||||
}
|
}
|
||||||
else
|
free (input_string);
|
||||||
retval = EXECUTION_SUCCESS;
|
return (retval);
|
||||||
|
}
|
||||||
|
#endif /* ARRAY_VARS */
|
||||||
|
|
||||||
if (!list)
|
if (!list)
|
||||||
{
|
{
|
||||||
@@ -179,28 +264,29 @@ read_builtin (list)
|
|||||||
var = bind_variable ("REPLY", input_string);
|
var = bind_variable ("REPLY", input_string);
|
||||||
var->attributes &= ~att_invisible;
|
var->attributes &= ~att_invisible;
|
||||||
free (input_string);
|
free (input_string);
|
||||||
|
return (retval);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This code implements the Posix.2 spec for splitting the words
|
/* This code implements the Posix.2 spec for splitting the words
|
||||||
read and assigning them to variables. If $IFS is unset, we
|
read and assigning them to variables. */
|
||||||
use the default value of " \t\n". */
|
|
||||||
orig_input_string = input_string;
|
orig_input_string = input_string;
|
||||||
|
|
||||||
/* Remove IFS white space at the beginning of the input string. If
|
/* Remove IFS white space at the beginning of the input string. If
|
||||||
$IFS is null, no field splitting is performed. */
|
$IFS is null, no field splitting is performed. */
|
||||||
for (t = input_string; *ifs_chars && spctabnl (*t) && issep (*t); t++)
|
for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++)
|
||||||
;
|
;
|
||||||
input_string = t;
|
input_string = t;
|
||||||
|
|
||||||
for (; list->next; list = list->next)
|
for (; list->next; list = list->next)
|
||||||
{
|
{
|
||||||
char *e, *t1;
|
|
||||||
|
|
||||||
varname = list->word->word;
|
varname = list->word->word;
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
if (legal_identifier (varname) == 0 && valid_array_reference (varname) == 0)
|
||||||
|
#else
|
||||||
if (legal_identifier (varname) == 0)
|
if (legal_identifier (varname) == 0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
builtin_error ("%s: not a legal variable name", varname);
|
builtin_error ("`%s': not a valid identifier", varname);
|
||||||
free (orig_input_string);
|
free (orig_input_string);
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -218,28 +304,37 @@ read_builtin (list)
|
|||||||
if (t && saw_escape)
|
if (t && saw_escape)
|
||||||
{
|
{
|
||||||
t1 = dequote_string (t);
|
t1 = dequote_string (t);
|
||||||
var = bind_variable (varname, t1);
|
var = bind_read_variable (varname, t1);
|
||||||
free (t1);
|
free (t1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
var = bind_variable (varname, t);
|
var = bind_read_variable (varname, t);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
t = (char *)0;
|
t = (char *)0;
|
||||||
var = bind_variable (varname, "");
|
var = bind_read_variable (varname, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE (t);
|
||||||
|
if (var == 0)
|
||||||
|
{
|
||||||
|
free (orig_input_string);
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
stupidly_hack_special_variables (varname);
|
stupidly_hack_special_variables (varname);
|
||||||
var->attributes &= ~att_invisible;
|
var->attributes &= ~att_invisible;
|
||||||
|
|
||||||
if (t)
|
|
||||||
free (t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now assign the rest of the line to the last variable argument. */
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word) == 0)
|
||||||
|
#else
|
||||||
if (legal_identifier (list->word->word) == 0)
|
if (legal_identifier (list->word->word) == 0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
builtin_error ("%s: not a legal variable name", list->word->word);
|
builtin_error ("`%s': not a valid identifier", list->word->word);
|
||||||
free (orig_input_string);
|
free (orig_input_string);
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -247,30 +342,62 @@ read_builtin (list)
|
|||||||
/* This has to be done this way rather than using string_list
|
/* This has to be done this way rather than using string_list
|
||||||
and list_string because Posix.2 says that the last variable gets the
|
and list_string because Posix.2 says that the last variable gets the
|
||||||
remaining words and their intervening separators. */
|
remaining words and their intervening separators. */
|
||||||
input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars,
|
input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
|
||||||
saw_escape);
|
|
||||||
|
|
||||||
if (saw_escape)
|
if (saw_escape)
|
||||||
{
|
{
|
||||||
t = dequote_string (input_string);
|
t = dequote_string (input_string);
|
||||||
var = bind_variable (list->word->word, t);
|
var = bind_read_variable (list->word->word, t);
|
||||||
free (t);
|
free (t);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
var = bind_variable (list->word->word, input_string);
|
var = bind_read_variable (list->word->word, input_string);
|
||||||
stupidly_hack_special_variables (list->word->word);
|
stupidly_hack_special_variables (list->word->word);
|
||||||
|
if (var)
|
||||||
var->attributes &= ~att_invisible;
|
var->attributes &= ~att_invisible;
|
||||||
free (orig_input_string);
|
free (orig_input_string);
|
||||||
}
|
|
||||||
|
|
||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This way I don't have to know whether fclose () is a
|
static SHELL_VAR *
|
||||||
function or a macro. */
|
bind_read_variable (name, value)
|
||||||
static int
|
char *name, *value;
|
||||||
stream_close (file)
|
|
||||||
FILE *file;
|
|
||||||
{
|
{
|
||||||
return (fclose (file));
|
#if defined (ARRAY_VARS)
|
||||||
|
if (valid_array_reference (name) == 0)
|
||||||
|
{
|
||||||
|
if (legal_identifier (name) == 0)
|
||||||
|
{
|
||||||
|
builtin_error ("`%s': not a valid identifier", name);
|
||||||
|
return ((SHELL_VAR *)NULL);
|
||||||
|
}
|
||||||
|
return (bind_variable (name, value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return (do_array_element_assignment (name, value));
|
||||||
|
#else
|
||||||
|
return bind_variable (name, value);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined (READLINE)
|
||||||
|
static char *
|
||||||
|
edit_line (p)
|
||||||
|
char *p;
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!bash_readline_initialized)
|
||||||
|
initialize_readline ();
|
||||||
|
ret = readline (p);
|
||||||
|
if (ret == 0)
|
||||||
|
return ret;
|
||||||
|
len = strlen (ret);
|
||||||
|
ret = xrealloc (ret, len + 2);
|
||||||
|
ret[len++] = '\n';
|
||||||
|
ret[len] = '\0';
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -43,6 +43,15 @@ in the variable REPLY. COMMANDS are executed after each selection
|
|||||||
until a break or return command is executed.
|
until a break or return command is executed.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
$BUILTIN time
|
||||||
|
$SHORT_DOC time [-p] PIPELINE
|
||||||
|
Execute PIPELINE and print a summary of the real time, user CPU time,
|
||||||
|
and system CPU time spent executing PIPELINE when it terminates.
|
||||||
|
The return status is the return status of PIPELINE. The `-p' option
|
||||||
|
prints the timing summary in a slightly different format. This uses
|
||||||
|
the value of the TIMEFORMAT variable as the output format.
|
||||||
|
$END
|
||||||
|
|
||||||
$BUILTIN case
|
$BUILTIN case
|
||||||
$SHORT_DOC case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
|
$SHORT_DOC case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
|
||||||
Selectively execute COMMANDS based upon WORD matching PATTERN. The
|
Selectively execute COMMANDS based upon WORD matching PATTERN. The
|
||||||
@@ -97,10 +106,12 @@ $END
|
|||||||
$BUILTIN variables
|
$BUILTIN variables
|
||||||
$DOCNAME variable_help
|
$DOCNAME variable_help
|
||||||
$SHORT_DOC variables - Some variable names and meanings
|
$SHORT_DOC variables - Some variable names and meanings
|
||||||
BASH_VERSION The version numbers of this Bash.
|
BASH_VERSION Version information for this Bash.
|
||||||
CDPATH A colon separated list of directories to search
|
CDPATH A colon separated list of directories to search
|
||||||
when the argument to `cd' is not found in the current
|
when the argument to `cd' is not found in the current
|
||||||
directory.
|
directory.
|
||||||
|
GLOBIGNORE A colon-separated list of patterns describing filenames to
|
||||||
|
be ignored by pathname expansion.
|
||||||
#if defined (HISTORY)
|
#if defined (HISTORY)
|
||||||
HISTFILE The name of the file where your command history is stored.
|
HISTFILE The name of the file where your command history is stored.
|
||||||
HISTFILESIZE The maximum number of lines this file can contain.
|
HISTFILESIZE The maximum number of lines this file can contain.
|
||||||
@@ -108,22 +119,29 @@ HISTSIZE The maximum number of history lines that a running
|
|||||||
shell can access.
|
shell can access.
|
||||||
#endif /* HISTORY */
|
#endif /* HISTORY */
|
||||||
HOME The complete pathname to your login directory.
|
HOME The complete pathname to your login directory.
|
||||||
|
HOSTNAME The name of the current host.
|
||||||
HOSTTYPE The type of CPU this version of Bash is running under.
|
HOSTTYPE The type of CPU this version of Bash is running under.
|
||||||
IGNOREEOF Controls the action of the shell on receipt of an EOF
|
IGNOREEOF Controls the action of the shell on receipt of an EOF
|
||||||
character as the sole input. If set, then the value
|
character as the sole input. If set, then the value
|
||||||
of it is the number of EOF characters that can be seen
|
of it is the number of EOF characters that can be seen
|
||||||
in a row on an empty line before the shell will exit
|
in a row on an empty line before the shell will exit
|
||||||
(default 10). When unset, EOF signifies the end of input.
|
(default 10). When unset, EOF signifies the end of input.
|
||||||
|
MACHTYPE A string describing the current system Bash is running on.
|
||||||
MAILCHECK How often, in seconds, Bash checks for new mail.
|
MAILCHECK How often, in seconds, Bash checks for new mail.
|
||||||
MAILPATH A colon-separated list of filenames which Bash checks
|
MAILPATH A colon-separated list of filenames which Bash checks
|
||||||
for new mail.
|
for new mail.
|
||||||
|
OSTYPE The version of Unix this version of Bash is running on.
|
||||||
PATH A colon-separated list of directories to search when
|
PATH A colon-separated list of directories to search when
|
||||||
looking for commands.
|
looking for commands.
|
||||||
PROMPT_COMMAND A command to be executed before the printing of each
|
PROMPT_COMMAND A command to be executed before the printing of each
|
||||||
primary prompt.
|
primary prompt.
|
||||||
PS1 The primary prompt string.
|
PS1 The primary prompt string.
|
||||||
PS2 The secondary prompt string.
|
PS2 The secondary prompt string.
|
||||||
|
PWD The full pathname of the current directory.
|
||||||
|
SHELLOPTS A colon-separated list of enabled shell options.
|
||||||
TERM The name of the current terminal type.
|
TERM The name of the current terminal type.
|
||||||
|
TIMEFORMAT The output format for timing statistics displayed by the
|
||||||
|
`time' reserved word.
|
||||||
auto_resume Non-null means a command word appearing on a line by
|
auto_resume Non-null means a command word appearing on a line by
|
||||||
itself is first looked for in the list of currently
|
itself is first looked for in the list of currently
|
||||||
stopped jobs. If found there, that job is foregrounded.
|
stopped jobs. If found there, that job is foregrounded.
|
||||||
@@ -133,9 +151,6 @@ auto_resume Non-null means a command word appearing on a line by
|
|||||||
match a substring of the job. Any other value means that
|
match a substring of the job. Any other value means that
|
||||||
the command must be a prefix of a stopped job.
|
the command must be a prefix of a stopped job.
|
||||||
#if defined (HISTORY)
|
#if defined (HISTORY)
|
||||||
command_oriented_history
|
|
||||||
Non-null means to save multiple-line commands together on
|
|
||||||
a single history line.
|
|
||||||
# if defined (BANG_HISTORY)
|
# if defined (BANG_HISTORY)
|
||||||
histchars Characters controlling history expansion and quick
|
histchars Characters controlling history expansion and quick
|
||||||
substitution. The first character is the history
|
substitution. The first character is the history
|
||||||
@@ -143,12 +158,7 @@ histchars Characters controlling history expansion and quick
|
|||||||
the `quick substitution' character, usually `^'. The
|
the `quick substitution' character, usually `^'. The
|
||||||
third is the `history comment' character, usually `#'.
|
third is the `history comment' character, usually `#'.
|
||||||
# endif /* BANG_HISTORY */
|
# endif /* BANG_HISTORY */
|
||||||
HISTCONTROL Set to a value of `ignorespace', it means don't enter
|
HISTIGNORE A colon-separated list of patterns used to decide which
|
||||||
lines which begin with a space or tab on the history
|
command should be saved on the history list.
|
||||||
list. Set to a value of `ignoredups', it means don't
|
|
||||||
enter lines which match the last entered line. Set to
|
|
||||||
`ignoreboth' means to combine the two options. Unset,
|
|
||||||
or set to any other value than those above means to save
|
|
||||||
all lines on the history list.
|
|
||||||
#endif /* HISTORY */
|
#endif /* HISTORY */
|
||||||
$END
|
$END
|
||||||
|
|||||||
@@ -29,11 +29,17 @@ Causes a function to exit with the return value specified by N. If N
|
|||||||
is omitted, the return status is that of the last command.
|
is omitted, the return status is that of the last command.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
extern int last_command_exit_value;
|
extern int last_command_exit_value;
|
||||||
extern int return_catch_flag, return_catch_value;
|
extern int return_catch_flag, return_catch_value;
|
||||||
extern jmp_buf return_catch;
|
|
||||||
|
|
||||||
/* If we are executing a user-defined function then exit with the value
|
/* If we are executing a user-defined function then exit with the value
|
||||||
specified as an argument. if no argument is given, then the last
|
specified as an argument. if no argument is given, then the last
|
||||||
@@ -42,16 +48,13 @@ int
|
|||||||
return_builtin (list)
|
return_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
return_catch_value = get_numeric_arg (list);
|
return_catch_value = list ? get_numeric_arg (list) : last_command_exit_value;
|
||||||
|
|
||||||
if (!list)
|
|
||||||
return_catch_value = last_command_exit_value;
|
|
||||||
|
|
||||||
if (return_catch_flag)
|
if (return_catch_flag)
|
||||||
longjmp (return_catch, 1);
|
longjmp (return_catch, 1);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
builtin_error ("Can only `return' from a function");
|
builtin_error ("can only `return' from a function or sourced script");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
540
builtins/set.def
540
builtins/set.def
@@ -21,57 +21,74 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||||||
|
|
||||||
$PRODUCES set.c
|
$PRODUCES set.c
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../flags.h"
|
#include "../flags.h"
|
||||||
|
#include "common.h"
|
||||||
#include "bashgetopt.h"
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
|
#if defined (READLINE)
|
||||||
|
# include "../input.h"
|
||||||
|
# include "../bashline.h"
|
||||||
|
# include <readline/readline.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (HISTORY)
|
||||||
|
# include "../bashhist.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int interactive;
|
extern int interactive;
|
||||||
extern int noclobber, no_brace_expansion, posixly_correct;
|
extern int noclobber, posixly_correct, ignoreeof, eof_encountered_limit;
|
||||||
#if defined (READLINE)
|
#if defined (READLINE)
|
||||||
extern int rl_editing_mode, no_line_editing;
|
extern int rl_editing_mode, no_line_editing;
|
||||||
#endif /* READLINE */
|
#endif /* READLINE */
|
||||||
|
|
||||||
#define USAGE_STRING "set [--abefhknotuvxldHCP] [-o option] [arg ...]"
|
|
||||||
|
|
||||||
$BUILTIN set
|
$BUILTIN set
|
||||||
$FUNCTION set_builtin
|
$FUNCTION set_builtin
|
||||||
$SHORT_DOC set [--abefhknotuvxldHCP] [-o option] [arg ...]
|
$SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
|
||||||
-a Mark variables which are modified or created for export.
|
-a Mark variables which are modified or created for export.
|
||||||
-b Notify of job termination immediately.
|
-b Notify of job termination immediately.
|
||||||
-e Exit immediately if a command exits with a non-zero status.
|
-e Exit immediately if a command exits with a non-zero status.
|
||||||
-f Disable file name generation (globbing).
|
-f Disable file name generation (globbing).
|
||||||
-h Locate and remember function commands as functions are
|
-h Remember the location of commands as they are looked up.
|
||||||
defined. Function commands are normally looked up when
|
|
||||||
the function is executed.
|
|
||||||
-i Force the shell to be an "interactive" one. Interactive shells
|
-i Force the shell to be an "interactive" one. Interactive shells
|
||||||
always read `~/.bashrc' on startup.
|
always read `~/.bashrc' on startup.
|
||||||
-k All keyword arguments are placed in the environment for a
|
-k All assignment arguments are placed in the environment for a
|
||||||
command, not just those that precede the command name.
|
command, not just those that precede the command name.
|
||||||
-m Job control is enabled.
|
-m Job control is enabled.
|
||||||
-n Read commands but do not execute them.
|
-n Read commands but do not execute them.
|
||||||
-o option-name
|
-o option-name
|
||||||
Set the variable corresponding to option-name:
|
Set the variable corresponding to option-name:
|
||||||
allexport same as -a
|
allexport same as -a
|
||||||
braceexpand the shell will perform brace expansion
|
braceexpand same as -B
|
||||||
#if defined (READLINE)
|
#if defined (READLINE)
|
||||||
emacs use an emacs-style line editing interface
|
emacs use an emacs-style line editing interface
|
||||||
#endif /* READLINE */
|
#endif /* READLINE */
|
||||||
errexit same as -e
|
errexit same as -e
|
||||||
|
hashall same as -h
|
||||||
#if defined (BANG_HISTORY)
|
#if defined (BANG_HISTORY)
|
||||||
histexpand same as -H
|
histexpand same as -H
|
||||||
#endif /* BANG_HISTORY */
|
#endif /* BANG_HISTORY */
|
||||||
ignoreeof the shell will not exit upon reading EOF
|
ignoreeof the shell will not exit upon reading EOF
|
||||||
interactive-comments
|
interactive-comments
|
||||||
allow comments to appear in interactive commands
|
allow comments to appear in interactive commands
|
||||||
|
keyword same as -k
|
||||||
monitor same as -m
|
monitor same as -m
|
||||||
noclobber disallow redirection to existing files
|
noclobber same as -C
|
||||||
noexec same as -n
|
noexec same as -n
|
||||||
noglob same as -f
|
noglob same as -f
|
||||||
nohash same as -d
|
|
||||||
notify save as -b
|
notify save as -b
|
||||||
nounset same as -u
|
nounset same as -u
|
||||||
|
onecmd same as -t
|
||||||
physical same as -P
|
physical same as -P
|
||||||
posix change the behavior of bash where the default
|
posix change the behavior of bash where the default
|
||||||
operation differs from the 1003.2 standard to
|
operation differs from the 1003.2 standard to
|
||||||
@@ -90,10 +107,9 @@ $SHORT_DOC set [--abefhknotuvxldHCP] [-o option] [arg ...]
|
|||||||
-u Treat unset variables as an error when substituting.
|
-u Treat unset variables as an error when substituting.
|
||||||
-v Print shell input lines as they are read.
|
-v Print shell input lines as they are read.
|
||||||
-x Print commands and their arguments as they are executed.
|
-x Print commands and their arguments as they are executed.
|
||||||
-l Save and restore the binding of the NAME in a FOR command.
|
#if defined (BRACE_EXPANSION)
|
||||||
-d Disable the hashing of commands that are looked up for execution.
|
-B the shell will perform brace expansion
|
||||||
Normally, commands are remembered in a hash table, and once
|
#endif /* BRACE_EXPANSION */
|
||||||
found, do not have to be looked up again.
|
|
||||||
#if defined (BANG_HISTORY)
|
#if defined (BANG_HISTORY)
|
||||||
-H Enable ! style history substitution. This flag is on
|
-H Enable ! style history substitution. This flag is on
|
||||||
by default.
|
by default.
|
||||||
@@ -110,6 +126,20 @@ parameters and are assigned, in order, to $1, $2, .. $n. If no
|
|||||||
ARGs are given, all shell variables are printed.
|
ARGs are given, all shell variables are printed.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
static int set_ignoreeof ();
|
||||||
|
|
||||||
|
#if defined (READLINE)
|
||||||
|
static int set_edit_mode ();
|
||||||
|
static int get_edit_mode ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (HISTORY)
|
||||||
|
static int bash_set_history ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *on = "on";
|
||||||
|
static char *off = "off";
|
||||||
|
|
||||||
/* An a-list used to match long options for set -o to the corresponding
|
/* An a-list used to match long options for set -o to the corresponding
|
||||||
option letter. */
|
option letter. */
|
||||||
struct {
|
struct {
|
||||||
@@ -117,104 +147,151 @@ struct {
|
|||||||
int letter;
|
int letter;
|
||||||
} o_options[] = {
|
} o_options[] = {
|
||||||
{ "allexport", 'a' },
|
{ "allexport", 'a' },
|
||||||
|
#if defined (BRACE_EXPANSION)
|
||||||
|
{ "braceexpand",'B' },
|
||||||
|
#endif
|
||||||
{ "errexit", 'e' },
|
{ "errexit", 'e' },
|
||||||
|
{ "hashall", 'h' },
|
||||||
#if defined (BANG_HISTORY)
|
#if defined (BANG_HISTORY)
|
||||||
{ "histexpand", 'H' },
|
{ "histexpand", 'H' },
|
||||||
#endif /* BANG_HISTORY */
|
#endif /* BANG_HISTORY */
|
||||||
|
{ "keyword", 'k' },
|
||||||
{ "monitor", 'm' },
|
{ "monitor", 'm' },
|
||||||
|
{ "noclobber", 'C' },
|
||||||
{ "noexec", 'n' },
|
{ "noexec", 'n' },
|
||||||
{ "noglob", 'f' },
|
{ "noglob", 'f' },
|
||||||
{ "nohash", 'd' },
|
|
||||||
#if defined (JOB_CONTROL)
|
#if defined (JOB_CONTROL)
|
||||||
{ "notify", 'b' },
|
{ "notify", 'b' },
|
||||||
#endif /* JOB_CONTROL */
|
#endif /* JOB_CONTROL */
|
||||||
{"nounset", 'u' },
|
{ "nounset", 'u' },
|
||||||
{"physical", 'P' },
|
{ "onecmd", 't' },
|
||||||
{"privileged", 'p' },
|
{ "physical", 'P' },
|
||||||
{"verbose", 'v' },
|
{ "privileged", 'p' },
|
||||||
{"xtrace", 'x' },
|
{ "verbose", 'v' },
|
||||||
{(char *)NULL, 0},
|
{ "xtrace", 'x' },
|
||||||
|
{(char *)NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
char *name;
|
||||||
|
int *variable;
|
||||||
|
Function *set_func;
|
||||||
|
Function *get_func;
|
||||||
|
} binary_o_options[] = {
|
||||||
|
#if defined (HISTORY)
|
||||||
|
{ "history", &remember_on_history, bash_set_history, (Function *)NULL },
|
||||||
|
#endif
|
||||||
|
{ "ignoreeof", &ignoreeof, set_ignoreeof, (Function *)NULL },
|
||||||
|
{ "interactive-comments", &interactive_comments, (Function *)NULL, (Function *)NULL },
|
||||||
|
{ "posix", &posixly_correct, (Function *)NULL, (Function *)NULL },
|
||||||
|
#if defined (READLINE)
|
||||||
|
{ "emacs", (int *)NULL, set_edit_mode, get_edit_mode },
|
||||||
|
{ "vi", (int *)NULL, set_edit_mode, get_edit_mode },
|
||||||
|
#endif
|
||||||
|
{ (char *)NULL, (int *)NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GET_BINARY_O_OPTION_VALUE(i, name) \
|
||||||
|
((binary_o_options[i].get_func) ? (*binary_o_options[i].get_func) (name) \
|
||||||
|
: (*binary_o_options[i].variable))
|
||||||
|
|
||||||
|
#define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \
|
||||||
|
((binary_o_options[i].set_func) ? (*binary_o_options[i].set_func) (onoff, name) \
|
||||||
|
: (*binary_o_options[i].variable = (onoff == FLAG_ON)))
|
||||||
|
|
||||||
|
int
|
||||||
|
minus_o_option_value (name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
int *on_or_off;
|
||||||
|
|
||||||
|
for (i = 0; o_options[i].name; i++)
|
||||||
|
{
|
||||||
|
if (STREQ (name, o_options[i].name))
|
||||||
|
{
|
||||||
|
on_or_off = find_flag (o_options[i].letter);
|
||||||
|
return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; binary_o_options[i].name; i++)
|
||||||
|
{
|
||||||
|
if (STREQ (name, binary_o_options[i].name))
|
||||||
|
return (GET_BINARY_O_OPTION_VALUE (i, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
#define MINUS_O_FORMAT "%-15s\t%s\n"
|
#define MINUS_O_FORMAT "%-15s\t%s\n"
|
||||||
|
|
||||||
void
|
void
|
||||||
list_minus_o_opts ()
|
list_minus_o_opts (mode)
|
||||||
|
int mode;
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
char *on = "on", *off = "off";
|
int *on_or_off, value;
|
||||||
|
|
||||||
printf (MINUS_O_FORMAT, "braceexpand", (no_brace_expansion == 0) ? on : off);
|
for (value = i = 0; o_options[i].name; i++)
|
||||||
printf (MINUS_O_FORMAT, "noclobber", (noclobber == 1) ? on : off);
|
|
||||||
|
|
||||||
if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
|
|
||||||
printf (MINUS_O_FORMAT, "ignoreeof", on);
|
|
||||||
else
|
|
||||||
printf (MINUS_O_FORMAT, "ignoreeof", off);
|
|
||||||
|
|
||||||
printf (MINUS_O_FORMAT, "interactive-comments",
|
|
||||||
interactive_comments ? on : off);
|
|
||||||
|
|
||||||
printf (MINUS_O_FORMAT, "posix", posixly_correct ? on : off);
|
|
||||||
|
|
||||||
#if defined (READLINE)
|
|
||||||
if (no_line_editing)
|
|
||||||
{
|
{
|
||||||
printf (MINUS_O_FORMAT, "emacs", off);
|
|
||||||
printf (MINUS_O_FORMAT, "vi", off);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Magic. This code `knows' how readline handles rl_editing_mode. */
|
|
||||||
printf (MINUS_O_FORMAT, "emacs", (rl_editing_mode == 1) ? on : off);
|
|
||||||
printf (MINUS_O_FORMAT, "vi", (rl_editing_mode == 0) ? on : off);
|
|
||||||
}
|
|
||||||
#endif /* READLINE */
|
|
||||||
|
|
||||||
for (i = 0; o_options[i].name; i++)
|
|
||||||
{
|
|
||||||
int *on_or_off, zero = 0;
|
|
||||||
|
|
||||||
on_or_off = find_flag (o_options[i].letter);
|
on_or_off = find_flag (o_options[i].letter);
|
||||||
if (on_or_off == FLAG_UNKNOWN)
|
if (on_or_off == FLAG_UNKNOWN)
|
||||||
on_or_off = &zero;
|
on_or_off = &value;
|
||||||
printf (MINUS_O_FORMAT, o_options[i].name, (*on_or_off == 1) ? on : off);
|
if (mode == -1 || mode == *on_or_off)
|
||||||
|
printf (MINUS_O_FORMAT, o_options[i].name, *on_or_off ? on : off);
|
||||||
|
}
|
||||||
|
for (i = 0; binary_o_options[i].name; i++)
|
||||||
|
{
|
||||||
|
value = GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name);
|
||||||
|
if (mode == -1 || mode == value)
|
||||||
|
printf (MINUS_O_FORMAT, binary_o_options[i].name, value ? on : off);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_minus_o_option (on_or_off, option_name)
|
static void
|
||||||
|
minus_o_option_commands ()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
int *on_or_off, value;
|
||||||
|
|
||||||
|
for (value = i = 0; o_options[i].name; i++)
|
||||||
|
{
|
||||||
|
on_or_off = find_flag (o_options[i].letter);
|
||||||
|
if (on_or_off == FLAG_UNKNOWN)
|
||||||
|
on_or_off = &value;
|
||||||
|
printf ("set %co %s\n", *on_or_off ? '-' : '+', o_options[i].name);
|
||||||
|
}
|
||||||
|
for (i = 0; binary_o_options[i].name; i++)
|
||||||
|
{
|
||||||
|
value = GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name);
|
||||||
|
printf ("set %co %s\n", value ? '-' : '+', binary_o_options[i].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
set_ignoreeof (on_or_off, option_name)
|
||||||
int on_or_off;
|
int on_or_off;
|
||||||
char *option_name;
|
char *option_name;
|
||||||
{
|
{
|
||||||
int option_char = -1;
|
ignoreeof = on_or_off == FLAG_ON;
|
||||||
|
|
||||||
if (STREQ (option_name, "braceexpand"))
|
|
||||||
{
|
|
||||||
if (on_or_off == FLAG_ON)
|
|
||||||
no_brace_expansion = 0;
|
|
||||||
else
|
|
||||||
no_brace_expansion = 1;
|
|
||||||
}
|
|
||||||
else if (STREQ (option_name, "noclobber"))
|
|
||||||
{
|
|
||||||
if (on_or_off == FLAG_ON)
|
|
||||||
bind_variable ("noclobber", "");
|
|
||||||
else
|
|
||||||
unbind_variable ("noclobber");
|
|
||||||
stupidly_hack_special_variables ("noclobber");
|
|
||||||
}
|
|
||||||
else if (STREQ (option_name, "ignoreeof"))
|
|
||||||
{
|
|
||||||
unbind_variable ("ignoreeof");
|
unbind_variable ("ignoreeof");
|
||||||
unbind_variable ("IGNOREEOF");
|
if (ignoreeof)
|
||||||
if (on_or_off == FLAG_ON)
|
|
||||||
bind_variable ("IGNOREEOF", "10");
|
bind_variable ("IGNOREEOF", "10");
|
||||||
stupidly_hack_special_variables ("IGNOREEOF");
|
else
|
||||||
}
|
unbind_variable ("IGNOREEOF");
|
||||||
|
sv_ignoreeof ("IGNOREEOF");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined (READLINE)
|
#if defined (READLINE)
|
||||||
else if ((STREQ (option_name, "emacs")) || (STREQ (option_name, "vi")))
|
/* Magic. This code `knows' how readline handles rl_editing_mode. */
|
||||||
{
|
static int
|
||||||
|
set_edit_mode (on_or_off, option_name)
|
||||||
|
int on_or_off;
|
||||||
|
char *option_name;
|
||||||
|
{
|
||||||
|
int isemacs;
|
||||||
|
|
||||||
if (on_or_off == FLAG_ON)
|
if (on_or_off == FLAG_ON)
|
||||||
{
|
{
|
||||||
rl_variable_bind ("editing-mode", option_name);
|
rl_variable_bind ("editing-mode", option_name);
|
||||||
@@ -225,36 +302,63 @@ set_minus_o_option (on_or_off, option_name)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int isemacs = (rl_editing_mode == 1);
|
isemacs = rl_editing_mode == 1;
|
||||||
if ((isemacs && STREQ (option_name, "emacs")) ||
|
if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
|
||||||
(!isemacs && STREQ (option_name, "vi")))
|
|
||||||
{
|
{
|
||||||
if (interactive)
|
if (interactive)
|
||||||
with_input_from_stream (stdin, "stdin");
|
with_input_from_stream (stdin, "stdin");
|
||||||
no_line_editing = 1;
|
no_line_editing = 1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
builtin_error ("not in %s editing mode", option_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return 1-no_line_editing;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_edit_mode (name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
|
||||||
|
: no_line_editing == 0 && rl_editing_mode == 0);
|
||||||
|
}
|
||||||
#endif /* READLINE */
|
#endif /* READLINE */
|
||||||
else if (STREQ (option_name, "interactive-comments"))
|
|
||||||
interactive_comments = (on_or_off == FLAG_ON);
|
#if defined (HISTORY)
|
||||||
else if (STREQ (option_name, "posix"))
|
static int
|
||||||
{
|
bash_set_history (on_or_off, option_name)
|
||||||
posixly_correct = (on_or_off == FLAG_ON);
|
int on_or_off;
|
||||||
unbind_variable ("POSIXLY_CORRECT");
|
char *option_name;
|
||||||
unbind_variable ("POSIX_PEDANTIC");
|
{
|
||||||
if (on_or_off == FLAG_ON)
|
if (on_or_off == FLAG_ON)
|
||||||
{
|
{
|
||||||
bind_variable ("POSIXLY_CORRECT", "");
|
bash_history_enable ();
|
||||||
stupidly_hack_special_variables ("POSIXLY_CORRECT");
|
if (history_lines_this_session == 0)
|
||||||
}
|
load_history ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
bash_history_disable ();
|
||||||
|
return (1 - remember_on_history);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
set_minus_o_option (on_or_off, option_name)
|
||||||
|
int on_or_off;
|
||||||
|
char *option_name;
|
||||||
|
{
|
||||||
|
int option_char;
|
||||||
|
VFunction *set_func;
|
||||||
register int i;
|
register int i;
|
||||||
for (i = 0; o_options[i].name; i++)
|
|
||||||
|
for (i = 0; binary_o_options[i].name; i++)
|
||||||
|
{
|
||||||
|
if (STREQ (option_name, binary_o_options[i].name))
|
||||||
|
{
|
||||||
|
SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, option_char = -1, set_func = 0; o_options[i].name; i++)
|
||||||
{
|
{
|
||||||
if (STREQ (option_name, o_options[i].name))
|
if (STREQ (option_name, o_options[i].name))
|
||||||
{
|
{
|
||||||
@@ -272,20 +376,12 @@ set_minus_o_option (on_or_off, option_name)
|
|||||||
bad_option (option_name);
|
bad_option (option_name);
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set some flags from the word values in the input list. If LIST is empty,
|
static void
|
||||||
then print out the values of the variables instead. If LIST contains
|
print_all_shell_variables ()
|
||||||
non-flags, then set $1 - $9 to the successive words of LIST. */
|
|
||||||
set_builtin (list)
|
|
||||||
WORD_LIST *list;
|
|
||||||
{
|
{
|
||||||
int on_or_off, flag_name, force_assignment = 0;
|
|
||||||
|
|
||||||
if (!list)
|
|
||||||
{
|
|
||||||
SHELL_VAR **vars;
|
SHELL_VAR **vars;
|
||||||
|
|
||||||
vars = all_shell_variables ();
|
vars = all_shell_variables ();
|
||||||
@@ -301,17 +397,104 @@ set_builtin (list)
|
|||||||
print_var_list (vars);
|
print_var_list (vars);
|
||||||
free (vars);
|
free (vars);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_shellopts ()
|
||||||
|
{
|
||||||
|
char *value;
|
||||||
|
int vsize, i, vptr, *ip;
|
||||||
|
SHELL_VAR *v;
|
||||||
|
|
||||||
|
for (vsize = i = 0; o_options[i].name; i++)
|
||||||
|
{
|
||||||
|
ip = find_flag (o_options[i].letter);
|
||||||
|
if (ip && *ip)
|
||||||
|
vsize += strlen (o_options[i].name) + 1;
|
||||||
|
}
|
||||||
|
for (i = 0; binary_o_options[i].name; i++)
|
||||||
|
if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
|
||||||
|
vsize += strlen (binary_o_options[i].name) + 1;
|
||||||
|
|
||||||
|
value = xmalloc (vsize + 1);
|
||||||
|
|
||||||
|
for (i = vptr = 0; o_options[i].name; i++)
|
||||||
|
{
|
||||||
|
ip = find_flag (o_options[i].letter);
|
||||||
|
if (ip && *ip)
|
||||||
|
{
|
||||||
|
strcpy (value + vptr, o_options[i].name);
|
||||||
|
vptr += strlen (o_options[i].name);
|
||||||
|
value[vptr++] = ':';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; binary_o_options[i].name; i++)
|
||||||
|
if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
|
||||||
|
{
|
||||||
|
strcpy (value + vptr, binary_o_options[i].name);
|
||||||
|
vptr += strlen (binary_o_options[i].name);
|
||||||
|
value[vptr++] = ':';
|
||||||
|
}
|
||||||
|
value[--vptr] = '\0'; /* cut off trailing colon */
|
||||||
|
|
||||||
|
v = find_variable ("SHELLOPTS");
|
||||||
|
if (v)
|
||||||
|
v->attributes &= ~att_readonly;
|
||||||
|
v = bind_variable ("SHELLOPTS", value);
|
||||||
|
v->attributes |= att_readonly;
|
||||||
|
|
||||||
|
free (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_shellopts (value)
|
||||||
|
char *value;
|
||||||
|
{
|
||||||
|
char *vname;
|
||||||
|
int vptr;
|
||||||
|
|
||||||
|
vptr = 0;
|
||||||
|
while (vname = extract_colon_unit (value, &vptr))
|
||||||
|
{
|
||||||
|
set_minus_o_option (FLAG_ON, vname);
|
||||||
|
free (vname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initialize_shell_options ()
|
||||||
|
{
|
||||||
|
char *temp;
|
||||||
|
|
||||||
|
/* set up any shell options we may have inherited. */
|
||||||
|
if (temp = get_string_value ("SHELLOPTS"))
|
||||||
|
parse_shellopts (temp);
|
||||||
|
|
||||||
|
/* Set up the $SHELLOPTS variable. */
|
||||||
|
set_shellopts ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set some flags from the word values in the input list. If LIST is empty,
|
||||||
|
then print out the values of the variables instead. If LIST contains
|
||||||
|
non-flags, then set $1 - $9 to the successive words of LIST. */
|
||||||
|
int
|
||||||
|
set_builtin (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
int on_or_off, flag_name, force_assignment, opts_changed;
|
||||||
|
WORD_LIST *l;
|
||||||
|
register char *arg;
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
{
|
||||||
|
print_all_shell_variables ();
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check validity of flag arguments. */
|
/* Check validity of flag arguments. */
|
||||||
if (*list->word->word == '-' || *list->word->word == '+')
|
if (*list->word->word == '-' || *list->word->word == '+')
|
||||||
{
|
{
|
||||||
register char *arg;
|
for (l = list; l && (arg = l->word->word); l = l->next)
|
||||||
WORD_LIST *save_list = list;
|
|
||||||
|
|
||||||
while (list && (arg = list->word->word))
|
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
@@ -319,8 +502,7 @@ set_builtin (list)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* `-' or `--' signifies end of flag arguments. */
|
/* `-' or `--' signifies end of flag arguments. */
|
||||||
if (arg[0] == '-' &&
|
if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
|
||||||
(!arg[1] || (arg[1] == '-' && !arg[2])))
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
while (c = *++arg)
|
while (c = *++arg)
|
||||||
@@ -331,30 +513,28 @@ set_builtin (list)
|
|||||||
s[0] = c; s[1] = '\0';
|
s[0] = c; s[1] = '\0';
|
||||||
bad_option (s);
|
bad_option (s);
|
||||||
if (c == '?')
|
if (c == '?')
|
||||||
printf ("usage: %s\n", USAGE_STRING);
|
builtin_usage ();
|
||||||
return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list = list->next;
|
|
||||||
}
|
}
|
||||||
list = save_list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the set command. While the list consists of words starting with
|
/* Do the set command. While the list consists of words starting with
|
||||||
'-' or '+' treat them as flags, otherwise, start assigning them to
|
'-' or '+' treat them as flags, otherwise, start assigning them to
|
||||||
$1 ... $n. */
|
$1 ... $n. */
|
||||||
while (list)
|
for (force_assignment = opts_changed = 0; list; )
|
||||||
{
|
{
|
||||||
char *string = list->word->word;
|
arg = list->word->word;
|
||||||
|
|
||||||
/* If the argument is `--' or `-' then signal the end of the list
|
/* If the argument is `--' or `-' then signal the end of the list
|
||||||
and remember the remaining arguments. */
|
and remember the remaining arguments. */
|
||||||
if (string[0] == '-' && (!string[1] || (string[1] == '-' && !string[2])))
|
if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
|
||||||
{
|
{
|
||||||
list = list->next;
|
list = list->next;
|
||||||
|
|
||||||
/* `set --' unsets the positional parameters. */
|
/* `set --' unsets the positional parameters. */
|
||||||
if (string[1] == '-')
|
if (arg[1] == '-')
|
||||||
force_assignment = 1;
|
force_assignment = 1;
|
||||||
|
|
||||||
/* Until told differently, the old shell behaviour of
|
/* Until told differently, the old shell behaviour of
|
||||||
@@ -364,20 +544,19 @@ set_builtin (list)
|
|||||||
{
|
{
|
||||||
change_flag ('x', '+');
|
change_flag ('x', '+');
|
||||||
change_flag ('v', '+');
|
change_flag ('v', '+');
|
||||||
|
opts_changed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((on_or_off = *string) &&
|
if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
|
||||||
(on_or_off == '-' || on_or_off == '+'))
|
|
||||||
{
|
{
|
||||||
int i = 1;
|
while (flag_name = *++arg)
|
||||||
while (flag_name = string[i++])
|
|
||||||
{
|
{
|
||||||
if (flag_name == '?')
|
if (flag_name == '?')
|
||||||
{
|
{
|
||||||
printf ("usage: %s\n", USAGE_STRING);
|
builtin_usage ();
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
else if (flag_name == 'o') /* -+o option-name */
|
else if (flag_name == 'o') /* -+o option-name */
|
||||||
@@ -387,36 +566,47 @@ set_builtin (list)
|
|||||||
|
|
||||||
opt = list->next;
|
opt = list->next;
|
||||||
|
|
||||||
if (!opt)
|
if (opt == 0)
|
||||||
{
|
{
|
||||||
list_minus_o_opts ();
|
if (on_or_off == '-')
|
||||||
|
list_minus_o_opts (-1);
|
||||||
|
else
|
||||||
|
minus_o_option_commands ();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
option_name = opt->word->word;
|
option_name = opt->word->word;
|
||||||
|
|
||||||
if (!option_name || !*option_name || (*option_name == '-'))
|
if (option_name == 0 || *option_name == '\0' ||
|
||||||
|
*option_name == '-' || *option_name == '+')
|
||||||
{
|
{
|
||||||
list_minus_o_opts ();
|
if (on_or_off == '-')
|
||||||
|
list_minus_o_opts (-1);
|
||||||
|
else
|
||||||
|
minus_o_option_commands ();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
list = list->next; /* Skip over option name. */
|
list = list->next; /* Skip over option name. */
|
||||||
|
|
||||||
|
opts_changed = 1;
|
||||||
if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
|
if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
|
||||||
|
{
|
||||||
|
set_shellopts ();
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
|
||||||
if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
|
|
||||||
{
|
{
|
||||||
char opt[3];
|
char opt[3];
|
||||||
opt[0] = on_or_off;
|
opt[0] = on_or_off;
|
||||||
opt[1] = flag_name;
|
opt[1] = flag_name;
|
||||||
opt[2] = '\0';
|
opt[2] = '\0';
|
||||||
bad_option (opt);
|
bad_option (opt);
|
||||||
|
builtin_usage ();
|
||||||
|
set_shellopts ();
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
opts_changed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -429,6 +619,9 @@ set_builtin (list)
|
|||||||
/* Assigning $1 ... $n */
|
/* Assigning $1 ... $n */
|
||||||
if (list || force_assignment)
|
if (list || force_assignment)
|
||||||
remember_args (list, 1);
|
remember_args (list, 1);
|
||||||
|
/* Set up new value of $SHELLOPTS */
|
||||||
|
if (opts_changed)
|
||||||
|
set_shellopts ();
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,13 +636,17 @@ function. Some variables (such as PATH and IFS) cannot be unset; also
|
|||||||
see readonly.
|
see readonly.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#define NEXT_VARIABLE() any_failed++; list = list->next; continue;
|
||||||
|
|
||||||
|
int
|
||||||
unset_builtin (list)
|
unset_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int unset_function = 0, unset_variable = 0, opt;
|
int unset_function, unset_variable, unset_array, opt, any_failed;
|
||||||
int any_failed = 0;
|
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
unset_function = unset_variable = unset_array = any_failed = 0;
|
||||||
|
|
||||||
reset_internal_getopt ();
|
reset_internal_getopt ();
|
||||||
while ((opt = internal_getopt (list, "fv")) != -1)
|
while ((opt = internal_getopt (list, "fv")) != -1)
|
||||||
{
|
{
|
||||||
@@ -462,7 +659,8 @@ unset_builtin (list)
|
|||||||
unset_variable = 1;
|
unset_variable = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (EXECUTION_FAILURE);
|
builtin_usage ();
|
||||||
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,54 +673,70 @@ unset_builtin (list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (list)
|
while (list)
|
||||||
{
|
|
||||||
name = list->word->word;
|
|
||||||
|
|
||||||
if (!unset_function &&
|
|
||||||
find_name_in_list (name, non_unsettable_vars) > -1)
|
|
||||||
{
|
|
||||||
builtin_error ("%s: cannot unset", name);
|
|
||||||
any_failed++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
SHELL_VAR *var;
|
SHELL_VAR *var;
|
||||||
int tem;
|
int tem;
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
char *t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
name = list->word->word;
|
||||||
|
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
if (!unset_function && valid_array_reference (name))
|
||||||
|
{
|
||||||
|
t = strchr (name, '[');
|
||||||
|
*t++ = '\0';
|
||||||
|
unset_array++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
var = unset_function ? find_function (name) : find_variable (name);
|
var = unset_function ? find_function (name) : find_variable (name);
|
||||||
|
|
||||||
|
if (var && !unset_function && non_unsettable_p (var))
|
||||||
|
{
|
||||||
|
builtin_error ("%s: cannot unset", name);
|
||||||
|
NEXT_VARIABLE ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Posix.2 says that unsetting readonly variables is an error. */
|
/* Posix.2 says that unsetting readonly variables is an error. */
|
||||||
if (var && readonly_p (var))
|
if (var && readonly_p (var))
|
||||||
{
|
{
|
||||||
builtin_error ("%s: cannot unset: readonly %s",
|
builtin_error ("%s: cannot unset: readonly %s",
|
||||||
name, unset_function ? "function" : "variable");
|
name, unset_function ? "function" : "variable");
|
||||||
any_failed++;
|
NEXT_VARIABLE ();
|
||||||
list = list->next;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unless the -f option is supplied, the name refers to a
|
/* Unless the -f option is supplied, the name refers to a variable. */
|
||||||
variable. */
|
#if defined (ARRAY_VARS)
|
||||||
tem = makunbound
|
if (var && unset_array)
|
||||||
(name, unset_function ? shell_functions : shell_variables);
|
{
|
||||||
|
if (array_p (var) == 0)
|
||||||
|
{
|
||||||
|
builtin_error ("%s: not an array variable", name);
|
||||||
|
NEXT_VARIABLE ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tem = unbind_array_element (var, t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* ARRAY_VARS */
|
||||||
|
tem = makunbound (name, unset_function ? shell_functions : shell_variables);
|
||||||
|
|
||||||
/* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
|
/* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
|
||||||
is specified, the name refers to a variable; if a variable by
|
is specified, the name refers to a variable; if a variable by
|
||||||
that name does not exist, a function by that name, if any,
|
that name does not exist, a function by that name, if any,
|
||||||
shall be unset.'' */
|
shall be unset.'' */
|
||||||
if ((tem == -1) && !unset_function && !unset_variable)
|
if (tem == -1 && !unset_function && !unset_variable)
|
||||||
tem = makunbound (name, shell_functions);
|
tem = makunbound (name, shell_functions);
|
||||||
|
|
||||||
if (tem == -1)
|
if (tem == -1)
|
||||||
any_failed++;
|
any_failed++;
|
||||||
else if (!unset_function)
|
else if (!unset_function)
|
||||||
stupidly_hack_special_variables (name);
|
stupidly_hack_special_variables (name);
|
||||||
}
|
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (any_failed)
|
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
||||||
return (EXECUTION_FAILURE);
|
|
||||||
else
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,15 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||||||
|
|
||||||
$PRODUCES setattr.c
|
$PRODUCES setattr.c
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "bashgetopt.h"
|
#include "bashgetopt.h"
|
||||||
@@ -30,7 +39,7 @@ extern char *this_command_name;
|
|||||||
|
|
||||||
$BUILTIN export
|
$BUILTIN export
|
||||||
$FUNCTION export_builtin
|
$FUNCTION export_builtin
|
||||||
$SHORT_DOC export [-n] [-f] [name ...] or export -p
|
$SHORT_DOC export [-nf] [name ...] or export -p
|
||||||
NAMEs are marked for automatic export to the environment of
|
NAMEs are marked for automatic export to the environment of
|
||||||
subsequently executed commands. If the -f option is given,
|
subsequently executed commands. If the -f option is given,
|
||||||
the NAMEs refer to functions. If no NAMEs are given, or if `-p'
|
the NAMEs refer to functions. If no NAMEs are given, or if `-p'
|
||||||
@@ -45,46 +54,51 @@ $END
|
|||||||
print all such variables. An argument of `-n' says to remove the
|
print all such variables. An argument of `-n' says to remove the
|
||||||
exported attribute from variables named in LIST. An argument of
|
exported attribute from variables named in LIST. An argument of
|
||||||
-f indicates that the names present in LIST refer to functions. */
|
-f indicates that the names present in LIST refer to functions. */
|
||||||
|
int
|
||||||
export_builtin (list)
|
export_builtin (list)
|
||||||
register WORD_LIST *list;
|
register WORD_LIST *list;
|
||||||
{
|
{
|
||||||
return (set_or_show_attributes (list, att_exported));
|
return (set_or_show_attributes (list, att_exported, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
$BUILTIN readonly
|
$BUILTIN readonly
|
||||||
$FUNCTION readonly_builtin
|
$FUNCTION readonly_builtin
|
||||||
$SHORT_DOC readonly [-n] [-f] [name ...] or readonly -p
|
$SHORT_DOC readonly [-anf] [name ...] or readonly -p
|
||||||
The given NAMEs are marked readonly and the values of these NAMEs may
|
The given NAMEs are marked readonly and the values of these NAMEs may
|
||||||
not be changed by subsequent assignment. If the -f option is given,
|
not be changed by subsequent assignment. If the -f option is given,
|
||||||
then functions corresponding to the NAMEs are so marked. If no
|
then functions corresponding to the NAMEs are so marked. If no
|
||||||
arguments are given, or if `-p' is given, a list of all readonly names
|
arguments are given, or if `-p' is given, a list of all readonly names
|
||||||
is printed. An argument of `-n' says to remove the readonly property
|
is printed. An argument of `-n' says to remove the readonly property
|
||||||
from subsequent NAMEs. An argument of `--' disables further option
|
from subsequent NAMEs. The `-a' option means to treat each NAME as
|
||||||
|
an array variable. An argument of `--' disables further option
|
||||||
processing.
|
processing.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
/* For each variable name in LIST, make that variable readonly. Given an
|
/* For each variable name in LIST, make that variable readonly. Given an
|
||||||
empty LIST, print out all existing readonly variables. */
|
empty LIST, print out all existing readonly variables. */
|
||||||
|
int
|
||||||
readonly_builtin (list)
|
readonly_builtin (list)
|
||||||
register WORD_LIST *list;
|
register WORD_LIST *list;
|
||||||
{
|
{
|
||||||
return (set_or_show_attributes (list, att_readonly));
|
return (set_or_show_attributes (list, att_readonly, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For each variable name in LIST, make that variable have the specified
|
/* For each variable name in LIST, make that variable have the specified
|
||||||
ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
|
ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
|
||||||
remaining names in LIST. */
|
remaining names in LIST. */
|
||||||
int
|
int
|
||||||
set_or_show_attributes (list, attribute)
|
set_or_show_attributes (list, attribute, nodefs)
|
||||||
register WORD_LIST *list;
|
register WORD_LIST *list;
|
||||||
int attribute;
|
int attribute, nodefs;
|
||||||
{
|
{
|
||||||
register SHELL_VAR *var;
|
register SHELL_VAR *var;
|
||||||
int assign, undo = 0, functions_only = 0, any_failed = 0, opt;
|
int assign, undo, functions_only, arrays_only, any_failed, assign_error, opt;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
undo = functions_only = arrays_only = any_failed = assign_error = 0;
|
||||||
/* Read arguments from the front of the list. */
|
/* Read arguments from the front of the list. */
|
||||||
reset_internal_getopt ();
|
reset_internal_getopt ();
|
||||||
while ((opt = internal_getopt (list, "nfp")) != -1)
|
while ((opt = internal_getopt (list, "anfp")) != -1)
|
||||||
{
|
{
|
||||||
switch (opt)
|
switch (opt)
|
||||||
{
|
{
|
||||||
@@ -94,10 +108,15 @@ set_or_show_attributes (list, attribute)
|
|||||||
case 'f':
|
case 'f':
|
||||||
functions_only = 1;
|
functions_only = 1;
|
||||||
break;
|
break;
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
case 'a':
|
||||||
|
arrays_only = 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case 'p':
|
case 'p':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
builtin_error ("usage: %s [-nfp] [varname]", this_command_name);
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,85 +127,56 @@ set_or_show_attributes (list, attribute)
|
|||||||
if (attribute & att_exported)
|
if (attribute & att_exported)
|
||||||
array_needs_making = 1;
|
array_needs_making = 1;
|
||||||
|
|
||||||
/* Cannot undo readonly status. */
|
/* Cannot undo readonly status, silently disallowed. */
|
||||||
if (undo && (attribute & att_readonly))
|
if (undo && (attribute & att_readonly))
|
||||||
attribute &= ~att_readonly;
|
attribute &= ~att_readonly;
|
||||||
|
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
register char *name = list->word->word;
|
name = list->word->word;
|
||||||
|
|
||||||
if (functions_only)
|
if (functions_only) /* xxx -f name */
|
||||||
{
|
{
|
||||||
var = find_function (name);
|
var = find_function (name);
|
||||||
if (!var)
|
if (var == 0)
|
||||||
{
|
{
|
||||||
builtin_error ("%s: not a function", name);
|
builtin_error ("%s: not a function", name);
|
||||||
any_failed++;
|
any_failed++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
SETVARATTR (var, attribute, undo);
|
||||||
if (undo)
|
|
||||||
var->attributes &= ~attribute;
|
|
||||||
else
|
|
||||||
var->attributes |= attribute;
|
|
||||||
}
|
|
||||||
list = list->next;
|
list = list->next;
|
||||||
if (attribute == att_exported)
|
|
||||||
array_needs_making++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* xxx [-np] name[=value] */
|
||||||
assign = assignment (name);
|
assign = assignment (name);
|
||||||
|
|
||||||
if (assign)
|
if (assign)
|
||||||
name[assign] = '\0';
|
name[assign] = '\0';
|
||||||
|
|
||||||
if (legal_identifier (name) == 0)
|
if (legal_identifier (name) == 0)
|
||||||
{
|
{
|
||||||
builtin_error ("%s: not a legal variable name", name);
|
builtin_error ("`%s': not a valid identifier", name);
|
||||||
any_failed++;
|
assign_error++;
|
||||||
list = list->next;
|
list = list->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (assign)
|
if (assign) /* xxx [-np] name=value */
|
||||||
{
|
{
|
||||||
name[assign] = '=';
|
name[assign] = '=';
|
||||||
/* This word has already been expanded once with command
|
/* This word has already been expanded once with command
|
||||||
and parameter expansion. Call do_assignment_no_expand (),
|
and parameter expansion. Call do_assignment_no_expand (),
|
||||||
which does not do command or parameter substitution. */
|
which does not do command or parameter substitution. If
|
||||||
do_assignment_no_expand (name);
|
the assignment is not performed correctly, flag an error. */
|
||||||
|
if (do_assignment_no_expand (name) == 0)
|
||||||
|
assign_error++;
|
||||||
name[assign] = '\0';
|
name[assign] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (undo)
|
set_var_attribute (name, attribute, undo);
|
||||||
{
|
|
||||||
var = find_variable (name);
|
|
||||||
if (var)
|
|
||||||
var->attributes &= ~attribute;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SHELL_VAR *find_tempenv_variable (), *tv;
|
|
||||||
|
|
||||||
if (tv = find_tempenv_variable (name))
|
|
||||||
{
|
|
||||||
var = bind_variable (tv->name, tv->value);
|
|
||||||
dispose_variable (tv);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
var = find_variable (name);
|
|
||||||
|
|
||||||
if (!var)
|
|
||||||
{
|
|
||||||
var = bind_variable (name, (char *)NULL);
|
|
||||||
var->attributes |= att_invisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
var->attributes |= attribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
array_needs_making++; /* XXX */
|
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,50 +194,133 @@ set_or_show_attributes (list, attribute)
|
|||||||
else
|
else
|
||||||
variable_list = all_shell_variables ();
|
variable_list = all_shell_variables ();
|
||||||
|
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
if (attribute & att_array)
|
||||||
|
{
|
||||||
|
arrays_only++;
|
||||||
|
if (attribute != att_array)
|
||||||
|
attribute &= ~att_array;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (variable_list)
|
if (variable_list)
|
||||||
{
|
{
|
||||||
for (i = 0; var = variable_list[i]; i++)
|
for (i = 0; var = variable_list[i]; i++)
|
||||||
{
|
{
|
||||||
if ((var->attributes & attribute) && !invisible_p (var))
|
#if defined (ARRAY_VARS)
|
||||||
{
|
if (arrays_only && array_p (var) == 0)
|
||||||
char flags[6];
|
continue;
|
||||||
|
#endif
|
||||||
flags[0] = '\0';
|
if ((var->attributes & attribute) && invisible_p (var) == 0)
|
||||||
|
show_var_attributes (var, nodefs);
|
||||||
if (exported_p (var))
|
|
||||||
strcat (flags, "x");
|
|
||||||
|
|
||||||
if (readonly_p (var))
|
|
||||||
strcat (flags, "r");
|
|
||||||
|
|
||||||
if (function_p (var))
|
|
||||||
strcat (flags, "f");
|
|
||||||
|
|
||||||
if (integer_p (var))
|
|
||||||
strcat (flags, "i");
|
|
||||||
|
|
||||||
if (flags[0])
|
|
||||||
{
|
|
||||||
printf ("declare -%s ", flags);
|
|
||||||
|
|
||||||
if (!function_p (var))
|
|
||||||
{
|
|
||||||
char *x = double_quote (value_cell (var));
|
|
||||||
printf ("%s=%s\n", var->name, x);
|
|
||||||
free (x);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char *named_function_string ();
|
|
||||||
|
|
||||||
printf ("%s\n", named_function_string
|
|
||||||
(var->name, function_cell (var), 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
free (variable_list);
|
free (variable_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
|
||||||
|
return (assign_error ? EX_BADASSIGN
|
||||||
|
: ((any_failed == 0) ? EXECUTION_SUCCESS
|
||||||
|
: EXECUTION_FAILURE));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
show_var_attributes (var, nodefs)
|
||||||
|
SHELL_VAR *var;
|
||||||
|
int nodefs;
|
||||||
|
{
|
||||||
|
char flags[6], *x;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
if (array_p (var))
|
||||||
|
flags[i++] = 'a';
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (function_p (var))
|
||||||
|
flags[i++] = 'f';
|
||||||
|
|
||||||
|
if (integer_p (var))
|
||||||
|
flags[i++] = 'i';
|
||||||
|
|
||||||
|
if (readonly_p (var))
|
||||||
|
flags[i++] = 'r';
|
||||||
|
|
||||||
|
if (exported_p (var))
|
||||||
|
flags[i++] = 'x';
|
||||||
|
|
||||||
|
flags[i] = '\0';
|
||||||
|
|
||||||
|
printf ("declare -%s ", i ? flags : "-");
|
||||||
|
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
if (array_p (var))
|
||||||
|
print_array_assignment (var, 1);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (nodefs)
|
||||||
|
printf ("%s\n", var->name);
|
||||||
|
else if (function_p (var))
|
||||||
|
printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x = double_quote (value_cell (var));
|
||||||
|
printf ("%s=%s\n", var->name, x);
|
||||||
|
free (x);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
show_name_attributes (name, nodefs)
|
||||||
|
char *name;
|
||||||
|
int nodefs;
|
||||||
|
{
|
||||||
|
SHELL_VAR *var;
|
||||||
|
|
||||||
|
var = find_tempenv_variable (name);
|
||||||
|
if (var == 0)
|
||||||
|
var = find_variable (name);
|
||||||
|
|
||||||
|
if (var && invisible_p (var) == 0)
|
||||||
|
{
|
||||||
|
show_var_attributes (var, nodefs);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_var_attribute (name, attribute, undo)
|
||||||
|
char *name;
|
||||||
|
int attribute, undo;
|
||||||
|
{
|
||||||
|
SHELL_VAR *var, *tv;
|
||||||
|
|
||||||
|
if (undo)
|
||||||
|
var = find_variable (name);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tv = find_tempenv_variable (name))
|
||||||
|
{
|
||||||
|
var = bind_variable (tv->name, tv->value);
|
||||||
|
dispose_variable (tv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
var = find_variable (name);
|
||||||
|
|
||||||
|
if (var == 0)
|
||||||
|
{
|
||||||
|
var = bind_variable (name, (char *)NULL);
|
||||||
|
var->attributes |= att_invisible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var)
|
||||||
|
SETVARATTR (var, attribute, undo);
|
||||||
|
|
||||||
|
if (var && ((var->attributes & att_exported) || (attribute & att_exported)))
|
||||||
|
array_needs_making++; /* XXX */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,16 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||||||
|
|
||||||
$PRODUCES shift.c
|
$PRODUCES shift.c
|
||||||
|
|
||||||
#if defined (HAVE_STRING_H)
|
#include <config.h>
|
||||||
# include <string.h>
|
|
||||||
#else /* !HAVE_STRING_H */
|
#if defined (HAVE_UNISTD_H)
|
||||||
# include <strings.h>
|
# include <unistd.h>
|
||||||
#endif /* !HAVE_STRING_H */
|
#endif
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
$BUILTIN shift
|
$BUILTIN shift
|
||||||
$FUNCTION shift_builtin
|
$FUNCTION shift_builtin
|
||||||
@@ -36,6 +39,8 @@ The positional parameters from $N+1 ... are renamed to $1 ... If N is
|
|||||||
not given, it is assumed to be 1.
|
not given, it is assumed to be 1.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
int print_shift_error;
|
||||||
|
|
||||||
/* Shift the arguments ``left''. Shift DOLLAR_VARS down then take one
|
/* Shift the arguments ``left''. Shift DOLLAR_VARS down then take one
|
||||||
off of REST_OF_ARGS and place it into DOLLAR_VARS[9]. If LIST has
|
off of REST_OF_ARGS and place it into DOLLAR_VARS[9]. If LIST has
|
||||||
anything in it, it is a number which says where to start the
|
anything in it, it is a number which says where to start the
|
||||||
@@ -44,34 +49,28 @@ int
|
|||||||
shift_builtin (list)
|
shift_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int times, number;
|
int times;
|
||||||
WORD_LIST *args;
|
register int count;
|
||||||
|
WORD_LIST *temp;
|
||||||
|
|
||||||
times = get_numeric_arg (list);
|
times = get_numeric_arg (list);
|
||||||
|
|
||||||
if (!times)
|
if (times == 0)
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
|
else if (times < 0)
|
||||||
if (times < 0)
|
|
||||||
{
|
{
|
||||||
builtin_error ("shift count must be >= 0");
|
builtin_error ("shift count must be >= 0");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
else if (times > number_of_args ())
|
||||||
args = list_rest_of_args ();
|
|
||||||
number = list_length (args);
|
|
||||||
dispose_words (args);
|
|
||||||
|
|
||||||
if (times > number)
|
|
||||||
{
|
{
|
||||||
|
if (print_shift_error)
|
||||||
builtin_error ("shift count must be <= $#");
|
builtin_error ("shift count must be <= $#");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (times-- > 0)
|
while (times-- > 0)
|
||||||
{
|
{
|
||||||
register int count;
|
|
||||||
|
|
||||||
if (dollar_vars[1])
|
if (dollar_vars[1])
|
||||||
free (dollar_vars[1]);
|
free (dollar_vars[1]);
|
||||||
|
|
||||||
@@ -80,8 +79,7 @@ shift_builtin (list)
|
|||||||
|
|
||||||
if (rest_of_args)
|
if (rest_of_args)
|
||||||
{
|
{
|
||||||
WORD_LIST *temp = rest_of_args;
|
temp = rest_of_args;
|
||||||
|
|
||||||
dollar_vars[9] = savestring (temp->word->word);
|
dollar_vars[9] = savestring (temp->word->word);
|
||||||
rest_of_args = rest_of_args->next;
|
rest_of_args = rest_of_args->next;
|
||||||
temp->next = (WORD_LIST *)NULL;
|
temp->next = (WORD_LIST *)NULL;
|
||||||
@@ -90,6 +88,5 @@ shift_builtin (list)
|
|||||||
else
|
else
|
||||||
dollar_vars[9] = (char *)NULL;
|
dollar_vars[9] = (char *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|||||||
343
builtins/shopt.def
Normal file
343
builtins/shopt.def
Normal file
@@ -0,0 +1,343 @@
|
|||||||
|
This file is shopt.def, from which is created shopt.c.
|
||||||
|
It implements the Bash `shopt' builtin.
|
||||||
|
|
||||||
|
Copyright (C) 1994 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
$PRODUCES shopt.c
|
||||||
|
|
||||||
|
$BUILTIN shopt
|
||||||
|
$DOCNAME shopt_builtin
|
||||||
|
$FUNCTION shopt_builtin
|
||||||
|
$SHORT_DOC shopt [-pqsu] [-o long-option] optname [optname...]
|
||||||
|
Toggle the values of variables controlling optional behavior.
|
||||||
|
The -s flag means to enable (set) each OPTNAME; the -u flag
|
||||||
|
unsets each OPTNAME. The -q flag suppresses output; the exit
|
||||||
|
status indicates whether each OPTNAME is set or unset. The -o
|
||||||
|
option restricts the OPTNAMEs to those defined for use with
|
||||||
|
`set -o'. With no options, or with the -p option, a list of all
|
||||||
|
settable options is displayed, with an indication of whether or
|
||||||
|
not each is set.
|
||||||
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../shell.h"
|
||||||
|
#include "../flags.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
|
#define UNSETOPT 0
|
||||||
|
#define SETOPT 1
|
||||||
|
|
||||||
|
#define OPTFMT "%-15s\t%s\n"
|
||||||
|
|
||||||
|
extern int allow_null_glob_expansion, glob_dot_filenames;
|
||||||
|
extern int cdable_vars, mail_warning, source_uses_path;
|
||||||
|
extern int no_exit_on_failed_exec, print_shift_error;
|
||||||
|
extern int check_hashed_filenames, promptvars, interactive_comments;
|
||||||
|
extern int cdspelling, expand_aliases;
|
||||||
|
extern int check_window_size;
|
||||||
|
|
||||||
|
#if defined (HISTORY)
|
||||||
|
extern int hist_verify, literal_history, command_oriented_history;
|
||||||
|
extern int force_append_history;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (READLINE)
|
||||||
|
extern int history_reediting, perform_hostname_completion;
|
||||||
|
extern void enable_hostname_completion ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int set_interactive_comments ();
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
char *name;
|
||||||
|
int *value;
|
||||||
|
Function *set_func;
|
||||||
|
} shopt_vars[] = {
|
||||||
|
{ "cdable_vars", &cdable_vars, (Function *)NULL },
|
||||||
|
{ "cdspell", &cdspelling, (Function *)NULL },
|
||||||
|
{ "checkhash", &check_hashed_filenames, (Function *)NULL },
|
||||||
|
{ "checkwinsize", &check_window_size, (Function *)NULL },
|
||||||
|
#if defined (HISTORY)
|
||||||
|
{ "cmdhist", &command_oriented_history, (Function *)NULL },
|
||||||
|
#endif
|
||||||
|
{ "dotglob", &glob_dot_filenames, (Function *)NULL },
|
||||||
|
{ "execfail", &no_exit_on_failed_exec, (Function *)NULL },
|
||||||
|
{ "expand_aliases", &expand_aliases, (Function *)NULL },
|
||||||
|
#if defined (READLINE)
|
||||||
|
{ "histreedit", &history_reediting, (Function *)NULL },
|
||||||
|
#endif
|
||||||
|
#if defined (HISTORY)
|
||||||
|
{ "histappend", &force_append_history, (Function *)NULL },
|
||||||
|
{ "histverify", &hist_verify, (Function *)NULL },
|
||||||
|
#endif
|
||||||
|
#if defined (READLINE)
|
||||||
|
{ "hostcomplete", &perform_hostname_completion, (Function *)enable_hostname_completion },
|
||||||
|
#endif
|
||||||
|
{ "interactive_comments", &interactive_comments, set_interactive_comments },
|
||||||
|
#if defined (HISTORY)
|
||||||
|
{ "lithist", &literal_history, (Function *)NULL },
|
||||||
|
#endif
|
||||||
|
{ "mailwarn", &mail_warning, (Function *)NULL },
|
||||||
|
{ "nullglob", &allow_null_glob_expansion, (Function *)NULL },
|
||||||
|
{ "promptvars", &promptvars, (Function *)NULL },
|
||||||
|
{ "shift_verbose", &print_shift_error, (Function *)NULL },
|
||||||
|
{ "sourcepath", &source_uses_path, (Function *)NULL },
|
||||||
|
{ (char *)0, (int *)0, (Function *)NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *on = "on";
|
||||||
|
static char *off = "off";
|
||||||
|
|
||||||
|
static int list_shopt_o_options ();
|
||||||
|
static int list_some_o_options (), list_some_shopts ();
|
||||||
|
static int toggle_shopts (), list_shopts (), set_shopt_o_options ();
|
||||||
|
|
||||||
|
#define SFLAG 0x01
|
||||||
|
#define UFLAG 0x02
|
||||||
|
#define QFLAG 0x04
|
||||||
|
#define OFLAG 0x08
|
||||||
|
#define PFLAG 0x10
|
||||||
|
|
||||||
|
int
|
||||||
|
shopt_builtin (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
int opt, flags, rval;
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "psuoq")) != -1)
|
||||||
|
{
|
||||||
|
switch (opt)
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
flags |= SFLAG;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
flags |= UFLAG;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
flags |= QFLAG;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
flags |= OFLAG;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
flags |= PFLAG;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
|
return (EX_USAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
|
if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG))
|
||||||
|
{
|
||||||
|
builtin_error ("cannot set and unset shell options simultaneously");
|
||||||
|
return (EXECUTION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
rval = EXECUTION_SUCCESS;
|
||||||
|
if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0)) /* shopt -o */
|
||||||
|
rval = list_shopt_o_options (list, flags & QFLAG);
|
||||||
|
else if (list && (flags & OFLAG)) /* shopt -so args */
|
||||||
|
rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG);
|
||||||
|
else if (flags & OFLAG) /* shopt -so */
|
||||||
|
rval = list_some_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, flags & QFLAG);
|
||||||
|
else if (list && (flags & (SFLAG|UFLAG))) /* shopt -su args */
|
||||||
|
rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG);
|
||||||
|
else if ((flags & (SFLAG|UFLAG)) == 0) /* shopt [args] */
|
||||||
|
rval = list_shopts (list, flags & QFLAG);
|
||||||
|
else /* shopt -su */
|
||||||
|
rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags & QFLAG);
|
||||||
|
return (rval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
find_shopt (name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; shopt_vars[i].name; i++)
|
||||||
|
if (STREQ (name, shopt_vars[i].name))
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SHOPT_ERROR(str) builtin_error ("%s: unknown shell option name", str)
|
||||||
|
|
||||||
|
static int
|
||||||
|
toggle_shopts (mode, list, quiet)
|
||||||
|
int mode;
|
||||||
|
WORD_LIST *list;
|
||||||
|
int quiet;
|
||||||
|
{
|
||||||
|
WORD_LIST *l;
|
||||||
|
int ind, rval;
|
||||||
|
|
||||||
|
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
||||||
|
{
|
||||||
|
ind = find_shopt (l->word->word);
|
||||||
|
if (ind < 0)
|
||||||
|
{
|
||||||
|
SHOPT_ERROR (l->word->word);
|
||||||
|
rval = EXECUTION_FAILURE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */
|
||||||
|
if (shopt_vars[ind].set_func)
|
||||||
|
(*shopt_vars[ind].set_func) (mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (rval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List the values of all or any of the `shopt' options. Returns 0 if
|
||||||
|
all were listed or all variables queried were on; 1 otherwise. */
|
||||||
|
static int
|
||||||
|
list_shopts (list, quiet)
|
||||||
|
WORD_LIST *list;
|
||||||
|
int quiet;
|
||||||
|
{
|
||||||
|
WORD_LIST *l;
|
||||||
|
int i, val, rval;
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
{
|
||||||
|
for (i = 0; shopt_vars[i].name; i++)
|
||||||
|
{
|
||||||
|
val = *shopt_vars[i].value;
|
||||||
|
if (quiet == 0)
|
||||||
|
printf (OPTFMT, shopt_vars[i].name, val ? on : off);
|
||||||
|
}
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
||||||
|
{
|
||||||
|
i = find_shopt (l->word->word);
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
SHOPT_ERROR (l->word->word);
|
||||||
|
rval = EXECUTION_FAILURE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
val = *shopt_vars[i].value;
|
||||||
|
if (val == 0)
|
||||||
|
rval = EXECUTION_FAILURE;
|
||||||
|
if (quiet == 0)
|
||||||
|
printf (OPTFMT, l->word->word, val ? on : off);
|
||||||
|
}
|
||||||
|
return (rval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
list_some_shopts (mode, quiet)
|
||||||
|
int mode, quiet;
|
||||||
|
{
|
||||||
|
int val, i;
|
||||||
|
|
||||||
|
for (i = 0; shopt_vars[i].name; i++)
|
||||||
|
{
|
||||||
|
val = *shopt_vars[i].value;
|
||||||
|
if (quiet == 0 && mode == val)
|
||||||
|
printf (OPTFMT, shopt_vars[i].name, val ? on : off);
|
||||||
|
}
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
list_shopt_o_options (list, quiet)
|
||||||
|
WORD_LIST *list;
|
||||||
|
int quiet;
|
||||||
|
{
|
||||||
|
WORD_LIST *l;
|
||||||
|
int val, rval;
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
{
|
||||||
|
if (quiet == 0)
|
||||||
|
list_minus_o_opts (-1);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
||||||
|
{
|
||||||
|
val = minus_o_option_value (l->word->word);
|
||||||
|
if (val == -1)
|
||||||
|
{
|
||||||
|
builtin_error ("%s: unknown option name", l->word->word);
|
||||||
|
rval = EXECUTION_FAILURE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (val == 0)
|
||||||
|
rval = EXECUTION_FAILURE;
|
||||||
|
if (quiet == 0)
|
||||||
|
printf (OPTFMT, l->word->word, val ? "on" : "off");
|
||||||
|
}
|
||||||
|
return (rval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
list_some_o_options (mode, quiet)
|
||||||
|
int mode, quiet;
|
||||||
|
{
|
||||||
|
if (quiet == 0)
|
||||||
|
list_minus_o_opts (mode);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
set_shopt_o_options (mode, list, quiet)
|
||||||
|
int mode;
|
||||||
|
WORD_LIST *list;
|
||||||
|
int quiet;
|
||||||
|
{
|
||||||
|
WORD_LIST *l;
|
||||||
|
int rval;
|
||||||
|
|
||||||
|
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
||||||
|
{
|
||||||
|
if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE)
|
||||||
|
rval = EXECUTION_FAILURE;
|
||||||
|
}
|
||||||
|
set_shellopts ();
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we set or unset interactive_comments with shopt, make sure the
|
||||||
|
change is reflected in $SHELLOPTS. */
|
||||||
|
static int
|
||||||
|
set_interactive_comments (mode)
|
||||||
|
int mode;
|
||||||
|
{
|
||||||
|
set_shellopts ();
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
@@ -36,34 +36,34 @@ in $PATH are used to find the directory containing FILENAME.
|
|||||||
$END
|
$END
|
||||||
/* source.c - Implements the `.' and `source' builtins. */
|
/* source.c - Implements the `.' and `source' builtins. */
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "../bashtypes.h"
|
||||||
|
#include "../posixstat.h"
|
||||||
|
#include "../filecntl.h"
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#if defined (HAVE_STRING_H)
|
#if defined (HAVE_UNISTD_H)
|
||||||
# include <string.h>
|
# include <unistd.h>
|
||||||
#else /* !HAVE_STRING_H */
|
#endif
|
||||||
# include <strings.h>
|
|
||||||
#endif /* !HAVE_STRING_H */
|
#include "../bashansi.h"
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../posixstat.h"
|
|
||||||
#include "../filecntl.h"
|
|
||||||
#include "../execute_cmd.h"
|
#include "../execute_cmd.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
|
|
||||||
#if !defined (errno)
|
#if !defined (errno)
|
||||||
extern int errno;
|
extern int errno;
|
||||||
#endif /* !errno */
|
#endif /* !errno */
|
||||||
|
|
||||||
/* Variables used here but defined in other files. */
|
#if defined (RESTRICTED_SHELL)
|
||||||
extern int return_catch_flag, return_catch_value;
|
extern int restricted;
|
||||||
extern jmp_buf return_catch;
|
#endif
|
||||||
extern int posixly_correct;
|
|
||||||
extern int interactive, interactive_shell, last_command_exit_value;
|
|
||||||
|
|
||||||
/* How many `levels' of sourced files we have. */
|
/* If non-zero, `.' uses $PATH to look up the script to be sourced. */
|
||||||
int sourcelevel = 0;
|
int source_uses_path = 1;
|
||||||
|
|
||||||
/* If this . script is supplied arguments, we save the dollar vars and
|
/* If this . script is supplied arguments, we save the dollar vars and
|
||||||
replace them with the script arguments for the duration of the script's
|
replace them with the script arguments for the duration of the script's
|
||||||
@@ -86,64 +86,39 @@ maybe_pop_dollar_vars ()
|
|||||||
This cannot be done in a subshell, since things like variable assignments
|
This cannot be done in a subshell, since things like variable assignments
|
||||||
take place in there. So, I open the file, place it into a large string,
|
take place in there. So, I open the file, place it into a large string,
|
||||||
close the file, and then execute the string. */
|
close the file, and then execute the string. */
|
||||||
|
int
|
||||||
source_builtin (list)
|
source_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int result, return_val;
|
int result;
|
||||||
|
char *filename;
|
||||||
|
|
||||||
/* Assume the best. */
|
if (list == 0)
|
||||||
result = EXECUTION_SUCCESS;
|
|
||||||
|
|
||||||
if (list)
|
|
||||||
{
|
{
|
||||||
char *string, *filename;
|
builtin_error ("filename argument required");
|
||||||
struct stat finfo;
|
builtin_usage ();
|
||||||
int fd, tt;
|
return (EX_USAGE);
|
||||||
|
|
||||||
filename = find_path_file (list->word->word);
|
|
||||||
if (!filename)
|
|
||||||
filename = savestring (list->word->word);
|
|
||||||
|
|
||||||
if (((fd = open (filename, O_RDONLY)) < 0) || (fstat (fd, &finfo) < 0))
|
|
||||||
goto file_error_exit;
|
|
||||||
|
|
||||||
string = (char *)xmalloc (1 + (int)finfo.st_size);
|
|
||||||
tt = read (fd, string, finfo.st_size);
|
|
||||||
string[finfo.st_size] = '\0';
|
|
||||||
|
|
||||||
/* Close the open file, preserving the state of errno. */
|
|
||||||
{ int temp = errno; close (fd); errno = temp; }
|
|
||||||
|
|
||||||
if (tt != finfo.st_size)
|
|
||||||
{
|
|
||||||
free (string);
|
|
||||||
|
|
||||||
file_error_exit:
|
|
||||||
file_error (filename);
|
|
||||||
free (filename);
|
|
||||||
|
|
||||||
/* POSIX shells exit if non-interactive and file error. */
|
|
||||||
if (posixly_correct && !interactive_shell)
|
|
||||||
{
|
|
||||||
last_command_exit_value = 1;
|
|
||||||
longjmp (top_level, EXITPROG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (no_options (list))
|
||||||
|
return (EX_USAGE);
|
||||||
|
|
||||||
|
#if defined (RESTRICTED_SHELL)
|
||||||
|
if (restricted && strchr (list->word->word, '/'))
|
||||||
|
{
|
||||||
|
builtin_error ("%s: restricted", list->word->word);
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (tt > 80)
|
filename = (char *)NULL;
|
||||||
tt = 80;
|
if (source_uses_path)
|
||||||
|
filename = find_path_file (list->word->word);
|
||||||
|
if (filename == 0)
|
||||||
|
filename = savestring (list->word->word);
|
||||||
|
|
||||||
if (check_binary_file ((unsigned char *)string, tt))
|
begin_unwind_frame ("source");
|
||||||
{
|
add_unwind_protect ((Function *)xfree, filename);
|
||||||
free (string);
|
|
||||||
builtin_error ("%s: cannot execute binary file", filename);
|
|
||||||
free (filename);
|
|
||||||
return (EX_BINARY_FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
begin_unwind_frame ("File Sourcing");
|
|
||||||
|
|
||||||
if (list->next)
|
if (list->next)
|
||||||
{
|
{
|
||||||
@@ -151,36 +126,11 @@ source_builtin (list)
|
|||||||
add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
|
add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
|
||||||
remember_args (list->next, 1);
|
remember_args (list->next, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
unwind_protect_int (return_catch_flag);
|
|
||||||
unwind_protect_jmp_buf (return_catch);
|
|
||||||
unwind_protect_int (interactive);
|
|
||||||
unwind_protect_int (sourcelevel);
|
|
||||||
add_unwind_protect ((Function *)xfree, filename);
|
|
||||||
interactive = 0;
|
|
||||||
sourcelevel++;
|
|
||||||
|
|
||||||
set_dollar_vars_unchanged ();
|
set_dollar_vars_unchanged ();
|
||||||
|
|
||||||
return_catch_flag++;
|
result = source_file (filename);
|
||||||
return_val = setjmp (return_catch);
|
|
||||||
|
|
||||||
if (return_val)
|
run_unwind_frame ("source");
|
||||||
parse_and_execute_cleanup ();
|
|
||||||
else
|
|
||||||
result = parse_and_execute (string, filename, -1);
|
|
||||||
|
|
||||||
run_unwind_frame ("File Sourcing");
|
|
||||||
|
|
||||||
/* If RETURN_VAL is non-zero, then we return the value given
|
|
||||||
to return_builtin (), since that is how we got here. */
|
|
||||||
if (return_val)
|
|
||||||
result = return_catch_value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
builtin_error ("filename argument required");
|
|
||||||
result = EXECUTION_FAILURE;
|
|
||||||
}
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,15 +30,23 @@ signal. The `-f' if specified says not to complain about this
|
|||||||
being a login shell if it is; just suspend anyway.
|
being a login shell if it is; just suspend anyway.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (JOB_CONTROL)
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../bashtypes.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../jobs.h"
|
#include "../jobs.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
#if defined (JOB_CONTROL)
|
|
||||||
extern int job_control;
|
extern int job_control;
|
||||||
|
|
||||||
static SigHandler *old_cont, *old_tstp;
|
static SigHandler *old_cont, *old_stop;
|
||||||
|
|
||||||
/* Continue handler. */
|
/* Continue handler. */
|
||||||
sighandler
|
sighandler
|
||||||
@@ -46,10 +54,10 @@ suspend_continue (sig)
|
|||||||
int sig;
|
int sig;
|
||||||
{
|
{
|
||||||
set_signal_handler (SIGCONT, old_cont);
|
set_signal_handler (SIGCONT, old_cont);
|
||||||
set_signal_handler (SIGTSTP, old_tstp);
|
#if 0
|
||||||
#if !defined (VOID_SIGHANDLER)
|
set_signal_handler (SIGSTOP, old_stop);
|
||||||
return (0);
|
#endif
|
||||||
#endif /* !VOID_SIGHANDLER */
|
SIGRETURN (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Suspending the shell. If -f is the arg, then do the suspend
|
/* Suspending the shell. If -f is the arg, then do the suspend
|
||||||
@@ -58,28 +66,45 @@ int
|
|||||||
suspend_builtin (list)
|
suspend_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
if (!job_control)
|
int opt, force;
|
||||||
|
|
||||||
|
reset_internal_getopt ();
|
||||||
|
force = 0;
|
||||||
|
while ((opt = internal_getopt (list, "f")) != -1)
|
||||||
|
switch (opt)
|
||||||
{
|
{
|
||||||
builtin_error ("Cannot suspend a shell without job control");
|
case 'f':
|
||||||
|
force++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
builtin_usage ();
|
||||||
|
return (EX_USAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
|
if (job_control == 0)
|
||||||
|
{
|
||||||
|
builtin_error ("cannot suspend a shell without job control");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list)
|
if (force == 0)
|
||||||
if (strcmp (list->word->word, "-f") == 0)
|
{
|
||||||
goto do_suspend;
|
|
||||||
|
|
||||||
no_args (list);
|
no_args (list);
|
||||||
|
|
||||||
if (login_shell)
|
if (login_shell)
|
||||||
{
|
{
|
||||||
builtin_error ("Can't suspend a login shell");
|
builtin_error ("cannot suspend a login shell");
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
do_suspend:
|
|
||||||
old_cont = (SigHandler *)set_signal_handler (SIGCONT, suspend_continue);
|
old_cont = (SigHandler *)set_signal_handler (SIGCONT, suspend_continue);
|
||||||
old_tstp = (SigHandler *)set_signal_handler (SIGTSTP, SIG_DFL);
|
#if 0
|
||||||
killpg (shell_pgrp, SIGTSTP);
|
old_stop = (SigHandler *)set_signal_handler (SIGSTOP, SIG_DFL);
|
||||||
|
#endif
|
||||||
|
killpg (shell_pgrp, SIGSTOP);
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,12 +37,12 @@ File operators:
|
|||||||
-e FILE True if file exists.
|
-e FILE True if file exists.
|
||||||
-f FILE True if file exists and is a regular file.
|
-f FILE True if file exists and is a regular file.
|
||||||
-g FILE True if file is set-group-id.
|
-g FILE True if file is set-group-id.
|
||||||
-h FILE True if file is a symbolic link. Use "-L".
|
-h FILE True if file is a symbolic link.
|
||||||
-L FILE True if file is a symbolic link.
|
-L FILE True if file is a symbolic link.
|
||||||
-k FILE True if file has its "sticky" bit set.
|
-k FILE True if file has its `sticky' bit set.
|
||||||
-p FILE True if file is a named pipe.
|
-p FILE True if file is a named pipe.
|
||||||
-r FILE True if file is readable by you.
|
-r FILE True if file is readable by you.
|
||||||
-s FILE True if file is not empty.
|
-s FILE True if file exists and is not empty.
|
||||||
-S FILE True if file is a socket.
|
-S FILE True if file is a socket.
|
||||||
-t FD True if FD is opened on a terminal.
|
-t FD True if FD is opened on a terminal.
|
||||||
-u FILE True if the file is set-user-id.
|
-u FILE True if the file is set-user-id.
|
||||||
@@ -63,12 +63,16 @@ String operators:
|
|||||||
-z STRING True if string is empty.
|
-z STRING True if string is empty.
|
||||||
|
|
||||||
-n STRING
|
-n STRING
|
||||||
or STRING True if string is not empty.
|
STRING True if string is not empty.
|
||||||
|
|
||||||
STRING1 = STRING2
|
STRING1 = STRING2
|
||||||
True if the strings are equal.
|
True if the strings are equal.
|
||||||
STRING1 != STRING2
|
STRING1 != STRING2
|
||||||
True if the strings are not equal.
|
True if the strings are not equal.
|
||||||
|
STRING1 < STRING2
|
||||||
|
True if STRING1 sorts before STRING2 lexicographically
|
||||||
|
STRING1 > STRING2
|
||||||
|
True if STRING1 sorts after STRING2 lexicographically
|
||||||
|
|
||||||
Other operators:
|
Other operators:
|
||||||
|
|
||||||
@@ -88,18 +92,21 @@ $BUILTIN [
|
|||||||
$DOCNAME test_bracket
|
$DOCNAME test_bracket
|
||||||
$FUNCTION test_builtin
|
$FUNCTION test_builtin
|
||||||
$SHORT_DOC [ arg... ]
|
$SHORT_DOC [ arg... ]
|
||||||
This is a synonym for the "test" shell builtin, excepting that the
|
This is a synonym for the "test" builtin, but the last
|
||||||
last argument must be literally `]', to match the `[' which invoked
|
argument must be a literal `]', to match the opening `['.
|
||||||
the test.
|
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#if defined (HAVE_STRING_H)
|
#include <config.h>
|
||||||
# include <string.h>
|
|
||||||
#else /* !HAVE_STRING_H */
|
#if defined (HAVE_UNISTD_H)
|
||||||
# include <strings.h>
|
# include <unistd.h>
|
||||||
#endif /* !HAVE_STRING_H */
|
#endif
|
||||||
|
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
extern char *this_command_name;
|
extern char *this_command_name;
|
||||||
|
|
||||||
/* TEST/[ builtin. */
|
/* TEST/[ builtin. */
|
||||||
@@ -109,12 +116,11 @@ test_builtin (list)
|
|||||||
{
|
{
|
||||||
char **argv;
|
char **argv;
|
||||||
int argc, result;
|
int argc, result;
|
||||||
WORD_LIST *t = list;
|
|
||||||
|
|
||||||
/* We let Matthew Bradburn and Kevin Braunsdorf's code do the
|
/* We let Matthew Bradburn and Kevin Braunsdorf's code do the
|
||||||
actual test command. So turn the list of args into an array
|
actual test command. So turn the list of args into an array
|
||||||
of strings, since that is what his code wants. */
|
of strings, since that is what their code wants. */
|
||||||
if (!list)
|
if (list == 0)
|
||||||
{
|
{
|
||||||
if (this_command_name[0] == '[' && !this_command_name[1])
|
if (this_command_name[0] == '[' && !this_command_name[1])
|
||||||
builtin_error ("missing `]'");
|
builtin_error ("missing `]'");
|
||||||
@@ -122,23 +128,9 @@ test_builtin (list)
|
|||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the length of the argument list. */
|
argv = make_builtin_argv (list, &argc);
|
||||||
for (argc = 0; t; t = t->next, argc++);
|
|
||||||
|
|
||||||
/* Account for argv[0] being a command name. This makes our life easier. */
|
|
||||||
argc++;
|
|
||||||
argv = (char **)xmalloc ((1 + argc) * sizeof (char *));
|
|
||||||
argv[argc] = (char *)NULL;
|
|
||||||
|
|
||||||
/* this_command_name is the name of the command that invoked this
|
|
||||||
function. So you can't call test_builtin () directly from
|
|
||||||
within this code, there are too many things to worry about. */
|
|
||||||
argv[0] = savestring (this_command_name);
|
|
||||||
|
|
||||||
for (t = list, argc = 1; t; t = t->next, argc++)
|
|
||||||
argv[argc] = savestring (t->word->word);
|
|
||||||
|
|
||||||
result = test_command (argc, argv);
|
result = test_command (argc, argv);
|
||||||
free_array (argv);
|
free ((char *)argv);
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,62 +28,79 @@ Print the accumulated user and system times for processes run from
|
|||||||
the shell.
|
the shell.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../bashtypes.h"
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#if defined (hpux) || defined (USGr4) || defined (XD88) || defined (USGr3)
|
#if TIME_WITH_SYS_TIME
|
||||||
# undef HAVE_RESOURCE
|
|
||||||
#endif /* hpux || USGr4 || XD88 || USGr3 */
|
|
||||||
|
|
||||||
#if defined (_POSIX_VERSION) || !defined (HAVE_RESOURCE)
|
|
||||||
# include <sys/times.h>
|
|
||||||
#else /* !_POSIX_VERSION && HAVE_RESOURCE */
|
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
# include <sys/resource.h>
|
# include <time.h>
|
||||||
#endif /* !_POSIX_VERSION && HAVE_RESOURCE */
|
#else
|
||||||
|
# if defined (HAVE_SYS_TIME_H)
|
||||||
|
# include <sys/time.h>
|
||||||
|
# else
|
||||||
|
# include <time.h>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Print the totals for system and user time used. The
|
#if defined (HAVE_SYS_TIMES_H)
|
||||||
information comes from variables in jobs.c used to keep
|
# include <sys/times.h>
|
||||||
track of this stuff. */
|
#endif /* HAVE_SYS_TIMES_H */
|
||||||
|
|
||||||
|
#if defined (HAVE_SYS_RESOURCE_H)
|
||||||
|
# include <sys/resource.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
/* Print the totals for system and user time used. */
|
||||||
|
int
|
||||||
times_builtin (list)
|
times_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
#if !defined (_POSIX_VERSION) && defined (HAVE_RESOURCE) && defined (RUSAGE_SELF)
|
#if defined (HAVE_GETRUSAGE) && defined (HAVE_TIMEVAL) && defined (RUSAGE_SELF)
|
||||||
struct rusage self, kids;
|
struct rusage self, kids;
|
||||||
|
|
||||||
getrusage (RUSAGE_SELF, &self);
|
getrusage (RUSAGE_SELF, &self);
|
||||||
getrusage (RUSAGE_CHILDREN, &kids); /* terminated child processes */
|
getrusage (RUSAGE_CHILDREN, &kids); /* terminated child processes */
|
||||||
|
|
||||||
print_timeval (&self.ru_utime);
|
print_timeval (stdout, &self.ru_utime);
|
||||||
putchar (' ');
|
putchar (' ');
|
||||||
print_timeval (&self.ru_stime);
|
print_timeval (stdout, &self.ru_stime);
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
print_timeval (&kids.ru_utime);
|
print_timeval (stdout, &kids.ru_utime);
|
||||||
putchar (' ');
|
putchar (' ');
|
||||||
print_timeval (&kids.ru_stime);
|
print_timeval (stdout, &kids.ru_stime);
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
|
|
||||||
#else /* _POSIX_VERSION || !HAVE_RESOURCE || !RUSAGE_SELF */
|
#else
|
||||||
# if !defined (BrainDeath)
|
# if defined (HAVE_TIMES)
|
||||||
struct tms t;
|
|
||||||
|
|
||||||
times (&t);
|
|
||||||
|
|
||||||
/* As of System V.3, HP-UX 6.5, and other ATT-like systems, this stuff is
|
/* As of System V.3, HP-UX 6.5, and other ATT-like systems, this stuff is
|
||||||
returned in terms of clock ticks (HZ from sys/param.h). C'mon, guys.
|
returned in terms of clock ticks (HZ from sys/param.h). C'mon, guys.
|
||||||
This kind of stupid clock-dependent stuff is exactly the reason 4.2BSD
|
This kind of stupid clock-dependent stuff is exactly the reason 4.2BSD
|
||||||
introduced the `timeval' struct. */
|
introduced the `timeval' struct. */
|
||||||
|
struct tms t;
|
||||||
|
|
||||||
print_time_in_hz (t.tms_utime);
|
times (&t);
|
||||||
|
|
||||||
|
print_time_in_hz (stdout, t.tms_utime);
|
||||||
putchar (' ');
|
putchar (' ');
|
||||||
print_time_in_hz (t.tms_stime);
|
print_time_in_hz (stdout, t.tms_stime);
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
print_time_in_hz (t.tms_cutime);
|
print_time_in_hz (stdout, t.tms_cutime);
|
||||||
putchar (' ');
|
putchar (' ');
|
||||||
print_time_in_hz (t.tms_cstime);
|
print_time_in_hz (stdout, t.tms_cstime);
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
# endif /* BrainDeath */
|
# else /* !HAVE_TIMES */
|
||||||
#endif /* _POSIX_VERSION || !HAVE_RESOURCE || !RUSAGE_SELF */
|
printf ("0.00 0.00\n0.00 0.00\n");
|
||||||
|
# endif /* HAVE_TIMES */
|
||||||
|
#endif /* !HAVE_TIMES */
|
||||||
|
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,30 +23,46 @@ $PRODUCES trap.c
|
|||||||
|
|
||||||
$BUILTIN trap
|
$BUILTIN trap
|
||||||
$FUNCTION trap_builtin
|
$FUNCTION trap_builtin
|
||||||
$SHORT_DOC trap [arg] [signal_spec]
|
$SHORT_DOC trap [arg] [signal_spec] or trap -l
|
||||||
The command ARG is to be read and executed when the shell receives
|
The command ARG is to be read and executed when the shell receives
|
||||||
signal(s) SIGNAL_SPEC. If ARG is absent all specified signals are
|
signal(s) SIGNAL_SPEC. If ARG is absent all specified signals are
|
||||||
reset to their original values. If ARG is the null string this
|
reset to their original values. If ARG is the null string each
|
||||||
signal is ignored by the shell and by the commands it invokes. If
|
SIGNAL_SPEC is ignored by the shell and by the commands it invokes.
|
||||||
SIGNAL_SPEC is EXIT (0) the command ARG is executed on exit from
|
If SIGNAL_SPEC is EXIT (0) the command ARG is executed on exit from
|
||||||
the shell. The trap command with no arguments prints the list of
|
the shell. If SIGNAL_SPEC is DEBUG, ARG is executed after every
|
||||||
commands associated with each signal number. SIGNAL_SPEC is either
|
command. If ARG is `-p' then the trap commands associated with
|
||||||
a signal name in <signal.h>, or a signal number. The syntax `trap -l'
|
each SIGNAL_SPEC are displayed. If no arguments are supplied or if
|
||||||
prints a list of signal names and their corresponding numbers.
|
only `-p' is given, trap prints the list of commands associated with
|
||||||
Note that a signal can be sent to the shell with "kill -signal $$".
|
each signal number. SIGNAL_SPEC is either a signal name in <signal.h>
|
||||||
|
or a signal number. `trap -l' prints a list of signal names and their
|
||||||
|
corresponding numbers. Note that a signal can be sent to the shell
|
||||||
|
with "kill -signal $$".
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../bashtypes.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../trap.h"
|
#include "../trap.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
|
static int display_traps ();
|
||||||
|
|
||||||
/* The trap command:
|
/* The trap command:
|
||||||
|
|
||||||
trap <arg> <signal ...>
|
trap <arg> <signal ...>
|
||||||
trap <signal ...>
|
trap <signal ...>
|
||||||
trap -l
|
trap -l
|
||||||
|
trap -p [sigspec ...]
|
||||||
trap [--]
|
trap [--]
|
||||||
|
|
||||||
Set things up so that ARG is executed when SIGNAL(s) N is recieved.
|
Set things up so that ARG is executed when SIGNAL(s) N is recieved.
|
||||||
@@ -62,60 +78,44 @@ $END
|
|||||||
|
|
||||||
extern int interactive;
|
extern int interactive;
|
||||||
|
|
||||||
|
int
|
||||||
trap_builtin (list)
|
trap_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
register int i;
|
int list_signal_names, display, result, opt;
|
||||||
int list_signal_names = 0;
|
|
||||||
|
|
||||||
while (list)
|
list_signal_names = display = 0;
|
||||||
|
result = EXECUTION_SUCCESS;
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "lp")) != -1)
|
||||||
{
|
{
|
||||||
if (ISOPTION (list->word->word, 'l'))
|
switch (opt)
|
||||||
{
|
{
|
||||||
|
case 'l':
|
||||||
list_signal_names++;
|
list_signal_names++;
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
else if (ISOPTION (list->word->word, '-'))
|
|
||||||
{
|
|
||||||
list = list->next;
|
|
||||||
break;
|
break;
|
||||||
}
|
case 'p':
|
||||||
else if ((*list->word->word == '-') && list->word->word[1])
|
display++;
|
||||||
{
|
break;
|
||||||
bad_option (list->word->word);
|
default:
|
||||||
builtin_error ("usage: trap [-l] [arg] [sigspec]");
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
if (list_signal_names)
|
if (list_signal_names)
|
||||||
{
|
return (display_signal_list ((WORD_LIST *)NULL, 1));
|
||||||
int column = 0;
|
else if (display || list == 0)
|
||||||
|
return (display_traps (list));
|
||||||
for (i = 0; i < NSIG; i++)
|
|
||||||
{
|
|
||||||
printf ("%2d) %s", i, signal_name (i));
|
|
||||||
if (++column < 4)
|
|
||||||
printf ("\t");
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("\n");
|
char *first_arg;
|
||||||
column = 0;
|
int operation, sig;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (column != 0)
|
|
||||||
printf ("\n");
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list)
|
operation = SET;
|
||||||
{
|
first_arg = list->word->word;
|
||||||
char *first_arg = list->word->word;
|
if (first_arg && *first_arg && signal_object_p (first_arg))
|
||||||
int operation = SET, any_failed = 0;
|
|
||||||
|
|
||||||
if (signal_object_p (first_arg))
|
|
||||||
operation = REVERT;
|
operation = REVERT;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -128,15 +128,13 @@ trap_builtin (list)
|
|||||||
|
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
int sig;
|
|
||||||
|
|
||||||
sig = decode_signal (list->word->word);
|
sig = decode_signal (list->word->word);
|
||||||
|
|
||||||
if (sig == NO_SIG)
|
if (sig == NO_SIG)
|
||||||
{
|
{
|
||||||
builtin_error ("%s: not a signal specification",
|
builtin_error ("%s: not a signal specification",
|
||||||
list->word->word);
|
list->word->word);
|
||||||
any_failed++;
|
result = EXECUTION_FAILURE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -183,22 +181,52 @@ trap_builtin (list)
|
|||||||
}
|
}
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
return ((!any_failed) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < NSIG; i++)
|
return (result);
|
||||||
{
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
showtrap (i)
|
||||||
|
int i;
|
||||||
|
{
|
||||||
char *t, *p;
|
char *t, *p;
|
||||||
|
|
||||||
p = trap_list[i];
|
p = trap_list[i];
|
||||||
|
|
||||||
if (p == (char *)DEFAULT_SIG)
|
if (p == (char *)DEFAULT_SIG)
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
t = (p == (char *)IGNORE_SIG) ? (char *)NULL : single_quote (p);
|
t = (p == (char *)IGNORE_SIG) ? (char *)NULL : single_quote (p);
|
||||||
printf ("trap -- %s %s\n", t ? t : "''", signal_name (i));
|
printf ("trap -- %s %s\n", t ? t : "''", signal_name (i));
|
||||||
if (t)
|
if (t)
|
||||||
free (t);
|
free (t);
|
||||||
}
|
}
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
|
static int
|
||||||
|
display_traps (list)
|
||||||
|
WORD_LIST *list;
|
||||||
|
{
|
||||||
|
int result, i;
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i <= NSIG; i++)
|
||||||
|
showtrap (i);
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (result = EXECUTION_SUCCESS; list; list = list->next)
|
||||||
|
{
|
||||||
|
i = decode_signal (list->word->word);
|
||||||
|
if (i == NO_SIG)
|
||||||
|
{
|
||||||
|
result = EXECUTION_FAILURE;
|
||||||
|
builtin_error ("%s: not a signal specification", list->word->word);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
showtrap (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,26 +23,38 @@ $PRODUCES type.c
|
|||||||
|
|
||||||
$BUILTIN type
|
$BUILTIN type
|
||||||
$FUNCTION type_builtin
|
$FUNCTION type_builtin
|
||||||
$SHORT_DOC type [-all] [-type | -path] [name ...]
|
$SHORT_DOC type [-apt] name [name ...]
|
||||||
For each NAME, indicate how it would be interpreted if used as a
|
For each NAME, indicate how it would be interpreted if used as a
|
||||||
command name.
|
command name.
|
||||||
|
|
||||||
If the -type flag is used, returns a single word which is one of
|
If the -t option is used, returns a single word which is one of
|
||||||
`alias', `keyword', `function', `builtin', `file' or `', if NAME is an
|
`alias', `keyword', `function', `builtin', `file' or `', if NAME is an
|
||||||
alias, shell reserved word, shell function, shell builtin, disk file,
|
alias, shell reserved word, shell function, shell builtin, disk file,
|
||||||
or unfound, respectively.
|
or unfound, respectively.
|
||||||
|
|
||||||
If the -path flag is used, either returns the name of the disk file
|
If the -p flag is used, either returns the name of the disk file
|
||||||
that would be exec'ed, or nothing if -type wouldn't return `file'.
|
that would be executed, or nothing if -t would not return `file'.
|
||||||
|
|
||||||
If the -all flag is used, displays all of the places that contain an
|
If the -a flag is used, displays all of the places that contain an
|
||||||
executable named `file'. This includes aliases and functions, if and
|
executable named `file'. This includes aliases and functions, if and
|
||||||
only if the -path flag is not also used.
|
only if the -p flag is not also used.
|
||||||
|
|
||||||
|
Type accepts -all, -path, and -type in place of -a, -p, and -t,
|
||||||
|
respectively.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <config.h>
|
||||||
#include <sys/types.h>
|
|
||||||
|
#include "../bashtypes.h"
|
||||||
#include "../posixstat.h"
|
#include "../posixstat.h"
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../bashansi.h"
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../execute_cmd.h"
|
#include "../execute_cmd.h"
|
||||||
|
|
||||||
@@ -52,7 +64,7 @@ $END
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
extern STRING_INT_ALIST word_token_alist[];
|
extern int find_reserved_word ();
|
||||||
|
|
||||||
/* For each word in LIST, find out what the shell is going to do with
|
/* For each word in LIST, find out what the shell is going to do with
|
||||||
it as a simple command. i.e., which file would this shell use to
|
it as a simple command. i.e., which file would this shell use to
|
||||||
@@ -75,18 +87,19 @@ extern STRING_INT_ALIST word_token_alist[];
|
|||||||
builtin
|
builtin
|
||||||
file
|
file
|
||||||
*/
|
*/
|
||||||
|
int
|
||||||
type_builtin (list)
|
type_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int path_only, type_only, all, verbose;
|
int path_only, type_only, all, verbose;
|
||||||
int successful_finds;
|
int successful_finds;
|
||||||
|
|
||||||
|
if (list == 0)
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
|
||||||
path_only = type_only = all = 0;
|
path_only = type_only = all = 0;
|
||||||
successful_finds = 0;
|
successful_finds = 0;
|
||||||
|
|
||||||
if (!list)
|
|
||||||
return (EXECUTION_SUCCESS);
|
|
||||||
|
|
||||||
while (list && *(list->word->word) == '-')
|
while (list && *(list->word->word) == '-')
|
||||||
{
|
{
|
||||||
char *flag = &(list->word->word[1]);
|
char *flag = &(list->word->word[1]);
|
||||||
@@ -108,7 +121,7 @@ type_builtin (list)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
bad_option (flag);
|
bad_option (flag);
|
||||||
builtin_error ("usage: type [-all | -path | -type ] name [name ...]");
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
list = list->next;
|
list = list->next;
|
||||||
@@ -116,7 +129,7 @@ type_builtin (list)
|
|||||||
|
|
||||||
if (type_only)
|
if (type_only)
|
||||||
verbose = 1;
|
verbose = 1;
|
||||||
else if (!path_only)
|
else if (path_only == 0)
|
||||||
verbose = 2;
|
verbose = 2;
|
||||||
else if (path_only)
|
else if (path_only)
|
||||||
verbose = 3;
|
verbose = 3;
|
||||||
@@ -156,22 +169,29 @@ type_builtin (list)
|
|||||||
* ALL says whether or not to look for all occurrences of COMMAND, or
|
* ALL says whether or not to look for all occurrences of COMMAND, or
|
||||||
* return after finding it once.
|
* return after finding it once.
|
||||||
*/
|
*/
|
||||||
|
int
|
||||||
describe_command (command, verbose, all)
|
describe_command (command, verbose, all)
|
||||||
char *command;
|
char *command;
|
||||||
int verbose, all;
|
int verbose, all;
|
||||||
{
|
{
|
||||||
int found = 0, i, found_file = 0;
|
int found, i, found_file;
|
||||||
char *full_path = (char *)NULL;
|
char *full_path;
|
||||||
SHELL_VAR *func;
|
SHELL_VAR *func;
|
||||||
|
#if defined (ALIAS)
|
||||||
|
alias_t *alias;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
found = found_file = 0;
|
||||||
|
full_path = (char *)NULL;
|
||||||
|
|
||||||
#if defined (ALIAS)
|
#if defined (ALIAS)
|
||||||
/* Command is an alias? */
|
/* Command is an alias? */
|
||||||
ASSOC *alias = find_alias (command);
|
alias = find_alias (command);
|
||||||
|
|
||||||
if (alias)
|
if (alias)
|
||||||
{
|
{
|
||||||
if (verbose == 1)
|
if (verbose == 1)
|
||||||
printf ("alias\n");
|
puts ("alias");
|
||||||
else if (verbose == 2)
|
else if (verbose == 2)
|
||||||
printf ("%s is aliased to `%s'\n", command, alias->value);
|
printf ("%s is aliased to `%s'\n", command, alias->value);
|
||||||
else if (verbose == 4)
|
else if (verbose == 4)
|
||||||
@@ -193,7 +213,7 @@ describe_command (command, verbose, all)
|
|||||||
if (i >= 0)
|
if (i >= 0)
|
||||||
{
|
{
|
||||||
if (verbose == 1)
|
if (verbose == 1)
|
||||||
printf ("keyword\n");
|
puts ("keyword");
|
||||||
else if (verbose == 2)
|
else if (verbose == 2)
|
||||||
printf ("%s is a shell keyword\n", command);
|
printf ("%s is a shell keyword\n", command);
|
||||||
else if (verbose == 4)
|
else if (verbose == 4)
|
||||||
@@ -211,7 +231,7 @@ describe_command (command, verbose, all)
|
|||||||
if (func)
|
if (func)
|
||||||
{
|
{
|
||||||
if (verbose == 1)
|
if (verbose == 1)
|
||||||
printf ("function\n");
|
puts ("function");
|
||||||
else if (verbose == 2)
|
else if (verbose == 2)
|
||||||
{
|
{
|
||||||
#define PRETTY_PRINT_FUNC 1
|
#define PRETTY_PRINT_FUNC 1
|
||||||
@@ -240,7 +260,7 @@ describe_command (command, verbose, all)
|
|||||||
if (find_shell_builtin (command))
|
if (find_shell_builtin (command))
|
||||||
{
|
{
|
||||||
if (verbose == 1)
|
if (verbose == 1)
|
||||||
printf ("builtin\n");
|
puts ("builtin");
|
||||||
else if (verbose == 2)
|
else if (verbose == 2)
|
||||||
printf ("%s is a shell builtin\n", command);
|
printf ("%s is a shell builtin\n", command);
|
||||||
else if (verbose == 4)
|
else if (verbose == 4)
|
||||||
@@ -261,7 +281,7 @@ describe_command (command, verbose, all)
|
|||||||
if (f & FS_EXECABLE)
|
if (f & FS_EXECABLE)
|
||||||
{
|
{
|
||||||
if (verbose == 1)
|
if (verbose == 1)
|
||||||
printf ("file\n");
|
puts ("file");
|
||||||
else if (verbose == 2)
|
else if (verbose == 2)
|
||||||
printf ("%s is %s\n", command, command);
|
printf ("%s is %s\n", command, command);
|
||||||
else if (verbose == 3 || verbose == 4)
|
else if (verbose == 3 || verbose == 4)
|
||||||
@@ -281,7 +301,7 @@ describe_command (command, verbose, all)
|
|||||||
if ((full_path = find_hashed_filename (command)) != (char *)NULL)
|
if ((full_path = find_hashed_filename (command)) != (char *)NULL)
|
||||||
{
|
{
|
||||||
if (verbose == 1)
|
if (verbose == 1)
|
||||||
printf ("file\n");
|
puts ("file");
|
||||||
else if (verbose == 2)
|
else if (verbose == 2)
|
||||||
printf ("%s is hashed (%s)\n", command, full_path);
|
printf ("%s is hashed (%s)\n", command, full_path);
|
||||||
else if (verbose == 3 || verbose == 4)
|
else if (verbose == 3 || verbose == 4)
|
||||||
@@ -308,7 +328,7 @@ describe_command (command, verbose, all)
|
|||||||
found = 1;
|
found = 1;
|
||||||
|
|
||||||
if (verbose == 1)
|
if (verbose == 1)
|
||||||
printf ("file\n");
|
puts ("file");
|
||||||
else if (verbose == 2)
|
else if (verbose == 2)
|
||||||
printf ("%s is %s\n", command, full_path);
|
printf ("%s is %s\n", command, full_path);
|
||||||
else if (verbose == 3 || verbose == 4)
|
else if (verbose == 3 || verbose == 4)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -31,12 +31,22 @@ If MODE begins with a digit, it is interpreted as an octal number,
|
|||||||
otherwise it is a symbolic mode string like that accepted by chmod(1).
|
otherwise it is a symbolic mode string like that accepted by chmod(1).
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <config.h>
|
||||||
#include <sys/types.h>
|
|
||||||
|
#include "../bashtypes.h"
|
||||||
|
#include "../filecntl.h"
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../posixstat.h"
|
#include "../posixstat.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
/* **************************************************************** */
|
/* **************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
@@ -49,47 +59,40 @@ static int symbolic_umask ();
|
|||||||
|
|
||||||
/* Set or display the mask used by the system when creating files. Flag
|
/* Set or display the mask used by the system when creating files. Flag
|
||||||
of -S means display the umask in a symbolic mode. */
|
of -S means display the umask in a symbolic mode. */
|
||||||
|
int
|
||||||
umask_builtin (list)
|
umask_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int print_symbolically = 0;
|
int print_symbolically, opt, umask_value;
|
||||||
|
|
||||||
while (list)
|
print_symbolically = 0;
|
||||||
|
reset_internal_getopt ();
|
||||||
|
while ((opt = internal_getopt (list, "S")) != -1)
|
||||||
{
|
{
|
||||||
if (ISOPTION (list->word->word, 'S'))
|
switch (opt)
|
||||||
{
|
{
|
||||||
list = list->next;
|
case 'S':
|
||||||
print_symbolically++;
|
print_symbolically++;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (ISOPTION (list->word->word, '-'))
|
|
||||||
{
|
|
||||||
list = list->next;
|
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
else if (*(list->word->word) == '-')
|
builtin_usage ();
|
||||||
{
|
|
||||||
bad_option (list->word->word);
|
|
||||||
builtin_error ("usage: umask [-S] [mode]");
|
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
int new_umask;
|
|
||||||
|
|
||||||
if (digit (*list->word->word))
|
if (digit (*list->word->word))
|
||||||
{
|
{
|
||||||
new_umask = read_octal (list->word->word);
|
umask_value = read_octal (list->word->word);
|
||||||
|
|
||||||
/* Note that other shells just let you set the umask to zero
|
/* Note that other shells just let you set the umask to zero
|
||||||
by specifying a number out of range. This is a problem
|
by specifying a number out of range. This is a problem
|
||||||
with those shells. We don't change the umask if the input
|
with those shells. We don't change the umask if the input
|
||||||
is lousy. */
|
is lousy. */
|
||||||
if (new_umask == -1)
|
if (umask_value == -1)
|
||||||
{
|
{
|
||||||
builtin_error ("`%s' is not an octal number from 000 to 777",
|
builtin_error ("`%s' is not an octal number from 000 to 777",
|
||||||
list->word->word);
|
list->word->word);
|
||||||
@@ -98,26 +101,25 @@ umask_builtin (list)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
new_umask = symbolic_umask (list);
|
umask_value = symbolic_umask (list);
|
||||||
if (new_umask == -1)
|
if (umask_value == -1)
|
||||||
return (EXECUTION_FAILURE);
|
return (EXECUTION_FAILURE);
|
||||||
}
|
}
|
||||||
umask (new_umask);
|
umask (umask_value);
|
||||||
if (print_symbolically)
|
if (print_symbolically)
|
||||||
print_symbolic_umask (new_umask);
|
print_symbolic_umask (umask_value);
|
||||||
}
|
}
|
||||||
else /* Display the UMASK for this user. */
|
else /* Display the UMASK for this user. */
|
||||||
{
|
{
|
||||||
int old_umask;
|
umask_value = umask (022);
|
||||||
|
umask (umask_value);
|
||||||
old_umask = umask (022);
|
|
||||||
umask (old_umask);
|
|
||||||
|
|
||||||
if (print_symbolically)
|
if (print_symbolically)
|
||||||
print_symbolic_umask (old_umask);
|
print_symbolic_umask (umask_value);
|
||||||
else
|
else
|
||||||
printf ("%03o\n", old_umask);
|
printf ("%03o\n", umask_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
return (EXECUTION_SUCCESS);
|
return (EXECUTION_SUCCESS);
|
||||||
}
|
}
|
||||||
@@ -176,7 +178,7 @@ symbolic_umask (list)
|
|||||||
um = umask (022);
|
um = umask (022);
|
||||||
umask (um);
|
umask (um);
|
||||||
|
|
||||||
/* All work below is done with the complement of the umask -- its
|
/* All work below is done with the complement of the umask -- it's
|
||||||
more intuitive and easier to deal with. It is complemented
|
more intuitive and easier to deal with. It is complemented
|
||||||
again before being returned. */
|
again before being returned. */
|
||||||
umc = ~um;
|
umc = ~um;
|
||||||
@@ -266,7 +268,7 @@ symbolic_umask (list)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
builtin_error ("bad operation character: %c", op);
|
builtin_error ("bad symbolic mode operator: %c", op);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ 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
|
with Bash; see the file COPYING. If not, write to the Free Software
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
|
||||||
$BUILTIN wait
|
$BUILTIN wait
|
||||||
$FUNCTION wait_builtin
|
$FUNCTION wait_builtin
|
||||||
$DEPENDS_ON JOB_CONTROL
|
$DEPENDS_ON JOB_CONTROL
|
||||||
@@ -42,10 +41,18 @@ and the return code is zero. N is a process ID; if it is not given,
|
|||||||
all child processes of the shell are waited for.
|
all child processes of the shell are waited for.
|
||||||
$END
|
$END
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "../bashtypes.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../shell.h"
|
#include "../shell.h"
|
||||||
#include "../jobs.h"
|
#include "../jobs.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
extern int interrupt_immediately;
|
extern int interrupt_immediately;
|
||||||
|
|
||||||
@@ -53,10 +60,17 @@ extern int interrupt_immediately;
|
|||||||
wait for all of the active background processes of the shell and return
|
wait for all of the active background processes of the shell and return
|
||||||
0. If a list of pids or job specs are given, return the exit status of
|
0. If a list of pids or job specs are given, return the exit status of
|
||||||
the last one waited for. */
|
the last one waited for. */
|
||||||
|
|
||||||
|
#define WAIT_RETURN(s) do { run_unwind_frame ("wait_builtin"); return (s); } while (0)
|
||||||
|
|
||||||
|
int
|
||||||
wait_builtin (list)
|
wait_builtin (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
int status = EXECUTION_SUCCESS;
|
int status;
|
||||||
|
|
||||||
|
if (no_options (list))
|
||||||
|
return (EX_USAGE);
|
||||||
|
|
||||||
begin_unwind_frame ("wait_builtin");
|
begin_unwind_frame ("wait_builtin");
|
||||||
unwind_protect_int (interrupt_immediately);
|
unwind_protect_int (interrupt_immediately);
|
||||||
@@ -67,13 +81,13 @@ wait_builtin (list)
|
|||||||
|
|
||||||
/* But wait without any arguments means to wait for all of the shell's
|
/* But wait without any arguments means to wait for all of the shell's
|
||||||
currently active background processes. */
|
currently active background processes. */
|
||||||
if (!list)
|
if (list == 0)
|
||||||
{
|
{
|
||||||
wait_for_background_pids ();
|
wait_for_background_pids ();
|
||||||
status = EXECUTION_SUCCESS;
|
WAIT_RETURN (EXECUTION_SUCCESS);
|
||||||
goto return_status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = EXECUTION_SUCCESS;
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@@ -89,9 +103,8 @@ wait_builtin (list)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
builtin_error ("`%s' is not a pid or legal job spec", w);
|
builtin_error ("`%s' is not a pid or valid job spec", w);
|
||||||
status = EXECUTION_FAILURE;
|
WAIT_RETURN (EXECUTION_FAILURE);
|
||||||
goto return_status;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined (JOB_CONTROL)
|
#if defined (JOB_CONTROL)
|
||||||
@@ -107,7 +120,7 @@ wait_builtin (list)
|
|||||||
if (job < 0 || job >= job_slots || !jobs[job])
|
if (job < 0 || job >= job_slots || !jobs[job])
|
||||||
{
|
{
|
||||||
if (job != DUP_JOB)
|
if (job != DUP_JOB)
|
||||||
builtin_error ("No such job %s", list->word->word);
|
builtin_error ("%s: no such job", list->word->word);
|
||||||
UNBLOCK_CHILD (oset);
|
UNBLOCK_CHILD (oset);
|
||||||
status = 127; /* As per Posix.2, section 4.70.2 */
|
status = 127; /* As per Posix.2, section 4.70.2 */
|
||||||
list = list->next;
|
list = list->next;
|
||||||
@@ -121,12 +134,11 @@ wait_builtin (list)
|
|||||||
#endif /* JOB_CONTROL */
|
#endif /* JOB_CONTROL */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
builtin_error ("`%s' is not a pid or legal job spec", w);
|
builtin_error ("`%s' is not a pid or valid job spec", w);
|
||||||
status = EXECUTION_FAILURE;
|
status = EXECUTION_FAILURE;
|
||||||
}
|
}
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
return_status:
|
|
||||||
run_unwind_frame ("wait_builtin");
|
WAIT_RETURN (status);
|
||||||
return (status);
|
|
||||||
}
|
}
|
||||||
|
|||||||
56
command.h
56
command.h
@@ -19,8 +19,8 @@
|
|||||||
with Bash; see the file COPYING. If not, write to the Free Software
|
with Bash; see the file COPYING. If not, write to the Free Software
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#if !defined (_COMMAND_H)
|
#if !defined (_COMMAND_H_)
|
||||||
#define _COMMAND_H
|
#define _COMMAND_H_
|
||||||
|
|
||||||
#include "stdc.h"
|
#include "stdc.h"
|
||||||
|
|
||||||
@@ -33,18 +33,45 @@ enum r_instruction {
|
|||||||
r_duplicating_input_word, r_duplicating_output_word
|
r_duplicating_input_word, r_duplicating_output_word
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Redirection errors. */
|
||||||
|
#define AMBIGUOUS_REDIRECT -1
|
||||||
|
#define NOCLOBBER_REDIRECT -2
|
||||||
|
#define RESTRICTED_REDIRECT -3 /* can only happen in restricted shells. */
|
||||||
|
|
||||||
|
#define OUTPUT_REDIRECT(ri) \
|
||||||
|
(ri == r_output_direction || ri == r_input_output || ri == r_err_and_out)
|
||||||
|
|
||||||
|
#define INPUT_REDIRECT(ri) \
|
||||||
|
(ri == r_input_direction || ri == r_inputa_direction || ri == r_input_output)
|
||||||
|
|
||||||
|
#define WRITE_REDIRECT(ri) \
|
||||||
|
(ri == r_output_direction || \
|
||||||
|
ri == r_input_output || \
|
||||||
|
ri == r_err_and_out || \
|
||||||
|
ri == r_appending_to || \
|
||||||
|
ri == r_output_force)
|
||||||
|
|
||||||
/* Command Types: */
|
/* Command Types: */
|
||||||
enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
|
enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
|
||||||
cm_connection, cm_function_def, cm_until, cm_group };
|
cm_connection, cm_function_def, cm_until, cm_group };
|
||||||
|
|
||||||
|
/* Possible values for the `flags' field of a WORD_DESC. */
|
||||||
|
#define W_HASDOLLAR 0x01 /* Dollar sign present. */
|
||||||
|
#define W_QUOTED 0x02 /* Some form of quote character is present. */
|
||||||
|
#define W_ASSIGNMENT 0x04 /* This word is a variable assignment. */
|
||||||
|
#define W_GLOBEXP 0x08 /* This word is the result of a glob expansion. */
|
||||||
|
#define W_NOSPLIT 0x10 /* Do not perform word splitting on this word. */
|
||||||
|
|
||||||
|
/* Possible values for subshell_environment */
|
||||||
|
#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */
|
||||||
|
#define SUBSHELL_PAREN 0x02 /* subshell caused by ( ... ) */
|
||||||
|
#define SUBSHELL_COMSUB 0x04 /* subshell caused by `command` or $(command) */
|
||||||
|
#define SUBSHELL_FORK 0x08 /* subshell caused by executing a disk command */
|
||||||
|
|
||||||
/* A structure which represents a word. */
|
/* A structure which represents a word. */
|
||||||
typedef struct word_desc {
|
typedef struct word_desc {
|
||||||
char *word; /* Zero terminated string. */
|
char *word; /* Zero terminated string. */
|
||||||
int dollar_present; /* Non-zero means dollar sign present. */
|
int flags; /* Flags associated with this word. */
|
||||||
int quoted; /* Non-zero means single, double, or back quote
|
|
||||||
or backslash is present. */
|
|
||||||
int assignment; /* Non-zero means that this word contains an
|
|
||||||
assignment. */
|
|
||||||
} WORD_DESC;
|
} WORD_DESC;
|
||||||
|
|
||||||
/* A linked list of words. */
|
/* A linked list of words. */
|
||||||
@@ -92,6 +119,8 @@ typedef struct element {
|
|||||||
#define CMD_NO_FUNCTIONS 0x10 /* Ignore functions during command lookup. */
|
#define CMD_NO_FUNCTIONS 0x10 /* Ignore functions during command lookup. */
|
||||||
#define CMD_INHIBIT_EXPANSION 0x20 /* Do not expand the command words. */
|
#define CMD_INHIBIT_EXPANSION 0x20 /* Do not expand the command words. */
|
||||||
#define CMD_NO_FORK 0x40 /* Don't fork; just call execve */
|
#define CMD_NO_FORK 0x40 /* Don't fork; just call execve */
|
||||||
|
#define CMD_TIME_PIPELINE 0x80 /* Time a pipeline */
|
||||||
|
#define CMD_TIME_POSIX 0x100 /* time -p; use POSIX.2 time output spec. */
|
||||||
|
|
||||||
/* What a command looks like. */
|
/* What a command looks like. */
|
||||||
typedef struct command {
|
typedef struct command {
|
||||||
@@ -184,19 +213,16 @@ typedef struct simple_com {
|
|||||||
int line; /* line number the command starts on */
|
int line; /* line number the command starts on */
|
||||||
} SIMPLE_COM;
|
} SIMPLE_COM;
|
||||||
|
|
||||||
/* The "function_def" command. This isn't really a command, but it is
|
/* The "function definition" command. */
|
||||||
represented as such for now. If the function def appears within
|
|
||||||
`(' `)' the parser tries to set the SUBSHELL bit of the command. That
|
|
||||||
means that FUNCTION_DEF has to be run through the executor. Maybe this
|
|
||||||
command should be defined in a subshell. Who knows or cares. */
|
|
||||||
typedef struct function_def {
|
typedef struct function_def {
|
||||||
int ignore; /* See description of CMD flags. */
|
int ignore; /* See description of CMD flags. */
|
||||||
WORD_DESC *name; /* The name of the function. */
|
WORD_DESC *name; /* The name of the function. */
|
||||||
COMMAND *command; /* The parsed execution tree. */
|
COMMAND *command; /* The parsed execution tree. */
|
||||||
|
int line; /* Line number the function def starts on. */
|
||||||
} FUNCTION_DEF;
|
} FUNCTION_DEF;
|
||||||
|
|
||||||
/* A command that is `grouped' allows pipes to take effect over
|
/* A command that is `grouped' allows pipes and redirections to affect all
|
||||||
the entire command structure. */
|
commands in the group. */
|
||||||
typedef struct group_com {
|
typedef struct group_com {
|
||||||
int ignore; /* See description of CMD flags. */
|
int ignore; /* See description of CMD flags. */
|
||||||
COMMAND *command;
|
COMMAND *command;
|
||||||
@@ -212,4 +238,4 @@ extern REDIRECT *copy_redirect __P((REDIRECT *));
|
|||||||
extern REDIRECT *copy_redirects __P((REDIRECT *));
|
extern REDIRECT *copy_redirects __P((REDIRECT *));
|
||||||
extern COMMAND *copy_command __P((COMMAND *));
|
extern COMMAND *copy_command __P((COMMAND *));
|
||||||
|
|
||||||
#endif /* _COMMAND_H */
|
#endif /* _COMMAND_H_ */
|
||||||
|
|||||||
186
config.h
186
config.h
@@ -1,186 +0,0 @@
|
|||||||
/* config.h -- Configuration file for bash. */
|
|
||||||
|
|
||||||
/* Copyright (C) 1987,1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|
||||||
|
|
||||||
#if !defined (_CONFIG_H_)
|
|
||||||
#define _CONFIG_H_
|
|
||||||
|
|
||||||
#if !defined (BUILDING_MAKEFILE)
|
|
||||||
#include "memalloc.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (HAVE_UNISTD_H) && !defined (BUILDING_MAKEFILE)
|
|
||||||
# ifdef CRAY
|
|
||||||
# define word __word
|
|
||||||
# endif
|
|
||||||
#include <unistd.h>
|
|
||||||
# ifdef CRAY
|
|
||||||
# undef word
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define JOB_CONTROL if your operating system supports
|
|
||||||
BSD-like job control. */
|
|
||||||
#define JOB_CONTROL
|
|
||||||
|
|
||||||
/* Note that vanilla System V machines don't support BSD job control,
|
|
||||||
although some do support Posix job control. */
|
|
||||||
#if defined (USG) || defined (MINIX) || defined (Minix)
|
|
||||||
# if !defined (_POSIX_JOB_CONTROL)
|
|
||||||
# undef JOB_CONTROL
|
|
||||||
# endif /* !_POSIX_JOB_CONTROL */
|
|
||||||
#endif /* USG || Minix || MINIX */
|
|
||||||
|
|
||||||
/* Define ALIAS if you want the alias features. */
|
|
||||||
#define ALIAS
|
|
||||||
|
|
||||||
/* Define PUSHD_AND_POPD if you want those commands to be compiled in.
|
|
||||||
(Also the `dirs' commands.) */
|
|
||||||
#define PUSHD_AND_POPD
|
|
||||||
|
|
||||||
/* Define BRACE_EXPANSION if you want curly brace expansion a la Csh:
|
|
||||||
foo{a,b} -> fooa foob. Even if this is compiled in (the default) you
|
|
||||||
can turn it off at shell startup with `-nobraceexpansion', or during
|
|
||||||
shell execution with `set +o braceexpand'. */
|
|
||||||
#define BRACE_EXPANSION
|
|
||||||
|
|
||||||
/* Define READLINE to get the nifty/glitzy editing features.
|
|
||||||
This is on by default. You can turn it off interactively
|
|
||||||
with the -nolineediting flag. */
|
|
||||||
#define READLINE
|
|
||||||
|
|
||||||
/* Define BANG_HISTORY if you want to have Csh style "!" history expansion.
|
|
||||||
This is unrelated to READLINE. */
|
|
||||||
#define BANG_HISTORY
|
|
||||||
|
|
||||||
/* Define HISTORY if you want to have access to previously typed commands.
|
|
||||||
|
|
||||||
If both HISTORY and READLINE are defined, you can get at the commands
|
|
||||||
with line editing commands, and you can directly manipulate the history
|
|
||||||
from the command line.
|
|
||||||
|
|
||||||
If only HISTORY is defined, the `fc' and `history' builtins are
|
|
||||||
available. */
|
|
||||||
#define HISTORY
|
|
||||||
|
|
||||||
#if defined (BANG_HISTORY) && !defined (HISTORY)
|
|
||||||
/* BANG_HISTORY requires HISTORY. */
|
|
||||||
# define HISTORY
|
|
||||||
#endif /* BANG_HISTORY && !HISTORY */
|
|
||||||
|
|
||||||
#if defined (READLINE) && !defined (HISTORY)
|
|
||||||
# define HISTORY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The default value of the PATH variable. */
|
|
||||||
#define DEFAULT_PATH_VALUE \
|
|
||||||
"/usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin:."
|
|
||||||
|
|
||||||
/* The value for PATH when invoking `command -p'. This is only used when
|
|
||||||
the Posix.2 confstr () function, or CS_PATH define are not present. */
|
|
||||||
#define STANDARD_UTILS_PATH \
|
|
||||||
"/bin:/usr/bin:/usr/ucb:/usr/sbin:/sbin:/etc:/usr/etc:/usr/lib"
|
|
||||||
|
|
||||||
/* Put system-specific default mail directories here. */
|
|
||||||
#if defined (__bsdi__) || defined (__FreeBSD__) || defined (__NetBSD__)
|
|
||||||
# define DEFAULT_MAIL_PATH "/var/mail/"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined (DEFAULT_MAIL_PATH)
|
|
||||||
#if defined (USG)
|
|
||||||
# define DEFAULT_MAIL_PATH "/usr/mail/"
|
|
||||||
#else
|
|
||||||
# define DEFAULT_MAIL_PATH "/usr/spool/mail/"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define V9_ECHO if you want to give the echo builtin backslash-escape
|
|
||||||
interpretation using the -e option, in the style of the Bell Labs 9th
|
|
||||||
Edition version of echo. */
|
|
||||||
#define V9_ECHO
|
|
||||||
|
|
||||||
/* Define DEFAULT_ECHO_TO_USG if you want the echo builtin to interpret
|
|
||||||
the backslash-escape characters by default, like the System V echo.
|
|
||||||
This requires that V9_ECHO be defined. */
|
|
||||||
/* #define DEFAULT_ECHO_TO_USG */
|
|
||||||
#if !defined (V9_ECHO)
|
|
||||||
# undef DEFAULT_ECHO_TO_USG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define CONTINUE_AFTER_KILL_ERROR if you want the kill command to
|
|
||||||
continue processing arguments after one of them fails. */
|
|
||||||
#define CONTINUE_AFTER_KILL_ERROR
|
|
||||||
|
|
||||||
/* Define BREAK_COMPLAINS if you want the non-standard, but useful
|
|
||||||
error messages about `break' and `continue' out of context. */
|
|
||||||
#define BREAK_COMPLAINS
|
|
||||||
|
|
||||||
/* Define GETOPTS_BUILTIN if you want the Posix.2 `getopts' shell builtin
|
|
||||||
compiled into the shell. */
|
|
||||||
#define GETOPTS_BUILTIN
|
|
||||||
|
|
||||||
/* When ALLOW_RIGID_POSIX_COMPLIANCE is defined, you can turn on strictly
|
|
||||||
Posix compliant behaviour by setting the environment variable
|
|
||||||
POSIXLY_CORRECT. */
|
|
||||||
#define ALLOW_RIGID_POSIX_COMPLIANCE
|
|
||||||
|
|
||||||
/* Define RESTRICTED_SHELL if you want the generated shell to have the
|
|
||||||
ability to be a restricted one. The shell thus generated can become
|
|
||||||
restricted by being run with the name "rbash", or by setting the -r
|
|
||||||
flag. */
|
|
||||||
/* #define RESTRICTED_SHELL */
|
|
||||||
|
|
||||||
/* Define DISABLED_BUILTINS if you want "builtin foo" to always run the
|
|
||||||
shell builtin "foo", even if it has been disabled with "enable -n foo". */
|
|
||||||
/* #define DISABLED_BUILTINS */
|
|
||||||
|
|
||||||
/* Define PROCESS_SUBSTITUTION if you want the K*rn shell-like process
|
|
||||||
substitution features "<(file)". */
|
|
||||||
/* Right now, you cannot do this on machines without fully operational
|
|
||||||
FIFO support. This currently include NeXT and Alliant. */
|
|
||||||
#if !defined (MKFIFO_MISSING) || defined (HAVE_DEV_FD)
|
|
||||||
# define PROCESS_SUBSTITUTION
|
|
||||||
#endif /* !MKFIFO_MISSING */
|
|
||||||
|
|
||||||
/* Define PROMPT_STRING_DECODE if you want the backslash-escaped special
|
|
||||||
characters in PS1 and PS2 expanded. Variable expansion will still be
|
|
||||||
performed. */
|
|
||||||
#define PROMPT_STRING_DECODE
|
|
||||||
|
|
||||||
/* Define BUFFERED_INPUT if you want the shell to do its own input
|
|
||||||
buffering. */
|
|
||||||
#define BUFFERED_INPUT
|
|
||||||
|
|
||||||
/* Define INTERACTIVE_COMMENTS if you want # comments to work by default
|
|
||||||
when the shell is interactive, as Posix.2a specifies. */
|
|
||||||
#define INTERACTIVE_COMMENTS
|
|
||||||
|
|
||||||
/* Define ONESHOT if you want sh -c 'command' to avoid forking to execute
|
|
||||||
`command' whenever possible. */
|
|
||||||
#define ONESHOT
|
|
||||||
|
|
||||||
/* Default primary and secondary prompt strings. */
|
|
||||||
#define PPROMPT "bash\\$ "
|
|
||||||
#define SPROMPT "> "
|
|
||||||
|
|
||||||
/* Define SELECT_COMMAND if you want the Korn-shell style `select' command:
|
|
||||||
select word in word_list; do command_list; done */
|
|
||||||
#define SELECT_COMMAND
|
|
||||||
|
|
||||||
#endif /* !_CONFIG_H_ */
|
|
||||||
63
config.h.bot
Normal file
63
config.h.bot
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/* config.h.bot */
|
||||||
|
/* modify settings or make new ones based on what autoconf tells us. */
|
||||||
|
|
||||||
|
#if !defined (HAVE_VPRINTF) && defined (HAVE_DOPRNT)
|
||||||
|
# define USE_VFPRINTF_EMULATION
|
||||||
|
# define HAVE_VPRINTF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Ultrix botches type-ahead when switching from canonical to
|
||||||
|
non-canonical mode, at least through version 4.3 */
|
||||||
|
#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix)
|
||||||
|
# define TERMIOS_MISSING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If we have a getcwd(3), but it calls popen(), #undef HAVE_GETCWD so
|
||||||
|
the replacement in getcwd.c will be built. */
|
||||||
|
#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN)
|
||||||
|
# undef HAVE_GETCWD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (HAVE_SYS_RESOURCE_H) && defined (HAVE_GETRLIMIT)
|
||||||
|
# define HAVE_RESOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined (GETPGRP_VOID)
|
||||||
|
# define HAVE_BSD_PGRP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined (HAVE_DEV_FD) && defined (NAMED_PIPES_MISSING)
|
||||||
|
# undef PROCESS_SUBSTITUTION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If the shell is called by this name, it will become restricted. */
|
||||||
|
#if defined (RESTRICTED_SHELL)
|
||||||
|
# define RESTRICTED_SHELL_NAME "rbash"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* BANG_HISTORY requires HISTORY. */
|
||||||
|
#if defined (BANG_HISTORY) && !defined (HISTORY)
|
||||||
|
# define HISTORY
|
||||||
|
#endif /* BANG_HISTORY && !HISTORY */
|
||||||
|
|
||||||
|
#if defined (READLINE) && !defined (HISTORY)
|
||||||
|
# define HISTORY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined (V9_ECHO)
|
||||||
|
# undef DEFAULT_ECHO_TO_USG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (JOB_CONTROL_MISSING)
|
||||||
|
# undef JOB_CONTROL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (__STDC__) && defined (HAVE_STDARG_H)
|
||||||
|
# define PREFER_STDARG
|
||||||
|
# define USE_VARARGS
|
||||||
|
#else
|
||||||
|
# if defined (HAVE_VARARGS_H)
|
||||||
|
# define PREFER_VARARGS
|
||||||
|
# define USE_VARARGS
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
505
config.h.in
Normal file
505
config.h.in
Normal file
@@ -0,0 +1,505 @@
|
|||||||
|
/* config.h -- Configuration file for bash. */
|
||||||
|
|
||||||
|
/* Copyright (C) 1987,1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef _CONFIG_H_
|
||||||
|
#define _CONFIG_H_
|
||||||
|
|
||||||
|
/* Configuration settings controllable by autoconf. */
|
||||||
|
|
||||||
|
/* Define JOB_CONTROL if your operating system supports
|
||||||
|
BSD-like job control. */
|
||||||
|
#undef JOB_CONTROL
|
||||||
|
|
||||||
|
/* Define ALIAS if you want the alias features. */
|
||||||
|
#undef ALIAS
|
||||||
|
|
||||||
|
/* Define PUSHD_AND_POPD if you want those commands to be compiled in.
|
||||||
|
(Also the `dirs' commands.) */
|
||||||
|
#undef PUSHD_AND_POPD
|
||||||
|
|
||||||
|
/* Define BRACE_EXPANSION if you want curly brace expansion a la Csh:
|
||||||
|
foo{a,b} -> fooa foob. Even if this is compiled in (the default) you
|
||||||
|
can turn it off at shell startup with `-nobraceexpansion', or during
|
||||||
|
shell execution with `set +o braceexpand'. */
|
||||||
|
#undef BRACE_EXPANSION
|
||||||
|
|
||||||
|
/* Define READLINE to get the nifty/glitzy editing features.
|
||||||
|
This is on by default. You can turn it off interactively
|
||||||
|
with the -nolineediting flag. */
|
||||||
|
#undef READLINE
|
||||||
|
|
||||||
|
/* Define BANG_HISTORY if you want to have Csh style "!" history expansion.
|
||||||
|
This is unrelated to READLINE. */
|
||||||
|
#undef BANG_HISTORY
|
||||||
|
|
||||||
|
/* Define HISTORY if you want to have access to previously typed commands.
|
||||||
|
|
||||||
|
If both HISTORY and READLINE are defined, you can get at the commands
|
||||||
|
with line editing commands, and you can directly manipulate the history
|
||||||
|
from the command line.
|
||||||
|
|
||||||
|
If only HISTORY is defined, the `fc' and `history' builtins are
|
||||||
|
available. */
|
||||||
|
#undef HISTORY
|
||||||
|
|
||||||
|
/* Define this if you want completion that puts all alternatives into
|
||||||
|
a brace expansion shell expression. */
|
||||||
|
#if defined (BRACE_EXPANSION) && defined (READLINE)
|
||||||
|
# define BRACE_COMPLETION
|
||||||
|
#endif /* BRACE_EXPANSION */
|
||||||
|
|
||||||
|
/* Define DEFAULT_ECHO_TO_USG if you want the echo builtin to interpret
|
||||||
|
the backslash-escape characters by default, like the System V echo.
|
||||||
|
This requires that V9_ECHO be defined. */
|
||||||
|
#undef DEFAULT_ECHO_TO_USG
|
||||||
|
|
||||||
|
/* Define HELP_BUILTIN if you want the `help' shell builtin and the long
|
||||||
|
documentation strings compiled into the shell. */
|
||||||
|
#undef HELP_BUILTIN
|
||||||
|
|
||||||
|
/* Define RESTRICTED_SHELL if you want the generated shell to have the
|
||||||
|
ability to be a restricted one. The shell thus generated can become
|
||||||
|
restricted by being run with the name "rbash", or by setting the -r
|
||||||
|
flag. */
|
||||||
|
#undef RESTRICTED_SHELL
|
||||||
|
|
||||||
|
/* Define DISABLED_BUILTINS if you want "builtin foo" to always run the
|
||||||
|
shell builtin "foo", even if it has been disabled with "enable -n foo". */
|
||||||
|
#undef DISABLED_BUILTINS
|
||||||
|
|
||||||
|
/* Define PROCESS_SUBSTITUTION if you want the K*rn shell-like process
|
||||||
|
substitution features "<(file)". */
|
||||||
|
/* Right now, you cannot do this on machines without fully operational
|
||||||
|
FIFO support. This currently include NeXT and Alliant. */
|
||||||
|
#undef PROCESS_SUBSTITUTION
|
||||||
|
|
||||||
|
/* Define PROMPT_STRING_DECODE if you want the backslash-escaped special
|
||||||
|
characters in PS1 and PS2 expanded. Variable expansion will still be
|
||||||
|
performed. */
|
||||||
|
#undef PROMPT_STRING_DECODE
|
||||||
|
|
||||||
|
/* Define SELECT_COMMAND if you want the Korn-shell style `select' command:
|
||||||
|
select word in word_list; do command_list; done */
|
||||||
|
#undef SELECT_COMMAND
|
||||||
|
|
||||||
|
/* Define COMMAND_TIMING of you want the ksh-style `time' reserved word and
|
||||||
|
the ability to time pipelines, functions, and builtins. */
|
||||||
|
#undef COMMAND_TIMING
|
||||||
|
|
||||||
|
/* Define ARRAY_VARS if you want ksh-style one-dimensional array variables. */
|
||||||
|
#undef ARRAY_VARS
|
||||||
|
|
||||||
|
/* Define DPAREN_ARITHMETIC if you want the ksh-style ((...)) arithmetic
|
||||||
|
evaluation command. */
|
||||||
|
#undef DPAREN_ARITHMETIC
|
||||||
|
|
||||||
|
/* Define AFS if you are using Transarc's AFS. */
|
||||||
|
#undef AFS
|
||||||
|
|
||||||
|
/* End of configuration settings controllable by autoconf. */
|
||||||
|
/* Other settable options appear in config.h.top. */
|
||||||
|
|
||||||
|
#include "config.h.top"
|
||||||
|
|
||||||
|
/* Beginning of autoconf additions. */
|
||||||
|
|
||||||
|
/* Define if using alloca.c. */
|
||||||
|
#undef C_ALLOCA
|
||||||
|
|
||||||
|
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||||
|
This function is required for alloca.c support on those systems. */
|
||||||
|
#undef CRAY_STACKSEG_END
|
||||||
|
|
||||||
|
/* Define to the type of elements in the array set by `getgroups'.
|
||||||
|
Usually this is either `int' or `gid_t'. */
|
||||||
|
#undef GETGROUPS_T
|
||||||
|
|
||||||
|
/* Define if the `getpgrp' function takes no argument. */
|
||||||
|
#undef GETPGRP_VOID
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
#undef gid_t
|
||||||
|
|
||||||
|
/* Define if you have alloca, as a function or macro. */
|
||||||
|
#undef HAVE_ALLOCA
|
||||||
|
|
||||||
|
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||||
|
#undef HAVE_ALLOCA_H
|
||||||
|
|
||||||
|
/* Define if you don't have vprintf but do have _doprnt. */
|
||||||
|
#undef HAVE_DOPRNT
|
||||||
|
|
||||||
|
/* Define if system calls automatically restart after interruption
|
||||||
|
by a signal. */
|
||||||
|
#undef HAVE_RESTARTABLE_SYSCALLS
|
||||||
|
|
||||||
|
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||||
|
#undef HAVE_SYS_WAIT_H
|
||||||
|
|
||||||
|
/* Define if you have <sys/time.h> */
|
||||||
|
#undef HAVE_SYS_TIME_H
|
||||||
|
|
||||||
|
#undef TIME_WITH_SYS_TIME
|
||||||
|
|
||||||
|
#undef HAVE_SYS_TIMES_H
|
||||||
|
|
||||||
|
/* Define if you have the vprintf function. */
|
||||||
|
#undef HAVE_VPRINTF
|
||||||
|
|
||||||
|
#undef HAVE_WAIT3
|
||||||
|
|
||||||
|
#undef HAVE_SETOSTYPE
|
||||||
|
|
||||||
|
/* Define if on MINIX. */
|
||||||
|
#undef _MINIX
|
||||||
|
|
||||||
|
/* Define to `long' if <sys/types.h> doesn't define. */
|
||||||
|
#undef off_t
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
#undef mode_t
|
||||||
|
|
||||||
|
/* Define to `int' if <signal.h> doesn't define. */
|
||||||
|
#undef sigset_t
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
#undef pid_t
|
||||||
|
|
||||||
|
/* Define if the system does not provide POSIX.1 features except
|
||||||
|
with this defined. */
|
||||||
|
#undef _POSIX_1_SOURCE
|
||||||
|
|
||||||
|
/* Define if you need to in order for stat and other things to work. */
|
||||||
|
#undef _POSIX_SOURCE
|
||||||
|
|
||||||
|
/* Define as the return type of signal handlers (int or void). */
|
||||||
|
#undef RETSIGTYPE
|
||||||
|
|
||||||
|
/* Define if the setvbuf function takes the buffering type as its second
|
||||||
|
argument and the buffer pointer as the third, as on System V
|
||||||
|
before release 3. */
|
||||||
|
#undef SETVBUF_REVERSED
|
||||||
|
|
||||||
|
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||||
|
#undef size_t
|
||||||
|
|
||||||
|
/* If using the C implementation of alloca, define if you know the
|
||||||
|
direction of stack growth for your system; otherwise it will be
|
||||||
|
automatically deduced at run-time.
|
||||||
|
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||||
|
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||||
|
STACK_DIRECTION = 0 => direction of growth unknown
|
||||||
|
*/
|
||||||
|
#undef STACK_DIRECTION
|
||||||
|
|
||||||
|
/* Define if you have the ANSI C header files. */
|
||||||
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
|
/* Define if `sys_siglist' is declared by <signal.h>. */
|
||||||
|
#undef SYS_SIGLIST_DECLARED
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
#undef uid_t
|
||||||
|
|
||||||
|
/* Define to `long' if <sys/types.h> doesn't define. */
|
||||||
|
#undef clock_t
|
||||||
|
|
||||||
|
/* Define to `long' if <sys/types.h> doesn't define. */
|
||||||
|
#undef time_t
|
||||||
|
|
||||||
|
#undef DUP2_BROKEN
|
||||||
|
|
||||||
|
#undef HAVE_GETRLIMIT
|
||||||
|
|
||||||
|
#undef HAVE_GETRUSAGE
|
||||||
|
|
||||||
|
#undef HAVE_GETTIMEOFDAY
|
||||||
|
|
||||||
|
#undef GWINSZ_IN_SYS_IOCTL
|
||||||
|
|
||||||
|
#undef TIOCSTAT_IN_SYS_IOCTL
|
||||||
|
|
||||||
|
#undef FIONREAD_IN_SYS_IOCTL
|
||||||
|
|
||||||
|
#undef WORDS_BIGENDIAN
|
||||||
|
|
||||||
|
#undef HAVE_HASH_BANG_EXEC
|
||||||
|
|
||||||
|
#undef HAVE_BSD_SIGNALS
|
||||||
|
|
||||||
|
#undef HAVE_POSIX_SIGNALS
|
||||||
|
|
||||||
|
#undef HAVE_USG_SIGHOLD
|
||||||
|
|
||||||
|
#undef HAVE_DEV_FD
|
||||||
|
|
||||||
|
#undef DEV_FD_PREFIX
|
||||||
|
|
||||||
|
#undef HAVE_GETPW_DECLS
|
||||||
|
|
||||||
|
#undef HAVE_QUAD_T
|
||||||
|
|
||||||
|
#undef HAVE_RESOURCE
|
||||||
|
|
||||||
|
#undef HAVE_STRSIGNAL
|
||||||
|
|
||||||
|
#undef HAVE_SYS_ERRLIST
|
||||||
|
|
||||||
|
#undef STAT_MACROS_BROKEN
|
||||||
|
|
||||||
|
#undef HAVE_TIMEVAL
|
||||||
|
|
||||||
|
#undef HAVE_MEMMOVE
|
||||||
|
|
||||||
|
#undef HAVE_MKFIFO
|
||||||
|
|
||||||
|
#undef NAMED_PIPES_MISSING
|
||||||
|
|
||||||
|
#undef OPENDIR_NOT_ROBUST
|
||||||
|
|
||||||
|
#undef PGRP_PIPE
|
||||||
|
|
||||||
|
#undef RLIMTYPE
|
||||||
|
|
||||||
|
#undef SBRK_DECLARED
|
||||||
|
|
||||||
|
#undef PRINTF_DECLARED
|
||||||
|
|
||||||
|
#undef HAVE_SYS_SIGLIST
|
||||||
|
|
||||||
|
#undef HAVE_TIMES
|
||||||
|
|
||||||
|
#undef HAVE_UNDER_SYS_SIGLIST
|
||||||
|
|
||||||
|
#undef VOID_SIGHANDLER
|
||||||
|
|
||||||
|
#undef TERMIOS_LDISC
|
||||||
|
|
||||||
|
#undef TERMIO_LDISC
|
||||||
|
|
||||||
|
#undef ULIMIT_MAXFDS
|
||||||
|
|
||||||
|
#undef GETCWD_BROKEN
|
||||||
|
|
||||||
|
#undef STRUCT_DIRENT_HAS_D_INO
|
||||||
|
|
||||||
|
#undef CAN_REDEFINE_GETENV
|
||||||
|
|
||||||
|
#undef MUST_REINSTALL_SIGHANDLERS
|
||||||
|
|
||||||
|
#undef JOB_CONTROL_MISSING
|
||||||
|
|
||||||
|
#undef HAVE_POSIX_SIGSETJMP
|
||||||
|
|
||||||
|
#define DEFAULT_MAIL_DIRECTORY "/usr/spool/mail"
|
||||||
|
|
||||||
|
/* Define if you have the bcopy function. */
|
||||||
|
#undef HAVE_BCOPY
|
||||||
|
|
||||||
|
/* Define if you have the bzero function. */
|
||||||
|
#undef HAVE_BZERO
|
||||||
|
|
||||||
|
/* Define if you have the confstr function. */
|
||||||
|
#undef HAVE_CONFSTR
|
||||||
|
|
||||||
|
/* Define if you have the dlclose function. */
|
||||||
|
#undef HAVE_DLCLOSE
|
||||||
|
|
||||||
|
/* Define if you have the dlopen function. */
|
||||||
|
#undef HAVE_DLOPEN
|
||||||
|
|
||||||
|
/* Define if you have the dlsym function. */
|
||||||
|
#undef HAVE_DLSYM
|
||||||
|
|
||||||
|
/* Define if you have the dup2 function. */
|
||||||
|
#undef HAVE_DUP2
|
||||||
|
|
||||||
|
/* Define if you have the getcwd function. */
|
||||||
|
#undef HAVE_GETCWD
|
||||||
|
|
||||||
|
/* Define if you have the getdtablesize function. */
|
||||||
|
#undef HAVE_GETDTABLESIZE
|
||||||
|
|
||||||
|
/* Define if you have the getgroups function. */
|
||||||
|
#undef HAVE_GETGROUPS
|
||||||
|
|
||||||
|
/* Define if you have the gethostname function. */
|
||||||
|
#undef HAVE_GETHOSTNAME
|
||||||
|
|
||||||
|
/* Define if you have the getpagesize function. */
|
||||||
|
#undef HAVE_GETPAGESIZE
|
||||||
|
|
||||||
|
/* Define if you have the getpeername function. */
|
||||||
|
#undef HAVE_GETPEERNAME
|
||||||
|
|
||||||
|
/* Define if you have the getwd function. */
|
||||||
|
#undef HAVE_GETWD
|
||||||
|
|
||||||
|
/* Define if you have the killpg function. */
|
||||||
|
#undef HAVE_KILLPG
|
||||||
|
|
||||||
|
#undef HAVE_LSTAT
|
||||||
|
|
||||||
|
/* Define if you have the putenv function. */
|
||||||
|
#undef HAVE_PUTENV
|
||||||
|
|
||||||
|
/* Define if you have the select function. */
|
||||||
|
#undef HAVE_SELECT
|
||||||
|
|
||||||
|
/* Define if you have the setdtablesize function. */
|
||||||
|
#undef HAVE_SETDTABLESIZE
|
||||||
|
|
||||||
|
/* Define if you have the setenv function. */
|
||||||
|
#undef HAVE_SETENV
|
||||||
|
|
||||||
|
/* Define if you have the setlinebuf function. */
|
||||||
|
#undef HAVE_SETLINEBUF
|
||||||
|
|
||||||
|
/* Define if you have the setlocale function. */
|
||||||
|
#undef HAVE_SETLOCALE
|
||||||
|
|
||||||
|
#undef HAVE_SIGINTERRUPT
|
||||||
|
|
||||||
|
/* Define if you have the strcasecmp function. */
|
||||||
|
#undef HAVE_STRCASECMP
|
||||||
|
|
||||||
|
/* Define if you have the strchr function. */
|
||||||
|
#undef HAVE_STRCHR
|
||||||
|
|
||||||
|
/* Define if you have the strerror function. */
|
||||||
|
#undef HAVE_STRERROR
|
||||||
|
|
||||||
|
/* Define if you have the tcgetattr function. */
|
||||||
|
#undef HAVE_TCGETATTR
|
||||||
|
|
||||||
|
/* Define if you have the sysconf function. */
|
||||||
|
#undef HAVE_SYSCONF
|
||||||
|
|
||||||
|
/* Define if you have the uname function. */
|
||||||
|
#undef HAVE_UNAME
|
||||||
|
|
||||||
|
/* Define if you have the ulimit function. */
|
||||||
|
#undef HAVE_ULIMIT
|
||||||
|
|
||||||
|
#undef HAVE_WAITPID
|
||||||
|
|
||||||
|
#undef HAVE_TCGETPGRP
|
||||||
|
|
||||||
|
#undef HAVE_GETTEXT
|
||||||
|
|
||||||
|
#undef HAVE_TEXTDOMAIN
|
||||||
|
|
||||||
|
#undef HAVE_BINDTEXTDOMAIN
|
||||||
|
|
||||||
|
#undef HAVE_STRCOLL
|
||||||
|
|
||||||
|
#undef HAVE_TZSET
|
||||||
|
|
||||||
|
/* Define if you have the <dirent.h> header file. */
|
||||||
|
#undef HAVE_DIRENT_H
|
||||||
|
|
||||||
|
/* Define if you have the <limits.h> header file. */
|
||||||
|
#undef HAVE_LIMITS_H
|
||||||
|
|
||||||
|
/* Define if you have the <locale.h> header file. */
|
||||||
|
#undef HAVE_LOCALE_H
|
||||||
|
|
||||||
|
/* Define if you have the <ndir.h> header file. */
|
||||||
|
#undef HAVE_NDIR_H
|
||||||
|
|
||||||
|
/* Define if you have the <stdlib.h> header file. */
|
||||||
|
#undef HAVE_STDLIB_H
|
||||||
|
|
||||||
|
/* Define if you have the <stdarg.h> header file. */
|
||||||
|
#undef HAVE_STDARG_H
|
||||||
|
|
||||||
|
/* Define if you have the <string.h> header file. */
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
|
||||||
|
/* Define if you have the <memory.h> header file. */
|
||||||
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/dir.h> header file. */
|
||||||
|
#undef HAVE_SYS_DIR_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/file.h> header file. */
|
||||||
|
#undef HAVE_SYS_FILE_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/ndir.h> header file. */
|
||||||
|
#undef HAVE_SYS_NDIR_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/param.h> header file. */
|
||||||
|
#undef HAVE_SYS_PARAM_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/pte.h> header file. */
|
||||||
|
#undef HAVE_SYS_PTE_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/ptem.h> header file. */
|
||||||
|
#undef HAVE_SYS_PTEM_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/resource.h> header file. */
|
||||||
|
#undef HAVE_SYS_RESOURCE_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/select.h> header file. */
|
||||||
|
#undef HAVE_SYS_SELECT_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/socket.h> header file. */
|
||||||
|
#undef HAVE_SYS_SOCKET_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/stream.h> header file. */
|
||||||
|
#undef HAVE_SYS_STREAM_H
|
||||||
|
|
||||||
|
/* Define if you have the <termcap.h> header file. */
|
||||||
|
#undef HAVE_TERMCAP_H
|
||||||
|
|
||||||
|
/* Define if you have the <termio.h> header file. */
|
||||||
|
#undef HAVE_TERMIO_H
|
||||||
|
|
||||||
|
/* Define if you have the <termios.h> header file. */
|
||||||
|
#undef HAVE_TERMIOS_H
|
||||||
|
|
||||||
|
/* Define if you have the <unistd.h> header file. */
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Define if you have the <varargs.h> header file. */
|
||||||
|
#undef HAVE_VARARGS_H
|
||||||
|
|
||||||
|
/* Define if you have the <libintl.h> header file. */
|
||||||
|
#undef HAVE_LIBINTL_H
|
||||||
|
|
||||||
|
#undef HAVE_LIBDL
|
||||||
|
|
||||||
|
#undef HAVE_LIBSUN
|
||||||
|
|
||||||
|
#undef HAVE_LIBSOCKET
|
||||||
|
|
||||||
|
/* Are we running SVR4.2? */
|
||||||
|
#undef SVR4_2
|
||||||
|
|
||||||
|
/* Are we running some version of SVR4? */
|
||||||
|
#undef SVR4
|
||||||
|
|
||||||
|
/* Do we need to define _KERNEL to get the RLIMIT_* defines from
|
||||||
|
<sys/resource.h>? */
|
||||||
|
#undef RLIMIT_NEEDS_KERNEL
|
||||||
|
|
||||||
|
#include "config.h.bot"
|
||||||
|
|
||||||
|
#endif /* _CONFIG_H_ */
|
||||||
194
config.h.mini
194
config.h.mini
@@ -1,194 +0,0 @@
|
|||||||
/* config.h -- Configuration file for bash. */
|
|
||||||
|
|
||||||
/* This is a `minimal' configuration file. It will create a shell without:
|
|
||||||
job control
|
|
||||||
aliases
|
|
||||||
pushd and popd
|
|
||||||
readline
|
|
||||||
history
|
|
||||||
restricted shell mode
|
|
||||||
`disabled' builtins (builtin xxx finds xxx even after enable -n xxx)
|
|
||||||
process substitution
|
|
||||||
prompt string decoding (though variable expansion is still done)
|
|
||||||
the `select' command */
|
|
||||||
|
|
||||||
/* Copyright (C) 1987,1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|
||||||
|
|
||||||
#if !defined (_CONFIG_H_)
|
|
||||||
#define _CONFIG_H_
|
|
||||||
|
|
||||||
#include "memalloc.h"
|
|
||||||
|
|
||||||
#if defined (HPUX) || defined (UNIXPC) || defined (Xenix)
|
|
||||||
# if !defined (USG)
|
|
||||||
# define USG
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (HAVE_UNISTD_H) && !defined (BUILDING_MAKEFILE)
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define JOB_CONTROL if your operating system supports
|
|
||||||
BSD-like job control. */
|
|
||||||
/* #define JOB_CONTROL */
|
|
||||||
|
|
||||||
/* Note that vanilla System V machines don't support BSD job control,
|
|
||||||
although some do support Posix job control. */
|
|
||||||
#if defined (USG) && !defined (_POSIX_JOB_CONTROL)
|
|
||||||
# undef JOB_CONTROL
|
|
||||||
#endif /* USG && !_POSIX_JOB_CONTROL */
|
|
||||||
|
|
||||||
/* Define ALIAS if you want the alias features. */
|
|
||||||
/* #define ALIAS */
|
|
||||||
|
|
||||||
/* Define PUSHD_AND_POPD if you want those commands to be compiled in.
|
|
||||||
(Also the `dirs' commands.) */
|
|
||||||
/* #define PUSHD_AND_POPD */
|
|
||||||
|
|
||||||
/* Define BRACE_EXPANSION if you want curly brace expansion a la Csh:
|
|
||||||
foo{a,b} -> fooa foob. Even if this is compiled in (the default) you
|
|
||||||
can turn it off at shell startup with `-nobraceexpansion', or during
|
|
||||||
shell execution with `set +o braceexpand'. */
|
|
||||||
/* #define BRACE_EXPANSION */
|
|
||||||
|
|
||||||
/* Define READLINE to get the nifty/glitzy editing features.
|
|
||||||
This is on by default. You can turn it off interactively
|
|
||||||
with the -nolineediting flag. */
|
|
||||||
/* #define READLINE */
|
|
||||||
|
|
||||||
/* Define BANG_HISTORY if you want to have Csh style "!" history expansion.
|
|
||||||
This is unrelated to READLINE. */
|
|
||||||
/* #define BANG_HISTORY */
|
|
||||||
|
|
||||||
/* Define HISTORY if you want to have access to previously typed commands.
|
|
||||||
|
|
||||||
If both HISTORY and READLINE are defined, you can get at the commands
|
|
||||||
with line editing commands, and you can directly manipulate the history
|
|
||||||
from the command line.
|
|
||||||
|
|
||||||
If only HISTORY is defined, the `fc' and `history' builtins are
|
|
||||||
available. */
|
|
||||||
/* #define HISTORY */
|
|
||||||
|
|
||||||
#if defined (BANG_HISTORY) && !defined (HISTORY)
|
|
||||||
/* BANG_HISTORY requires HISTORY. */
|
|
||||||
# define HISTORY
|
|
||||||
#endif /* BANG_HISTORY && !HISTORY */
|
|
||||||
|
|
||||||
#if defined (READLINE) && !defined (HISTORY)
|
|
||||||
# define HISTORY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The default value of the PATH variable. */
|
|
||||||
#define DEFAULT_PATH_VALUE \
|
|
||||||
"/usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin:."
|
|
||||||
|
|
||||||
/* The value for PATH when invoking `command -p'. This is only used when
|
|
||||||
the Posix.2 confstr () function, or CS_PATH define are not present. */
|
|
||||||
#define STANDARD_UTILS_PATH \
|
|
||||||
"/bin:/usr/bin:/usr/ucb:/usr/sbin:/sbin:/etc:/usr/etc:/usr/lib"
|
|
||||||
|
|
||||||
/* Put system-specific default mail directories here. */
|
|
||||||
#if defined (__bsdi__) || defined (__FreeBSD__) || defined (__NetBSD__)
|
|
||||||
# define DEFAULT_MAIL_PATH "/var/mail/"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined (DEFAULT_MAIL_PATH)
|
|
||||||
#if defined (USG)
|
|
||||||
# define DEFAULT_MAIL_PATH "/usr/mail/"
|
|
||||||
#else
|
|
||||||
# define DEFAULT_MAIL_PATH "/usr/spool/mail/"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define V9_ECHO if you want to give the echo builtin backslash-escape
|
|
||||||
interpretation using the -e option, in the style of the Bell Labs 9th
|
|
||||||
Edition version of echo. */
|
|
||||||
#define V9_ECHO
|
|
||||||
|
|
||||||
/* Define DEFAULT_ECHO_TO_USG if you want the echo builtin to interpret
|
|
||||||
the backslash-escape characters by default, like the System V echo.
|
|
||||||
This requires that V9_ECHO be defined. */
|
|
||||||
/* #define DEFAULT_ECHO_TO_USG */
|
|
||||||
#if !defined (V9_ECHO)
|
|
||||||
# undef DEFAULT_ECHO_TO_USG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define CONTINUE_AFTER_KILL_ERROR if you want the kill command to
|
|
||||||
continue processing arguments after one of them fails. */
|
|
||||||
#define CONTINUE_AFTER_KILL_ERROR
|
|
||||||
|
|
||||||
/* Define BREAK_COMPLAINS if you want the non-standard, but useful
|
|
||||||
error messages about `break' and `continue' out of context. */
|
|
||||||
#define BREAK_COMPLAINS
|
|
||||||
|
|
||||||
/* Define GETOPTS_BUILTIN if you want the Posix.2 `getopts' shell builtin
|
|
||||||
compiled into the shell. */
|
|
||||||
#define GETOPTS_BUILTIN
|
|
||||||
|
|
||||||
/* When ALLOW_RIGID_POSIX_COMPLIANCE is defined, you can turn on strictly
|
|
||||||
Posix compliant behaviour by setting the environment variable
|
|
||||||
POSIXLY_CORRECT. */
|
|
||||||
#define ALLOW_RIGID_POSIX_COMPLIANCE
|
|
||||||
|
|
||||||
/* Define RESTRICTED_SHELL if you want the generated shell to have the
|
|
||||||
ability to be a restricted one. The shell thus generated can become
|
|
||||||
restricted by being run with the name "rbash", or by setting the -r
|
|
||||||
flag. */
|
|
||||||
/* #define RESTRICTED_SHELL */
|
|
||||||
|
|
||||||
/* Define DISABLED_BUILTINS if you want "builtin foo" to always run the
|
|
||||||
shell builtin "foo", even if it has been disabled with "enable -n foo". */
|
|
||||||
/* #define DISABLED_BUILTINS */
|
|
||||||
|
|
||||||
/* Define PROCESS_SUBSTITUTION if you want the K*rn shell-like process
|
|
||||||
substitution features "<(file)". */
|
|
||||||
/* Right now, you cannot do this on machines without fully operational
|
|
||||||
FIFO support. This currently include NeXT and Alliant. */
|
|
||||||
#if !defined (MKFIFO_MISSING)
|
|
||||||
# define PROCESS_SUBSTITUTION
|
|
||||||
#endif /* !MKFIFO_MISSING */
|
|
||||||
|
|
||||||
/* Define PROMPT_STRING_DECODE if you want the backslash-escaped special
|
|
||||||
characters in PS1 and PS2 expanded. Variable expansion will still be
|
|
||||||
performed. */
|
|
||||||
/* #define PROMPT_STRING_DECODE */
|
|
||||||
|
|
||||||
/* Define BUFFERED_INPUT if you want the shell to do its own input
|
|
||||||
buffering. */
|
|
||||||
#define BUFFERED_INPUT
|
|
||||||
|
|
||||||
/* Define INTERACTIVE_COMMENTS if you want # comments to work by default
|
|
||||||
when the shell is interactive, as Posix.2a specifies. */
|
|
||||||
#define INTERACTIVE_COMMENTS
|
|
||||||
|
|
||||||
/* Define ONESHOT if you want sh -c 'command' to avoid forking to execute
|
|
||||||
`command' whenever possible. */
|
|
||||||
#define ONESHOT
|
|
||||||
|
|
||||||
/* Default primary and secondary prompt strings. */
|
|
||||||
#define PPROMPT "bash\\$ "
|
|
||||||
#define SPROMPT "> "
|
|
||||||
|
|
||||||
/* Define SELECT_COMMAND if you want the Korn-shell style `select' command:
|
|
||||||
select word in word_list; do command_list; done */
|
|
||||||
/* #define SELECT_COMMAND */
|
|
||||||
|
|
||||||
#endif /* !_CONFIG_H_ */
|
|
||||||
51
config.h.top
Normal file
51
config.h.top
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/* config.h.top */
|
||||||
|
|
||||||
|
/* This contains various user-settable options not under the control of
|
||||||
|
autoconf. */
|
||||||
|
|
||||||
|
/* Define CONTINUE_AFTER_KILL_ERROR if you want the kill command to
|
||||||
|
continue processing arguments after one of them fails. This is
|
||||||
|
what POSIX.2 specifies. */
|
||||||
|
#define CONTINUE_AFTER_KILL_ERROR
|
||||||
|
|
||||||
|
/* Define BREAK_COMPLAINS if you want the non-standard, but useful
|
||||||
|
error messages about `break' and `continue' out of context. */
|
||||||
|
#define BREAK_COMPLAINS
|
||||||
|
|
||||||
|
/* Define BUFFERED_INPUT if you want the shell to do its own input
|
||||||
|
buffering, rather than using stdio. Do not undefine this; it's
|
||||||
|
required to preserve semantics required by POSIX. */
|
||||||
|
#define BUFFERED_INPUT
|
||||||
|
|
||||||
|
/* Define ONESHOT if you want sh -c 'command' to avoid forking to execute
|
||||||
|
`command' whenever possible. This is a big efficiency improvement. */
|
||||||
|
#define ONESHOT
|
||||||
|
|
||||||
|
/* Define V9_ECHO if you want to give the echo builtin backslash-escape
|
||||||
|
interpretation using the -e option, in the style of the Bell Labs 9th
|
||||||
|
Edition version of echo. You cannot emulate the System V echo behavior
|
||||||
|
without this option. */
|
||||||
|
#define V9_ECHO
|
||||||
|
|
||||||
|
/* The default value of the PATH variable. */
|
||||||
|
#ifndef DEFAULT_PATH_VALUE
|
||||||
|
#define DEFAULT_PATH_VALUE \
|
||||||
|
"/usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin:."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The value for PATH when invoking `command -p'. This is only used when
|
||||||
|
the Posix.2 confstr () function, or CS_PATH define are not present. */
|
||||||
|
#ifndef STANDARD_UTILS_PATH
|
||||||
|
#define STANDARD_UTILS_PATH \
|
||||||
|
"/bin:/usr/bin:/usr/ucb:/sbin:/usr/sbin:/etc:/usr/etc"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Default primary and secondary prompt strings. */
|
||||||
|
#define PPROMPT "\\s-\\v\\$ "
|
||||||
|
#define SPROMPT "> "
|
||||||
|
|
||||||
|
/* System-wide .bashrc file for interactive shells. */
|
||||||
|
/* #define SYS_BASHRC "/etc/bash.bashrc" */
|
||||||
|
|
||||||
|
/* System-wide .bash_logout for login shells. */
|
||||||
|
/* #define SYS_BASH_LOGOUT "/etc/bash.bash_logout" */
|
||||||
462
configure.in
Normal file
462
configure.in
Normal file
@@ -0,0 +1,462 @@
|
|||||||
|
dnl
|
||||||
|
dnl Configure script for bash-2.0
|
||||||
|
dnl
|
||||||
|
dnl report bugs to chet@po.cwru.edu
|
||||||
|
dnl
|
||||||
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
dnl checks for version info
|
||||||
|
AC_REVISION([for Bash 2.0, version 1.14, from autoconf version] AC_ACVERSION)dnl
|
||||||
|
|
||||||
|
AC_INIT(shell.h)
|
||||||
|
AC_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
|
dnl make sure we are using a recent autoconf version
|
||||||
|
AC_PREREQ(2.8)
|
||||||
|
|
||||||
|
dnl where to find install.sh, config.sub, and config.guess
|
||||||
|
AC_CONFIG_AUX_DIR(./support)
|
||||||
|
|
||||||
|
dnl canonicalize the host and os so we can do some tricky things before
|
||||||
|
dnl parsing options
|
||||||
|
AC_CANONICAL_HOST
|
||||||
|
|
||||||
|
dnl configure defaults
|
||||||
|
opt_gnu_malloc=yes
|
||||||
|
opt_glibc_malloc=no
|
||||||
|
opt_purify=no
|
||||||
|
opt_afs=no
|
||||||
|
|
||||||
|
dnl some systems should be configured without gnu malloc by default
|
||||||
|
dnl and some need a special compiler or loader
|
||||||
|
dnl look in the NOTES file for more
|
||||||
|
case "${host_cpu}-${host_os}" in
|
||||||
|
alpha-*) opt_gnu_malloc=no ;; # alpha running osf/1 or linux
|
||||||
|
*cray*-*) opt_gnu_malloc=no ;; # Crays
|
||||||
|
*-osf1*) opt_gnu_malloc=no ;; # other osf/1 machines
|
||||||
|
sparc-svr4*) opt_gnu_malloc=no ;; # sparc SVR4, SVR4.2
|
||||||
|
sparc-netbsd*) opt_gnu_malloc=no ;; # needs 8-byte alignment
|
||||||
|
sparc-linux*) opt_gnu_malloc=no ;; # sparc running linux; requires ELF
|
||||||
|
*-aix*) opt_gnu_malloc=no ;; # AIX machines
|
||||||
|
*-nextstep*) opt_gnu_malloc=no ;; # NeXT machines running NeXTstep
|
||||||
|
*-dgux*) opt_gnu_malloc=no ;; # DG/UX machines
|
||||||
|
*-qnx) opt_gnu_malloc=no ;; # QNX 4.2
|
||||||
|
*-bsdi2.1) opt_gnu_malloc=no ; : ${CC:=shlicc2} ;; # for loadable builtins
|
||||||
|
esac
|
||||||
|
|
||||||
|
dnl arguments to configure
|
||||||
|
dnl packages
|
||||||
|
AC_ARG_WITH(gnu-malloc, --with-gnu-malloc use the GNU version of malloc,opt_gnu_malloc=$withval)
|
||||||
|
AC_ARG_WITH(glibc-malloc, --with-glibc-malloc use the GNU C library version of malloc,opt_glibc_malloc=$withval)
|
||||||
|
AC_ARG_WITH(purify, --with-purify configure to postprocess with purify, opt_purify=$withval)
|
||||||
|
AC_ARG_WITH(afs, --with-afs if you are running AFS, opt_afs=$withval)
|
||||||
|
|
||||||
|
dnl test for glibc malloc first because it can override the default
|
||||||
|
if test "$opt_glibc_malloc" = yes; then
|
||||||
|
MALLOC=gmalloc.o MALLOC_SRC='$(ALLOC_LIBSRC)/gmalloc.c'
|
||||||
|
elif test "$opt_gnu_malloc" = yes; then
|
||||||
|
MALLOC=malloc.o MALLOC_SRC='$(ALLOC_LIBSRC)/malloc.c'
|
||||||
|
else
|
||||||
|
MALLOC= MALLOC_SRC=
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$opt_purify" = yes; then
|
||||||
|
PURIFY=purify
|
||||||
|
else
|
||||||
|
PURIFY=
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$opt_afs" = yes; then
|
||||||
|
AC_DEFINE(AFS)
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl optional shell features in config.h.in
|
||||||
|
opt_minimal_config=no
|
||||||
|
|
||||||
|
opt_job_control=yes
|
||||||
|
opt_alias=yes
|
||||||
|
opt_readline=yes
|
||||||
|
opt_history=yes
|
||||||
|
opt_bang_history=yes
|
||||||
|
opt_dirstack=yes
|
||||||
|
opt_restricted=yes
|
||||||
|
opt_process_subst=yes
|
||||||
|
opt_prompt_decoding=yes
|
||||||
|
opt_select=yes
|
||||||
|
opt_help=yes
|
||||||
|
opt_array_variables=yes
|
||||||
|
opt_dparen_arith=yes
|
||||||
|
opt_brace_expansion=yes
|
||||||
|
opt_disabled_builtins=no
|
||||||
|
opt_command_timing=yes
|
||||||
|
opt_usg_echo=no
|
||||||
|
|
||||||
|
dnl argument parsing for optional features
|
||||||
|
AC_ARG_ENABLE(minimal-config, --enable-minimal-config a minimal sh-like configuration, opt_minimal_config=$enableval)
|
||||||
|
|
||||||
|
dnl a minimal configuration turns everything off, but features can be
|
||||||
|
dnl added individually
|
||||||
|
if test $opt_minimal_config = yes; then
|
||||||
|
opt_job_control=no opt_alias=no opt_readline=no
|
||||||
|
opt_history=no opt_bang_history=no opt_dirstack=no
|
||||||
|
opt_restricted=no opt_process_subst=no opt_prompt_decoding=no
|
||||||
|
opt_select=no opt_help=no opt_array_variables=no opt_dparen_arith=no
|
||||||
|
opt_brace_expansion=no opt_disabled_builtins=no opt_command_timing=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(job-control, --enable-job-control enable job control features, opt_job_control=$enableval)
|
||||||
|
AC_ARG_ENABLE(alias, --enable-alias enable shell aliases, opt_alias=$enableval)
|
||||||
|
AC_ARG_ENABLE(readline, --enable-readline turn on command line editing, opt_readline=$enableval)
|
||||||
|
AC_ARG_ENABLE(history, --enable-history turn on command history, opt_history=$enableval)
|
||||||
|
AC_ARG_ENABLE(bang-history, --enable-bang-history turn on csh-style history substitution, opt_bang_history=$enableval)
|
||||||
|
AC_ARG_ENABLE(directory-stack, --enable-directory-stack enable builtins pushd/popd/dirs, opt_dirstack=$enableval)
|
||||||
|
AC_ARG_ENABLE(restricted, --enable-restricted enable a restricted shell, opt_restricted=$enableval)
|
||||||
|
AC_ARG_ENABLE(process-substitution, --enable-process-substitution enable process substitution, opt_process_subst=$enableval)
|
||||||
|
AC_ARG_ENABLE(prompt-string-decoding, --enable-prompt-string-decoding turn on escape character decoding in prompts, opt_prompt_decoding=$enableval)
|
||||||
|
AC_ARG_ENABLE(select, --enable-select include select command, opt_select=$enableval)
|
||||||
|
AC_ARG_ENABLE(help-builtin, --enable-help-builtin include the help builtin, opt_help=$enableval)
|
||||||
|
AC_ARG_ENABLE(array-variables, --enable-array-variables include shell array variables, opt_array_variables=$enableval)
|
||||||
|
AC_ARG_ENABLE(dparen-arithmetic, [--enable-dparen-arithmetic include ((...)) command], opt_dparen_arith=$enableval)
|
||||||
|
AC_ARG_ENABLE(brace-expansion, --enable-brace-expansion include brace expansion, opt_brace_expansion=$enableval)
|
||||||
|
AC_ARG_ENABLE(disabled-builtins, --enable-disabled-builtins allow disabled builtins to still be invoked, opt_disabled_builtins=$enableval)
|
||||||
|
AC_ARG_ENABLE(command-timing, --enable-command-timing enable the time reserved word and command timing, opt_command_timing=$enableval)
|
||||||
|
AC_ARG_ENABLE(usg-echo-default, --enable-usg-echo-default make the echo builtin expand escape sequences by default, opt_usg_echo=$enableval)
|
||||||
|
|
||||||
|
dnl opt_job_control is handled later, after BASH_JOB_CONTROL_MISSING runs
|
||||||
|
|
||||||
|
if test $opt_alias = yes; then
|
||||||
|
AC_DEFINE(ALIAS)
|
||||||
|
fi
|
||||||
|
if test $opt_readline = yes; then
|
||||||
|
AC_DEFINE(READLINE)
|
||||||
|
READLINE_LIB=-lreadline
|
||||||
|
READLINE_DEP='$(READLINE_LIBRARY)'
|
||||||
|
else
|
||||||
|
READLINE_LIB= READLINE_DEP=
|
||||||
|
fi
|
||||||
|
if test $opt_history = yes; then
|
||||||
|
AC_DEFINE(HISTORY)
|
||||||
|
HISTORY_LIB=-lhistory
|
||||||
|
HISTORY_DEP='$(HISTORY_LIBRARY)'
|
||||||
|
else
|
||||||
|
HISTORY_LIB= HISTORY_DEP=
|
||||||
|
fi
|
||||||
|
if test $opt_bang_history = yes; then
|
||||||
|
AC_DEFINE(BANG_HISTORY)
|
||||||
|
HISTORY_LIB=-lhistory
|
||||||
|
HISTORY_DEP='$(HISTORY_LIBRARY)'
|
||||||
|
else
|
||||||
|
HISTORY_LIB= HISTORY_DEP=
|
||||||
|
fi
|
||||||
|
if test $opt_dirstack = yes; then
|
||||||
|
AC_DEFINE(PUSHD_AND_POPD)
|
||||||
|
fi
|
||||||
|
if test $opt_restricted = yes; then
|
||||||
|
AC_DEFINE(RESTRICTED_SHELL)
|
||||||
|
fi
|
||||||
|
if test $opt_process_subst = yes; then
|
||||||
|
AC_DEFINE(PROCESS_SUBSTITUTION)
|
||||||
|
fi
|
||||||
|
if test $opt_prompt_decoding = yes; then
|
||||||
|
AC_DEFINE(PROMPT_STRING_DECODE)
|
||||||
|
fi
|
||||||
|
if test $opt_select = yes; then
|
||||||
|
AC_DEFINE(SELECT_COMMAND)
|
||||||
|
fi
|
||||||
|
if test $opt_help = yes; then
|
||||||
|
AC_DEFINE(HELP_BUILTIN)
|
||||||
|
fi
|
||||||
|
if test $opt_array_variables = yes; then
|
||||||
|
AC_DEFINE(ARRAY_VARS)
|
||||||
|
fi
|
||||||
|
if test $opt_dparen_arith = yes; then
|
||||||
|
AC_DEFINE(DPAREN_ARITHMETIC)
|
||||||
|
fi
|
||||||
|
if test $opt_brace_expansion = yes; then
|
||||||
|
AC_DEFINE(BRACE_EXPANSION)
|
||||||
|
fi
|
||||||
|
if test $opt_disabled_builtins = yes; then
|
||||||
|
AC_DEFINE(DISABLED_BUILTINS)
|
||||||
|
fi
|
||||||
|
if test $opt_command_timing = yes; then
|
||||||
|
AC_DEFINE(COMMAND_TIMING)
|
||||||
|
fi
|
||||||
|
if test $opt_usg_echo = yes ; then
|
||||||
|
AC_DEFINE(DEFAULT_ECHO_TO_USG)
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl now substitute in the values generated by arguments
|
||||||
|
AC_SUBST(PURIFY)
|
||||||
|
AC_SUBST(MALLOC)
|
||||||
|
AC_SUBST(MALLOC_SRC)
|
||||||
|
AC_SUBST(READLINE_LIB)
|
||||||
|
AC_SUBST(READLINE_DEP)
|
||||||
|
AC_SUBST(HISTORY_LIB)
|
||||||
|
AC_SUBST(HISTORY_DEP)
|
||||||
|
|
||||||
|
echo "Beginning configuration for bash-2.0"
|
||||||
|
|
||||||
|
dnl compilation checks
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_ISC_POSIX
|
||||||
|
AC_MINIX
|
||||||
|
|
||||||
|
dnl See whether cc works at all
|
||||||
|
BASH_CC_WORKS
|
||||||
|
|
||||||
|
dnl We want these before the checks, so the checks can modify their values.
|
||||||
|
test -z "$CFLAGS" && CFLAGS=-g auto_cflags=1
|
||||||
|
|
||||||
|
dnl If we're using gcc and the user hasn't specified CFLAGS, add -O2 to CFLAGS.
|
||||||
|
test -n "$GCC" && test -n "$auto_cflags" && CFLAGS="$CFLAGS -O2"
|
||||||
|
|
||||||
|
AC_SUBST(CFLAGS)
|
||||||
|
AC_SUBST(CPPFLAGS)
|
||||||
|
AC_SUBST(LDFLAGS)
|
||||||
|
|
||||||
|
AC_PROG_GCC_TRADITIONAL
|
||||||
|
|
||||||
|
dnl programs needed by the build and install process
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_CHECK_PROG(AR, ar, ar)
|
||||||
|
AC_PROG_RANLIB
|
||||||
|
AC_PROG_YACC
|
||||||
|
AC_PROG_MAKE_SET
|
||||||
|
|
||||||
|
dnl special checks for libc functions
|
||||||
|
AC_FUNC_ALLOCA
|
||||||
|
AC_FUNC_GETPGRP
|
||||||
|
AC_FUNC_SETVBUF_REVERSED
|
||||||
|
AC_FUNC_VPRINTF
|
||||||
|
AC_FUNC_WAIT3
|
||||||
|
AC_FUNC_STRCOLL
|
||||||
|
|
||||||
|
dnl if vprintf is not in libc, see if it's defined in stdio.h
|
||||||
|
if test "$ac_cv_func_vprintf" = no; then
|
||||||
|
AC_MSG_CHECKING(for declaration of vprintf in stdio.h)
|
||||||
|
AC_EGREP_HEADER([[int[ ]*vprintf[^a-zA-Z0-9]]],stdio.h,ac_cv_func_vprintf=yes)
|
||||||
|
AC_MSG_RESULT($ac_cv_func_vprintf)
|
||||||
|
if test $ac_cv_func_vprintf = yes; then
|
||||||
|
AC_DEFINE(HAVE_VPRINTF)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl signal stuff
|
||||||
|
AC_RETSIGTYPE
|
||||||
|
|
||||||
|
dnl checks for certain version-specific system calls and libc functions
|
||||||
|
AC_CHECK_FUNC(__setostype, AC_DEFINE(HAVE_SETOSTYPE))
|
||||||
|
AC_CHECK_FUNC(wait3, AC_DEFINE(HAVE_WAIT3))
|
||||||
|
|
||||||
|
dnl checks for missing libc functions
|
||||||
|
AC_CHECK_FUNC(mkfifo,AC_DEFINE(HAVE_MKFIFO),AC_DEFINE(MKFIFO_MISSING))
|
||||||
|
|
||||||
|
dnl checks for system calls
|
||||||
|
AC_CHECK_FUNCS(dup2 select getdtablesize getgroups gethostname \
|
||||||
|
setdtablesize getpagesize killpg lstat getpeername \
|
||||||
|
getrlimit getrusage gettimeofday waitpid tcgetpgrp)
|
||||||
|
|
||||||
|
dnl checks for c library functions
|
||||||
|
AC_CHECK_FUNCS(bcopy bzero confstr getcwd strcasecmp setenv putenv \
|
||||||
|
setlinebuf setlocale strchr strerror tcgetattr uname \
|
||||||
|
sysconf ulimit times tzset siginterrupt memmove)
|
||||||
|
|
||||||
|
dnl checks for locale functions
|
||||||
|
AC_CHECK_HEADERS(libintl.h)
|
||||||
|
AC_CHECK_FUNCS(gettext textdomain bindtextdomain)
|
||||||
|
|
||||||
|
dnl check for GNU libintl if gettext/textdomain/bindtextdomain
|
||||||
|
dnl are not found in libc
|
||||||
|
if test "$ac_cv_func_bindtextdomain" = "no"; then
|
||||||
|
AC_CHECK_LIB(intl,bindtextdomain)
|
||||||
|
if test "$ac_cv_lib_intl" = "yes"; then
|
||||||
|
AC_CHECK_FUNCS(gettext textdomain bindtextdomain)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl checks for the dynamic loading library functions in libc and libdl
|
||||||
|
AC_CHECK_LIB(dl, dlopen)
|
||||||
|
AC_CHECK_FUNCS(dlopen dlclose dlsym)
|
||||||
|
|
||||||
|
dnl this defines SYS_SIGLIST_DECLARED
|
||||||
|
AC_DECL_SYS_SIGLIST
|
||||||
|
|
||||||
|
dnl header files
|
||||||
|
AC_HEADER_DIRENT
|
||||||
|
AC_HEADER_TIME
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS(unistd.h stdlib.h stdarg.h varargs.h limits.h string.h \
|
||||||
|
memory.h locale.h termcap.h termio.h termios.h)
|
||||||
|
AC_CHECK_HEADERS(sys/ptem.h sys/pte.h sys/stream.h sys/select.h sys/file.h \
|
||||||
|
sys/resource.h sys/param.h sys/socket.h \
|
||||||
|
sys/time.h sys/times.h sys/wait.h)
|
||||||
|
|
||||||
|
dnl libraries
|
||||||
|
dnl this is reportedly no longer necessary for irix[56].?
|
||||||
|
dnl AC_CHECK_LIB(sun, getpwent)
|
||||||
|
BASH_CHECK_SOCKLIB
|
||||||
|
|
||||||
|
dnl system types
|
||||||
|
AC_TYPE_GETGROUPS
|
||||||
|
AC_TYPE_OFF_T
|
||||||
|
AC_TYPE_MODE_T
|
||||||
|
AC_TYPE_UID_T
|
||||||
|
AC_TYPE_PID_T
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_CHECK_TYPE(time_t, long)
|
||||||
|
|
||||||
|
AC_TYPE_SIGNAL
|
||||||
|
|
||||||
|
dnl structures
|
||||||
|
AC_HEADER_STAT
|
||||||
|
AC_HEADER_EGREP(struct timeval, sys/time.h, bash_cv_struct_timeval=yes, )
|
||||||
|
if test -z "$bash_cv_struct_timeval"; then
|
||||||
|
AC_HEADER_EGREP(struct timeval, time.h, bash_cv_struct_timeval=yes, bash_cv_struct_timeval=no)
|
||||||
|
fi
|
||||||
|
if test $bash_cv_struct_timeval = yes; then
|
||||||
|
AC_DEFINE(HAVE_TIMEVAL)
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl C compiler characteristics
|
||||||
|
AC_C_BIGENDIAN
|
||||||
|
|
||||||
|
dnl system services
|
||||||
|
AC_SYS_INTERPRETER
|
||||||
|
if test $ac_cv_sys_interpreter = yes; then
|
||||||
|
AC_DEFINE(HAVE_HASH_BANG_EXEC)
|
||||||
|
fi
|
||||||
|
dnl we use NO_READ_RESTART_ON_SIGNAL
|
||||||
|
AC_SYS_RESTARTABLE_SYSCALLS
|
||||||
|
|
||||||
|
dnl Miscellaneous Bash tests
|
||||||
|
if test "$ac_cv_func_lstat" = "no"; then
|
||||||
|
BASH_FUNC_LSTAT
|
||||||
|
fi
|
||||||
|
|
||||||
|
BASH_DUP2_CLOEXEC_CHECK
|
||||||
|
BASH_PGRP_SYNC
|
||||||
|
BASH_SYS_ERRLIST
|
||||||
|
BASH_SYS_SIGLIST
|
||||||
|
BASH_UNDER_SYS_SIGLIST
|
||||||
|
BASH_SIGNAL_CHECK
|
||||||
|
BASH_TYPE_SIGHANDLER
|
||||||
|
BASH_CHECK_TYPE(clock_t, [#include <sys/times.h>], long)
|
||||||
|
BASH_CHECK_TYPE(sigset_t, [#include <signal.h>], int)
|
||||||
|
BASH_CHECK_TYPE(quad_t, , long, HAVE_QUAD_T)
|
||||||
|
BASH_RLIMIT_TYPE
|
||||||
|
BASH_STRUCT_TERMIOS_LDISC
|
||||||
|
BASH_STRUCT_TERMIO_LDISC
|
||||||
|
BASH_STRUCT_DIRENT_D_INO
|
||||||
|
BASH_FUNC_STRSIGNAL
|
||||||
|
BASH_FUNC_OPENDIR_CHECK
|
||||||
|
BASH_FUNC_PRINTF
|
||||||
|
BASH_FUNC_ULIMIT_MAXFDS
|
||||||
|
BASH_FUNC_GETENV
|
||||||
|
BASH_FUNC_GETCWD
|
||||||
|
BASH_FUNC_SBRK_DECLARED
|
||||||
|
BASH_FUNC_POSIX_SETJMP
|
||||||
|
BASH_REINSTALL_SIGHANDLERS
|
||||||
|
BASH_JOB_CONTROL_MISSING
|
||||||
|
BASH_SYS_NAMED_PIPES
|
||||||
|
BASH_HAVE_TIOCGWINSZ
|
||||||
|
BASH_HAVE_TIOCSTAT
|
||||||
|
BASH_HAVE_FIONREAD
|
||||||
|
BASH_CHECK_GETPW_FUNCS
|
||||||
|
BASH_CHECK_DEV_FD
|
||||||
|
|
||||||
|
case "$host_os" in
|
||||||
|
hpux*) BASH_KERNEL_RLIMIT_CHECK ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if test "$opt_readline" = yes; then
|
||||||
|
BASH_CHECK_LIB_TERMCAP
|
||||||
|
fi
|
||||||
|
AC_SUBST(TERMCAP_LIB)
|
||||||
|
AC_SUBST(TERMCAP_DEP)
|
||||||
|
|
||||||
|
dnl special checks
|
||||||
|
BASH_DEFAULT_MAIL_DIR
|
||||||
|
|
||||||
|
if test "$bash_cv_job_control_missing" = missing; then
|
||||||
|
opt_job_control=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$opt_job_control" = yes; then
|
||||||
|
AC_DEFINE(JOB_CONTROL)
|
||||||
|
JOBS_O=jobs.o
|
||||||
|
else
|
||||||
|
JOBS_O=nojobs.o
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(JOBS_O)
|
||||||
|
|
||||||
|
dnl use this section to possibly define more cpp variables, specify local
|
||||||
|
dnl libraries, and specify any additional local cc flags
|
||||||
|
dnl
|
||||||
|
dnl this should really go away someday
|
||||||
|
|
||||||
|
case "$host_os" in
|
||||||
|
sysv4.2) AC_DEFINE(SVR4_2)
|
||||||
|
AC_DEFINE(SVR4) ;;
|
||||||
|
sysv4*) AC_DEFINE(SVR4) ;;
|
||||||
|
hpux*) LOCAL_CFLAGS=-DHPUX ;;
|
||||||
|
dgux*) LOCAL_CFLAGS=-D_DGUX_SOURCE; LOCAL_LIBS=-ldgc ;;
|
||||||
|
isc*) LOCAL_CFLAGS=-Disc386;;
|
||||||
|
sco3.2v5*) LOCAL_CFLAGS="-DWAITPID_BROKEN -DNO_MEMSCRAMBLE -DPATH_MAX=1024" ;;
|
||||||
|
sco3.2v4*) LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DNO_MEMSCRAMBLE -DPATH_MAX=1024" ;;
|
||||||
|
sco3.2*) LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;;
|
||||||
|
sunos4*) LOCAL_CFLAGS=-DSunOS4;;
|
||||||
|
linux*) LOCAL_LDFLAGS=-rdynamic ;; # allow dynamic loading
|
||||||
|
aix4.2*) LOCAL_LDFLAGS="-bexpall -brtl";;# allow dynamic loading
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$host_cpu" in
|
||||||
|
*cray*) LOCAL_CFLAGS="-DCRAY" ;; # shell var so config.h can use it
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$host_cpu-$host_os" in
|
||||||
|
ibmrt-*bsd4*) LOCAL_CFLAGS="-ma -U__STDC__" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$host_cpu-$host_vendor-$host_os" in
|
||||||
|
m88k-motorola-sysv3) LOCAL_CFLAGS=-DWAITPID_BROKEN ;;
|
||||||
|
mips-pyramid-sysv4) LOCAL_CFLAGS=-Xa ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# try to create a directory tree if the source is elsewhere
|
||||||
|
# this should be packaged into a script accessible via ${srcdir}/support
|
||||||
|
case "$srcdir" in
|
||||||
|
.) ;;
|
||||||
|
*) for d in doc tests support lib ; do # dirs
|
||||||
|
test -d $d || mkdir $d
|
||||||
|
done
|
||||||
|
for ld in readline glob tilde malloc termcap; do # libdirs
|
||||||
|
test -d lib/$ld || mkdir lib/$ld
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
BUILD_DIR=`pwd`
|
||||||
|
|
||||||
|
AC_SUBST(incdir)
|
||||||
|
AC_SUBST(BUILD_DIR)
|
||||||
|
|
||||||
|
AC_SUBST(YACC)
|
||||||
|
AC_SUBST(AR)
|
||||||
|
|
||||||
|
AC_SUBST(host_cpu)
|
||||||
|
AC_SUBST(host_os)
|
||||||
|
|
||||||
|
AC_SUBST(LOCAL_LIBS)
|
||||||
|
AC_SUBST(LOCAL_CFLAGS)
|
||||||
|
AC_SUBST(LOCAL_LDFLAGS)
|
||||||
|
|
||||||
|
AC_SUBST(ALLOCA_SOURCE)
|
||||||
|
AC_SUBST(ALLOCA_OBJECT)
|
||||||
|
|
||||||
|
AC_OUTPUT([Makefile builtins/Makefile lib/readline/Makefile lib/glob/Makefile \
|
||||||
|
lib/malloc/Makefile lib/termcap/Makefile lib/tilde/Makefile \
|
||||||
|
doc/Makefile],
|
||||||
|
[
|
||||||
|
# Makefile uses this timestamp file to record whether config.h is up to date.
|
||||||
|
echo timestamp > stamp-h
|
||||||
|
])
|
||||||
99
copy_cmd.c
99
copy_cmd.c
@@ -20,8 +20,14 @@
|
|||||||
along with Bash; see the file COPYING. If not, write to the Free
|
along with Bash; see the file COPYING. If not, write to the Free
|
||||||
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined (HAVE_STRING_H)
|
#if defined (HAVE_STRING_H)
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
#else /* !HAVE_STRING_H */
|
#else /* !HAVE_STRING_H */
|
||||||
@@ -34,7 +40,9 @@ WORD_DESC *
|
|||||||
copy_word (word)
|
copy_word (word)
|
||||||
WORD_DESC *word;
|
WORD_DESC *word;
|
||||||
{
|
{
|
||||||
WORD_DESC *new_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
|
WORD_DESC *new_word;
|
||||||
|
|
||||||
|
new_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
|
||||||
FASTCOPY ((char *)word, (char *)new_word, sizeof (WORD_DESC));
|
FASTCOPY ((char *)word, (char *)new_word, sizeof (WORD_DESC));
|
||||||
new_word->word = savestring (word->word);
|
new_word->word = savestring (word->word);
|
||||||
return (new_word);
|
return (new_word);
|
||||||
@@ -46,15 +54,14 @@ WORD_LIST *
|
|||||||
copy_word_list (list)
|
copy_word_list (list)
|
||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
WORD_LIST *new_list = NULL;
|
WORD_LIST *new_list, *temp;
|
||||||
|
|
||||||
while (list)
|
for (new_list = (WORD_LIST *)NULL; list; list = list->next)
|
||||||
{
|
{
|
||||||
WORD_LIST *temp = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
|
temp = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
|
||||||
temp->next = new_list;
|
temp->next = new_list;
|
||||||
new_list = temp;
|
new_list = temp;
|
||||||
new_list->word = copy_word (list->word);
|
new_list->word = copy_word (list->word);
|
||||||
list = list->next;
|
|
||||||
}
|
}
|
||||||
return (REVERSE_LIST (new_list, WORD_LIST *));
|
return (REVERSE_LIST (new_list, WORD_LIST *));
|
||||||
}
|
}
|
||||||
@@ -63,7 +70,9 @@ static PATTERN_LIST *
|
|||||||
copy_case_clause (clause)
|
copy_case_clause (clause)
|
||||||
PATTERN_LIST *clause;
|
PATTERN_LIST *clause;
|
||||||
{
|
{
|
||||||
PATTERN_LIST *new_clause = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
|
PATTERN_LIST *new_clause;
|
||||||
|
|
||||||
|
new_clause = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
|
||||||
new_clause->patterns = copy_word_list (clause->patterns);
|
new_clause->patterns = copy_word_list (clause->patterns);
|
||||||
new_clause->action = copy_command (clause->action);
|
new_clause->action = copy_command (clause->action);
|
||||||
return (new_clause);
|
return (new_clause);
|
||||||
@@ -73,14 +82,13 @@ static PATTERN_LIST *
|
|||||||
copy_case_clauses (clauses)
|
copy_case_clauses (clauses)
|
||||||
PATTERN_LIST *clauses;
|
PATTERN_LIST *clauses;
|
||||||
{
|
{
|
||||||
PATTERN_LIST *new_list = (PATTERN_LIST *)NULL;
|
PATTERN_LIST *new_list, *new_clause;
|
||||||
|
|
||||||
while (clauses)
|
for (new_list = (PATTERN_LIST *)NULL; clauses; clauses = clauses->next)
|
||||||
{
|
{
|
||||||
PATTERN_LIST *new_clause = copy_case_clause (clauses);
|
new_clause = copy_case_clause (clauses);
|
||||||
new_clause->next = new_list;
|
new_clause->next = new_list;
|
||||||
new_list = new_clause;
|
new_list = new_clause;
|
||||||
clauses = clauses->next;
|
|
||||||
}
|
}
|
||||||
return (REVERSE_LIST (new_list, PATTERN_LIST *));
|
return (REVERSE_LIST (new_list, PATTERN_LIST *));
|
||||||
}
|
}
|
||||||
@@ -90,14 +98,16 @@ REDIRECT *
|
|||||||
copy_redirect (redirect)
|
copy_redirect (redirect)
|
||||||
REDIRECT *redirect;
|
REDIRECT *redirect;
|
||||||
{
|
{
|
||||||
REDIRECT *new_redirect = (REDIRECT *)xmalloc (sizeof (REDIRECT));
|
REDIRECT *new_redirect;
|
||||||
|
|
||||||
|
new_redirect = (REDIRECT *)xmalloc (sizeof (REDIRECT));
|
||||||
FASTCOPY ((char *)redirect, (char *)new_redirect, (sizeof (REDIRECT)));
|
FASTCOPY ((char *)redirect, (char *)new_redirect, (sizeof (REDIRECT)));
|
||||||
switch (redirect->instruction)
|
switch (redirect->instruction)
|
||||||
{
|
{
|
||||||
case r_reading_until:
|
case r_reading_until:
|
||||||
case r_deblank_reading_until:
|
case r_deblank_reading_until:
|
||||||
new_redirect->here_doc_eof = savestring (redirect->here_doc_eof);
|
new_redirect->here_doc_eof = savestring (redirect->here_doc_eof);
|
||||||
/* There is NO BREAK HERE ON PURPOSE!!!! */
|
/*FALLTHROUGH*/
|
||||||
case r_appending_to:
|
case r_appending_to:
|
||||||
case r_output_direction:
|
case r_output_direction:
|
||||||
case r_input_direction:
|
case r_input_direction:
|
||||||
@@ -107,8 +117,7 @@ copy_redirect (redirect)
|
|||||||
case r_output_force:
|
case r_output_force:
|
||||||
case r_duplicating_input_word:
|
case r_duplicating_input_word:
|
||||||
case r_duplicating_output_word:
|
case r_duplicating_output_word:
|
||||||
new_redirect->redirectee.filename =
|
new_redirect->redirectee.filename = copy_word (redirect->redirectee.filename);
|
||||||
copy_word (redirect->redirectee.filename);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (new_redirect);
|
return (new_redirect);
|
||||||
@@ -118,14 +127,13 @@ REDIRECT *
|
|||||||
copy_redirects (list)
|
copy_redirects (list)
|
||||||
REDIRECT *list;
|
REDIRECT *list;
|
||||||
{
|
{
|
||||||
REDIRECT *new_list = NULL;
|
REDIRECT *new_list, *temp;
|
||||||
|
|
||||||
while (list)
|
for (new_list = (REDIRECT *)NULL; list; list = list->next)
|
||||||
{
|
{
|
||||||
REDIRECT *temp = copy_redirect (list);
|
temp = copy_redirect (list);
|
||||||
temp->next = new_list;
|
temp->next = new_list;
|
||||||
new_list = temp;
|
new_list = temp;
|
||||||
list = list->next;
|
|
||||||
}
|
}
|
||||||
return (REVERSE_LIST (new_list, REDIRECT *));
|
return (REVERSE_LIST (new_list, REDIRECT *));
|
||||||
}
|
}
|
||||||
@@ -134,7 +142,9 @@ static FOR_COM *
|
|||||||
copy_for_command (com)
|
copy_for_command (com)
|
||||||
FOR_COM *com;
|
FOR_COM *com;
|
||||||
{
|
{
|
||||||
FOR_COM *new_for = (FOR_COM *)xmalloc (sizeof (FOR_COM));
|
FOR_COM *new_for;
|
||||||
|
|
||||||
|
new_for = (FOR_COM *)xmalloc (sizeof (FOR_COM));
|
||||||
new_for->flags = com->flags;
|
new_for->flags = com->flags;
|
||||||
new_for->name = copy_word (com->name);
|
new_for->name = copy_word (com->name);
|
||||||
new_for->map_list = copy_word_list (com->map_list);
|
new_for->map_list = copy_word_list (com->map_list);
|
||||||
@@ -142,26 +152,13 @@ copy_for_command (com)
|
|||||||
return (new_for);
|
return (new_for);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (SELECT_COMMAND)
|
|
||||||
static SELECT_COM *
|
|
||||||
copy_select_command (com)
|
|
||||||
SELECT_COM *com;
|
|
||||||
{
|
|
||||||
SELECT_COM *new_select = (SELECT_COM *)xmalloc (sizeof (SELECT_COM));
|
|
||||||
new_select->flags = com->flags;
|
|
||||||
new_select->name = copy_word (com->name);
|
|
||||||
new_select->map_list = copy_word_list (com->map_list);
|
|
||||||
new_select->action = copy_command (com->action);
|
|
||||||
return (new_select);
|
|
||||||
}
|
|
||||||
#endif /* SELECT_COMMAND */
|
|
||||||
|
|
||||||
static GROUP_COM *
|
static GROUP_COM *
|
||||||
copy_group_command (com)
|
copy_group_command (com)
|
||||||
GROUP_COM *com;
|
GROUP_COM *com;
|
||||||
{
|
{
|
||||||
GROUP_COM *new_group = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
|
GROUP_COM *new_group;
|
||||||
|
|
||||||
|
new_group = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
|
||||||
new_group->command = copy_command (com->command);
|
new_group->command = copy_command (com->command);
|
||||||
return (new_group);
|
return (new_group);
|
||||||
}
|
}
|
||||||
@@ -170,8 +167,9 @@ static CASE_COM *
|
|||||||
copy_case_command (com)
|
copy_case_command (com)
|
||||||
CASE_COM *com;
|
CASE_COM *com;
|
||||||
{
|
{
|
||||||
CASE_COM *new_case = (CASE_COM *)xmalloc (sizeof (CASE_COM));
|
CASE_COM *new_case;
|
||||||
|
|
||||||
|
new_case = (CASE_COM *)xmalloc (sizeof (CASE_COM));
|
||||||
new_case->flags = com->flags;
|
new_case->flags = com->flags;
|
||||||
new_case->word = copy_word (com->word);
|
new_case->word = copy_word (com->word);
|
||||||
new_case->clauses = copy_case_clauses (com->clauses);
|
new_case->clauses = copy_case_clauses (com->clauses);
|
||||||
@@ -182,8 +180,9 @@ static WHILE_COM *
|
|||||||
copy_while_command (com)
|
copy_while_command (com)
|
||||||
WHILE_COM *com;
|
WHILE_COM *com;
|
||||||
{
|
{
|
||||||
WHILE_COM *new_while = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
|
WHILE_COM *new_while;
|
||||||
|
|
||||||
|
new_while = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
|
||||||
new_while->flags = com->flags;
|
new_while->flags = com->flags;
|
||||||
new_while->test = copy_command (com->test);
|
new_while->test = copy_command (com->test);
|
||||||
new_while->action = copy_command (com->action);
|
new_while->action = copy_command (com->action);
|
||||||
@@ -194,8 +193,9 @@ static IF_COM *
|
|||||||
copy_if_command (com)
|
copy_if_command (com)
|
||||||
IF_COM *com;
|
IF_COM *com;
|
||||||
{
|
{
|
||||||
IF_COM *new_if = (IF_COM *)xmalloc (sizeof (IF_COM));
|
IF_COM *new_if;
|
||||||
|
|
||||||
|
new_if = (IF_COM *)xmalloc (sizeof (IF_COM));
|
||||||
new_if->flags = com->flags;
|
new_if->flags = com->flags;
|
||||||
new_if->test = copy_command (com->test);
|
new_if->test = copy_command (com->test);
|
||||||
new_if->true_case = copy_command (com->true_case);
|
new_if->true_case = copy_command (com->true_case);
|
||||||
@@ -220,8 +220,9 @@ static FUNCTION_DEF *
|
|||||||
copy_function_def (com)
|
copy_function_def (com)
|
||||||
FUNCTION_DEF *com;
|
FUNCTION_DEF *com;
|
||||||
{
|
{
|
||||||
FUNCTION_DEF *new_def = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
|
FUNCTION_DEF *new_def;
|
||||||
|
|
||||||
|
new_def = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
|
||||||
new_def->name = copy_word (com->name);
|
new_def->name = copy_word (com->name);
|
||||||
new_def->command = copy_command (com->command);
|
new_def->command = copy_command (com->command);
|
||||||
return (new_def);
|
return (new_def);
|
||||||
@@ -234,10 +235,11 @@ COMMAND *
|
|||||||
copy_command (command)
|
copy_command (command)
|
||||||
COMMAND *command;
|
COMMAND *command;
|
||||||
{
|
{
|
||||||
COMMAND *new_command = (COMMAND *)NULL;
|
COMMAND *new_command;
|
||||||
|
|
||||||
|
if (command == NULL)
|
||||||
|
return (command);
|
||||||
|
|
||||||
if (command)
|
|
||||||
{
|
|
||||||
new_command = (COMMAND *)xmalloc (sizeof (COMMAND));
|
new_command = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||||
FASTCOPY ((char *)command, (char *)new_command, sizeof (COMMAND));
|
FASTCOPY ((char *)command, (char *)new_command, sizeof (COMMAND));
|
||||||
new_command->flags = command->flags;
|
new_command->flags = command->flags;
|
||||||
@@ -254,7 +256,8 @@ copy_command (command)
|
|||||||
|
|
||||||
#if defined (SELECT_COMMAND)
|
#if defined (SELECT_COMMAND)
|
||||||
case cm_select:
|
case cm_select:
|
||||||
new_command->value.Select = copy_select_command (command->value.Select);
|
new_command->value.Select =
|
||||||
|
(SELECT_COM *)copy_for_command ((FOR_COM *)command->value.Select);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -285,21 +288,15 @@ copy_command (command)
|
|||||||
|
|
||||||
new_connection = (CONNECTION *)xmalloc (sizeof (CONNECTION));
|
new_connection = (CONNECTION *)xmalloc (sizeof (CONNECTION));
|
||||||
new_connection->connector = command->value.Connection->connector;
|
new_connection->connector = command->value.Connection->connector;
|
||||||
new_connection->first =
|
new_connection->first = copy_command (command->value.Connection->first);
|
||||||
copy_command (command->value.Connection->first);
|
new_connection->second = copy_command (command->value.Connection->second);
|
||||||
new_connection->second =
|
|
||||||
copy_command (command->value.Connection->second);
|
|
||||||
new_command->value.Connection = new_connection;
|
new_command->value.Connection = new_connection;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pathological case. I'm not even sure that you can have a
|
|
||||||
function definition as part of a function definition. */
|
|
||||||
case cm_function_def:
|
case cm_function_def:
|
||||||
new_command->value.Function_def =
|
new_command->value.Function_def = copy_function_def (command->value.Function_def);
|
||||||
copy_function_def (command->value.Function_def);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return (new_command);
|
return (new_command);
|
||||||
}
|
}
|
||||||
|
|||||||
1553
cpp-Makefile
1553
cpp-Makefile
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,13 @@
|
|||||||
along with Bash; see the file COPYING. If not, write to the Free
|
along with Bash; see the file COPYING. If not, write to the Free
|
||||||
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined (HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bashansi.h"
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
|
|
||||||
/* Dispose of the command structure passed. */
|
/* Dispose of the command structure passed. */
|
||||||
@@ -25,7 +32,8 @@ void
|
|||||||
dispose_command (command)
|
dispose_command (command)
|
||||||
COMMAND *command;
|
COMMAND *command;
|
||||||
{
|
{
|
||||||
if (!command) return;
|
if (command == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (command->redirects)
|
if (command->redirects)
|
||||||
dispose_redirects (command->redirects);
|
dispose_redirects (command->redirects);
|
||||||
@@ -33,26 +41,23 @@ dispose_command (command)
|
|||||||
switch (command->type)
|
switch (command->type)
|
||||||
{
|
{
|
||||||
case cm_for:
|
case cm_for:
|
||||||
{
|
|
||||||
register FOR_COM *c = command->value.For;
|
|
||||||
dispose_word (c->name);
|
|
||||||
dispose_words (c->map_list);
|
|
||||||
dispose_command (c->action);
|
|
||||||
free (c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined (SELECT_COMMAND)
|
#if defined (SELECT_COMMAND)
|
||||||
case cm_select:
|
case cm_select:
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
register SELECT_COM *c = command->value.Select;
|
register FOR_COM *c;
|
||||||
|
#if defined (SELECT_COMMAND)
|
||||||
|
if (command->type == cm_select)
|
||||||
|
c = (FOR_COM *)command->value.Select;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
c = command->value.For;
|
||||||
dispose_word (c->name);
|
dispose_word (c->name);
|
||||||
dispose_words (c->map_list);
|
dispose_words (c->map_list);
|
||||||
dispose_command (c->action);
|
dispose_command (c->action);
|
||||||
free (c);
|
free (c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
case cm_group:
|
case cm_group:
|
||||||
{
|
{
|
||||||
@@ -63,12 +68,13 @@ dispose_command (command)
|
|||||||
|
|
||||||
case cm_case:
|
case cm_case:
|
||||||
{
|
{
|
||||||
register CASE_COM *c = command->value.Case;
|
register CASE_COM *c;
|
||||||
PATTERN_LIST *t, *p = c->clauses;
|
PATTERN_LIST *t, *p;
|
||||||
|
|
||||||
|
c = command->value.Case;
|
||||||
dispose_word (c->word);
|
dispose_word (c->word);
|
||||||
|
|
||||||
while (p)
|
for (p = c->clauses; p; )
|
||||||
{
|
{
|
||||||
dispose_words (p->patterns);
|
dispose_words (p->patterns);
|
||||||
dispose_command (p->action);
|
dispose_command (p->action);
|
||||||
@@ -83,8 +89,9 @@ dispose_command (command)
|
|||||||
case cm_until:
|
case cm_until:
|
||||||
case cm_while:
|
case cm_while:
|
||||||
{
|
{
|
||||||
register WHILE_COM *c = command->value.While;
|
register WHILE_COM *c;
|
||||||
|
|
||||||
|
c = command->value.While;
|
||||||
dispose_command (c->test);
|
dispose_command (c->test);
|
||||||
dispose_command (c->action);
|
dispose_command (c->action);
|
||||||
free (c);
|
free (c);
|
||||||
@@ -93,7 +100,9 @@ dispose_command (command)
|
|||||||
|
|
||||||
case cm_if:
|
case cm_if:
|
||||||
{
|
{
|
||||||
register IF_COM *c = command->value.If;
|
register IF_COM *c;
|
||||||
|
|
||||||
|
c = command->value.If;
|
||||||
dispose_command (c->test);
|
dispose_command (c->test);
|
||||||
dispose_command (c->true_case);
|
dispose_command (c->true_case);
|
||||||
dispose_command (c->false_case);
|
dispose_command (c->false_case);
|
||||||
@@ -103,7 +112,9 @@ dispose_command (command)
|
|||||||
|
|
||||||
case cm_simple:
|
case cm_simple:
|
||||||
{
|
{
|
||||||
register SIMPLE_COM *c = command->value.Simple;
|
register SIMPLE_COM *c;
|
||||||
|
|
||||||
|
c = command->value.Simple;
|
||||||
dispose_words (c->words);
|
dispose_words (c->words);
|
||||||
dispose_redirects (c->redirects);
|
dispose_redirects (c->redirects);
|
||||||
free (c);
|
free (c);
|
||||||
@@ -112,7 +123,9 @@ dispose_command (command)
|
|||||||
|
|
||||||
case cm_connection:
|
case cm_connection:
|
||||||
{
|
{
|
||||||
register CONNECTION *c = command->value.Connection;
|
register CONNECTION *c;
|
||||||
|
|
||||||
|
c = command->value.Connection;
|
||||||
dispose_command (c->first);
|
dispose_command (c->first);
|
||||||
dispose_command (c->second);
|
dispose_command (c->second);
|
||||||
free (c);
|
free (c);
|
||||||
@@ -121,7 +134,9 @@ dispose_command (command)
|
|||||||
|
|
||||||
case cm_function_def:
|
case cm_function_def:
|
||||||
{
|
{
|
||||||
register FUNCTION_DEF *c = command->value.Function_def;
|
register FUNCTION_DEF *c;
|
||||||
|
|
||||||
|
c = command->value.Function_def;
|
||||||
dispose_word (c->name);
|
dispose_word (c->name);
|
||||||
dispose_command (c->command);
|
dispose_command (c->command);
|
||||||
free (c);
|
free (c);
|
||||||
@@ -129,7 +144,7 @@ dispose_command (command)
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
report_error ("Attempt to free unknown command type `%d'.\n", command->type);
|
programming_error ("dispose_command: bad command type `%d'", command->type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free (command);
|
free (command);
|
||||||
@@ -140,8 +155,7 @@ void
|
|||||||
dispose_word (word)
|
dispose_word (word)
|
||||||
WORD_DESC *word;
|
WORD_DESC *word;
|
||||||
{
|
{
|
||||||
if (word->word)
|
FREE (word->word);
|
||||||
free (word->word);
|
|
||||||
free (word);
|
free (word);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +165,7 @@ dispose_words (list)
|
|||||||
WORD_LIST *list;
|
WORD_LIST *list;
|
||||||
{
|
{
|
||||||
WORD_LIST *t;
|
WORD_LIST *t;
|
||||||
|
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
t = list;
|
t = list;
|
||||||
@@ -189,7 +204,7 @@ dispose_redirects (list)
|
|||||||
case r_reading_until:
|
case r_reading_until:
|
||||||
case r_deblank_reading_until:
|
case r_deblank_reading_until:
|
||||||
free (t->here_doc_eof);
|
free (t->here_doc_eof);
|
||||||
/* ... */
|
/*FALLTHROUGH*/
|
||||||
case r_output_direction:
|
case r_output_direction:
|
||||||
case r_input_direction:
|
case r_input_direction:
|
||||||
case r_inputa_direction:
|
case r_inputa_direction:
|
||||||
@@ -200,6 +215,8 @@ dispose_redirects (list)
|
|||||||
case r_duplicating_input_word:
|
case r_duplicating_input_word:
|
||||||
case r_duplicating_output_word:
|
case r_duplicating_output_word:
|
||||||
dispose_word (t->redirectee.filename);
|
dispose_word (t->redirectee.filename);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free (t);
|
free (t);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user