Imported from ../bash-2.0.tar.gz.

This commit is contained in:
Jari Aalto 1996-12-23 17:02:34 +00:00
commit ccc6cda312
502 changed files with 91988 additions and 69123 deletions

View file

@ -1 +1 @@
1.14
2.0

View file

@ -1 +1 @@
7
0

575
CHANGES Normal file
View 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
View 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'.

332
COPYING
View file

@ -1,9 +1,8 @@
GNU GENERAL PUBLIC LICENSE
Version 1, February 1989
Version 2, June 1991
Copyright (C) 1989 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
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
The license agreements of most software companies try to keep users
at the mercy of those companies. By contrast, our General Public
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
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
General Public License applies to the Free Software Foundation's
software and to any other program whose authors commit to using it.
You can use it for your programs, too.
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
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
price. Specifically, the General Public License is designed to make
sure that you have the freedom to give away or sell copies of free
software, that you receive source code or can get it if you want it,
that you can change the software or use pieces of it in new free
programs; and that you know you can do these things.
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
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.
These restrictions translate to certain responsibilities for you if you
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
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
(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
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
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any program or other work which
contains a notice placed by the copyright holder saying it may be
distributed under the terms of this General Public License. The
"Program", below, refers to any such program or work, and a "work based
on the Program" means either the Program or any work containing the
Program or a portion of it, either verbatim or with modifications. Each
licensee is addressed as "you".
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
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
code as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and
disclaimer of warranty; keep intact all the notices that refer to this
General Public License and to the absence of any warranty; and give any
other recipients of the Program a copy of this General Public License
along with the Program. You may charge a fee for the physical act of
transferring a copy.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
2. You may modify your copy or copies of the Program or any portion of
it, and copy and distribute such modifications under the terms of Paragraph
1 above, provided that you also do the following:
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
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 changed the files and the date of any change; and
You may charge a fee for the physical act of transferring a copy, 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
in whole or in part contains the Program or any part thereof, either
with or without modifications, to be licensed at no charge to all
third parties under the terms of this General Public License (except
that you may choose to grant warranty protection to some or all
third parties, at your option).
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
c) If the modified program normally reads commands interactively when
run, you must cause it, when started running for such interactive use
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.
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
d) You may charge a fee for the physical act of transferring a
copy, and you may at your option offer warranty protection in
exchange for a fee.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
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
derivative) on a volume of a storage or distribution medium does not bring
the other work under the scope of these terms.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
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
it, under Paragraph 2) in object code or executable form under the terms of
Paragraphs 1 and 2 above provided that you also do one of the following:
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
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
source code, which must be distributed under the terms of
Paragraphs 1 and 2 above; or,
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
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
years, to give any third party free (except for a nominal charge
for the cost of distribution) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
3. You may copy and distribute the Program (or a work based on it,
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
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
modifications to it. For an executable file, complete source code means
all the source code for all modules it contains; but, as a special
exception, it need not include source code for modules which are standard
libraries that accompany the operating system on which the executable
file runs, or for standard header files or definitions files that
accompany that operating system.
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
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
Program except as expressly provided under this General Public License.
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
the Program is void, and will automatically terminate your rights to use
the Program under this License. However, parties who have received
copies, or rights to use copies, from you under this General Public
License will not have their licenses terminated so long as such parties
remain in full compliance.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
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
on the Program) you indicate your acceptance of this license to do so,
and all its terms and conditions.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
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
Program), the recipient automatically receives a license from the original
licensor to copy, distribute or modify the Program subject to these
terms and conditions. You may not impose any further restrictions on the
recipients' exercise of the rights granted herein.
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
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
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
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
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
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.
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
to ask for permission. For software which is copyrighted by the Free
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
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
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
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,
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
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
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
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
free software which everyone can redistribute and change under these
terms.
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 terms.
To do so, attach the following notices to the program. It is safest to
attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
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.>
Copyright (C) 19yy <name of author>
Copyright (C) 19yy <name of author>
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
the Free Software Foundation; either version 1, or (at your option)
any later version.
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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
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.
If the program is interactive, make it output a short notice like this
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'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the
appropriate parts of the General Public License. Of course, the
commands you use may be called something other than `show w' and `show
c'; they could even be mouse-clicks or menu items--whatever suits your
program.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
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
necessary. Here a sample; alter the names:
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
program `Gnomovision' (a program to direct compilers to make passes
at assemblers) written by James Hacker.
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
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.

View file

@ -1,18 +1,28 @@
The version of bash in this directory has been compiled on the
following systems:
Sun 690 SunOS 4.1.2
Sparcstation SunOS 5.3
Sparcstation NetBSD 0.9a
386 BSDI BSD/386 1.0, 1.1
NeXTstation NeXT OS 2.1
IBM RT IBM/4.3 (AOS)
Motorola Delta 88K SVR3.2
Decstation 3100 Ultrix 4.3
Dec 4000 Alpha AXP DEC OSF/1 V1.3
386 ISC UNIX 3.0.1
386 FreeBSD 1.1
IBM RS/6000 AIX 3.2
Amiga Amiga UNIX 2.1
Sony NEWS 841 NEWS OS
HP 9000/834 HP/UX 7.0
By chet:
SunOS 4.1.4
SunOS 5.5
BSDI BSD/OS 2.1
Motorola SVR3.2
FreeBSD 2.1.5
AIX 4.2
HP/UX 9.05, 10.01, 10.10, 10.20
By other testers:
SCO ODT 2.0
SCO 3.2v5.0, 3.2v4.2
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

View file

@ -1,63 +1,86 @@
Starting bash with the `-posix' command-line option or setting the variable
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.
Bash POSIX Mode
===============
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
$PATH to find the new location.
The following list is what's changed when `POSIX mode' is in effect:
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
exits with a non-zero status is `Done(status)'.
2. The `>&' redirection does not redirect stdout and stderr.
4. The <> redirection does not open a file for both stdin and stdout, but
rather opens it for read-write on fd 0.
3. The message printed by the job control code and builtins when a job
exits with a non-zero status is `Done(status)'.
5. Reserved words may not be aliased.
4. Reserved words may not be aliased.
6. The Posix.2 PS1 and PS2 expansions of `!' -> history number and `!!' -> `!'
are enabled.
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.
7. Interactive comments are enabled by default. (Note that this version has
them on by default anyway.)
6. Interactive comments are enabled by default. (Note that Bash has
them on by default anyway.)
8. The Posix.2 startup files are executed ($ENV) rather than the normal bash
files.
7. The POSIX.2 startup files are executed (`$ENV') rather than the
normal Bash files.
9. Tilde expansion is only performed on assignments preceding a command name,
rather than on all assignment statements on the line.
8. Tilde expansion is only performed on assignments preceding a
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,
separated by spaces.
10. The output of `kill -l' prints all the signal names on a single
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
in the redirection unless the shell is interactive
12. Redirection operators do not perform filename expansion on the word
in the redirection unless the shell is interactive.
14. Function names must be valid shell identifiers. That is, they may not
contain characters other than letters, digits, and underscores, and
may not start with a digit
13. Function names must be valid shell `name's. That is, they may not
contain characters other than letters, digits, and underscores, and
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
are equivalent. This means that:
15. If a POSIX.2 special builtin returns an error status, a
non-interactive shell exits. The fatal errors are those listed in
the POSIX.2 standard, and include things like passing incorrect
options, redirection errors, variable assignment errors for
assignments preceding the command name, and so on.
o assignment statements affect the execution environment of all
builtins, not just special ones
o temporary assignments do not persist after Posix.2 special
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
16. If the `cd' builtin finds a directory to change to using
`$CDPATH', the value it assigns to the `PWD' variable does not
contain any symbolic links, as if `cd -P' had been executed.
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

View file

@ -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:
CWRU.chlog - 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
changelog - my change log since the last release
POSIX.NOTES - list of what changes for `posix mode'
README - this file
RSH.README - explanation of the bash `restricted shell' mode
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

File diff suppressed because it is too large Load diff

449
CWRU/mh-folder-comp Normal file
View 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;
+ }
/*

View file

@ -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 */

376
INSTALL
View file

@ -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
to dynamically figure out what kind of machine and operating system
you are using. It makes an educated guess based on the information
it finds.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package
(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
machine and operating system has been chosen for you. This
information is also saved in the file `.machine' so you can look at
it later.
If you need to do unusual things to compile the package, please try to
figure out how `configure' could check whether or not to do them, and
mail diffs or instructions to `bash-maintainers@prep.ai.mit.edu' so
they can be considered for the next release.
Therefore, for most machines, simply follow this simple checklist
to install BASH:
The file `configure.in' is used to create `configure' by a program
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
`make CC=gcc CPPNAME='$(CC) -E''.
The simplest way to compile Bash is:
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
of your local GNU software installation tree) to copy bash to
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.
2. Type `make' to compile Bash and build the `bashbug' bug reporting
script.
* 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:
File: bash.info, Node: Problems, Next: Files, Prev: Install, Up: Install
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
What if it Doesn't Install so Easily?
=====================================
On systems that have the `env' program, you can do it like this:
Sometimes BASH gets confused and will make the wrong assumptions
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.
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
However, if BASH says that your machine type is an
"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).
The configuration process uses GCC to build Bash if it is available.
On the MIPSEB with the BSD universe, you must:
Compiling For Multiple Architectures
====================================
1) Place /bsd43/bin in your PATH before /bin
2) Use $(CC) -E instead of /lib/cpp to build cpp-Makefile.
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 `..'.
On SCO Xenix 386, you must:
If you have to use a `make' that does not supports the `VPATH'
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.
1) Use $(CC) -E instead of /lib/cpp to build cpp-Makefile.
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':
On Interactive Unix version 3 or 4, you must:
bash /usr/gnu/src/bash-2.0/support/mkclone -s /usr/gnu/src/bash-2.0 .
1) Edit cpp-Makefile to remove either -O or -g from DEBUG_FLAGS
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.
File: bash.info, Node: Files, Next: Porting, Prev: Problems, Up: Install
Installation Names
==================
Files Used in the `make' Process.
=================================
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'.
The following files are used during the installation of BASH, 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.
`Makefile'
This is responsible for making the actual `Makefile' that is
used to create Bash. It runs the C preprocessor (usually
located in `/lib/cpp') on the file `cpp-Makefile', producing
the output file `bash-Makefile'.
Specifying the System Type
==========================
`cpp-Makefile'
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'.
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--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').
`machines.h'
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.
See the file `support/config.sub' for the possible values of each field.
These conditional blocks are depend upon the unique identifier
that `cpp' has predefined for this machine. In some cases,
additional information can be passed from `Makefile'. It is
possible to pass information such as whether or not a
particular file is available on this system, and so on.
Sharing Defaults
================
`sysdefs.h'
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.
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'. `configure'
looks for `PREFIX/share/config.site' if it exists, then
`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.
`bash-Makefile'
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.
Operation Controls
==================
`configure' recognizes the following options to control how it operates.
File: bash.info, Node: Porting, Next: Bugs, Prev: Files, Up: Install
`--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'.
What if You Have to Port to a New Machine?
==========================================
`--help'
Print a summary of the options to `configure', and exit.
Sometimes you may want to port BASH to a new, previously
unsupported machine. To do so you need to create a block in
`machines.h' which is conditional based on a unique identifier
present in your version of the C preprocessor.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made.
If you don't know what that symbol is, you might try the following
simple test:
`--srcdir=DIR'
Look for the Bash source code in directory DIR. Usually
`configure' can determine that directory automatically.
echo "main () { }" > foo.c
cc -v foo.c
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
You are looking for `-DMACHINE', where `MACHINE' is an identifier
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.
`configure' also accepts some other, not widely used, boilerplate
options.
Let's say you have a machine from Yoyodyne Industries, called the
YoYo. It runs a version of BSD, so it is reasonably compatible.
However, the `cpp' on this YoYo machine doesn't define any unique
identifiers. You should change the `Makefile' line for `CPPFLAGS'
to:
Optional Features
=================
CPPFLAGS = -P -DYoYo
The Bash `configure' has a number of `--enable-FEATURE' options, where
FEATURE indicates an optional part of the package. There are also
several `--with-PACKAGE' options, where PACKAGE is something like
`gnu-malloc' or `purify' (for the Purify memory allocation checker). 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'.
Then, in `machines.h', you copy the block for `UNKNOWN_MACHINE',
and change the conditional to;
Here is a complete list of the `--enable-' and `--with-' options that
the Bash `configure' recognizes.
#if defined (YoYo)
`--with-gnu-malloc'
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.
Inside of the YoYo block you define `M_MACHINE="YoYo"', and
`M_OS=Bsd'. You also modify the existing defines to match your
machine's software.
`--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.
If BASH still won't compile, perhaps because of missing code that
is required for your YoYo machine, you will have to write that code
and place it within a conditional block based on YoYo.
`--with-afs'
Define if you are using the Andrew File System from Transarc.
Most machines aren't that difficult; simply redefining a few of the
default values is sufficient. If you do run across a difficult
machine, please send all fixes and changes to
bash-maintainers@prep.ai.mit.edu in the form of context diffs:
`--with-purify'
Define this to use the Purify memory allocation checker from Pure
Software.
diff -c orig-machines.h machines.h >machines.diffs
`--enable-minimal-config'
This produces a shell with minimal features, close to the
historical Bourne shell.
Please include information about which version of the shell you have.
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'.
For those machines which prove more difficult, or if you are not
sure about where to start, the scripts in the `portbash' directory
may prove helpful.
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.
File: bash.info, Node: Bugs, Prev: Porting, Up: Install
`--enable-job-control'
This enables job control features, if the OS supports them.
Reporting Bugs
==============
`--enable-alias'
Allow alias expansion and include the `alias' and `unalias'
builtins.
If you find a bug in bash, you should report it. But first you
should make sure that it really is a bug and that it appears in the
latest version of BASH that is available.
`--enable-readline'
Include support for command-line editing and history with the Bash
version of the Readline library.
Once you have ascertained that a bug really exists, you are welcome
to mail in a bug report. If you have a fix, please mail that too!
The program `bashbug' is used to submit bug reports.
`--enable-history'
Include command history and the `fc' and `history' builtin
commands.
Suggestions and "philosophical" bug reports should be mailed to
bug-bash@ai.mit.edu. Genuine bug reports should be mailed to the
same place, or to bash-maintainers@prep.ai.mit.edu. The `bashbug'
script sends its messages to bug-bash@prep.ai.mit.edu.
`--enable-bang-history'
Include support for `csh'-like history substitution.
*All* bug reports should include:
`--enable-directory-stack'
Include support for a `csh'-like directory stack and the `pushd',
`popd', and `dirs' builtins.
* The version number of BASH.
`--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 hardware and operating system used.
`--enable-process-substitution'
This enables process substitution (*note Process Substitution::.)
if the OS provides the necessary support.
* The compiler used to compile BASH.
`--enable-prompt-string-decoding'
Turn on the interpretation of a number of backslash-escaped
characters in the `$PS1', `$PS2', `$PS3', and `$PS4' prompt
strings.
* A description of the bug's behavior.
`--enable-select'
Include the `ksh' `select' builtin, which allows the generation of
simple menus.
* A short script or "recipe" which demonstrates the bug.
`--enable-help-builtin'
Include the `help' builtin, which displays help on shell builtins
and variables.
The `bashbug' program includes much of this information
automatically. Without this information, it is generally not
possible to successfully debug BASH. Usually, without this
information, the bug won't manifest itself!
`--enable-array-variables'
Include support for one-dimensional array shell variables.
Discussion and questions about BASH in general (including
questions about this documentation) can be sent to
bash-maintainers@prep.ai.mit.edu.
`--enable-dparen-arithmetic'
Include support for the `ksh' `((...))' command.
`--enable-brace-expansion'
Include `csh'-like brace expansion ( `b{a,b}c' ==> `bac bbc' ).
`--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.

360
MANIFEST
View file

@ -7,17 +7,20 @@
CWRU d
CWRU/misc d
builtins d
documentation d
doc d
examples d
examples/bashdb d
examples/functions d
examples/scripts d
examples/scripts.v2 d
examples/scripts.noah d
examples/startup-files d
examples/misc d
examples/loadables d
lib d
lib/doc-support d
lib/glob d
lib/glob/doc d
lib/malloc d
lib/malloclib d
lib/posixheaders d
lib/readline d
lib/readline/doc d
@ -26,20 +29,32 @@ lib/termcap d
lib/termcap/grot d
lib/tilde d
lib/tilde/doc d
portbash d
support d
tests d
tests/misc d
README f
RELEASE f
INSTALL f
CHANGES f
COMPAT f
COPYING f
INSTALL f
MANIFEST f
NEWS f
NOTES f
README f
configure.in f
configure f
Makefile f
cpp-Makefile f
Makefile.in 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
general.c f
list.c f
locale.c f
stringlib.c f
oslib.c f
variables.c f
make_cmd.c f
copy_cmd.c f
@ -47,16 +62,17 @@ unwind_prot.c f
dispose_cmd.c f
getcwd.c f
bashhist.c f
hash.c f
hashlib.c f
parse.y f
pathexp.c f
subst.c f
shell.c f
trap.c f
sig.c f
siglist.c f
version.c f
flags.c f
jobs.c f
newversion.c f
input.c f
mailcheck.c f
test.c f
@ -69,22 +85,23 @@ bracecomp.c f
nojobs.c f
vprint.c f
error.c f
signames.c f
endian.c f
xmalloc.c f
alias.h f
config.h f
config.h.mini f
builtins.h f
parser.h f
bashhist.h f
bashline.h f
variables.h f
machines.h f
array.h f
jobs.h f
maxpath.h f
filecntl.h f
hash.h f
hashlib.h f
quit.h f
flags.h f
shell.h f
pathexp.h f
parser.h f
sig.h f
trap.h f
general.h f
unwind_prot.h f
@ -93,22 +110,28 @@ error.h f
command.h f
externs.h f
siglist.h f
subst.h f
subst.h f
dispose_cmd.h f
bashansi.h f
bashtty.h f
bashjmp.h f
bashwait.h f
bashintl.h f
make_cmd.h f
bashhist.h f
execute_cmd.h f
bashtypes.h f
mailcheck.h f
pathnames.h f
y.tab.c f
y.tab.h f
posixdir.h f
posixstat.h f
stdc.h f
ansi_stdlib.h f
memalloc.h f
parser-built f
builtins/ChangeLog f
builtins/Makefile f
builtins/Makefile.in f
builtins/alias.def f
builtins/bind.def f
builtins/break.def f
@ -121,6 +144,8 @@ builtins/declare.def f
builtins/echo.def f
builtins/enable.def f
builtins/eval.def f
builtins/evalfile.c f
builtins/evalstring.c f
builtins/exec.def f
builtins/exit.def f
builtins/fc.def f
@ -136,12 +161,14 @@ builtins/history.def f
builtins/jobs.def f
builtins/kill.def f
builtins/mkbuiltins.c f
builtins/pushd.def f
builtins/read.def f
builtins/reserved.def f
builtins/return.def f
builtins/set.def f
builtins/setattr.def f
builtins/shift.def f
builtins/shopt.def f
builtins/source.def f
builtins/suspend.def f
builtins/test.def f
@ -157,63 +184,76 @@ builtins/inlib.def f
builtins/bashgetopt.c f
builtins/common.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/Makefile f
lib/glob/Makefile.in f
lib/glob/fnmatch.c f
lib/glob/fnmatch.h f
lib/glob/glob.c f
lib/glob/glob.h f
lib/glob/doc/Makefile f
lib/glob/doc/glob.texi f
lib/glob/ndir.h f
lib/malloc/Makefile f
lib/malloc/alloca.c f
lib/malloc/Makefile.in f
lib/malloc/getpagesize.h f
lib/malloc/i386-alloca.s f
lib/malloc/alloca.c f
lib/malloc/malloc.c f
lib/malloc/x386-alloca.s f
lib/malloc/gmalloc.c f
lib/malloc/xmalloc.c f
lib/malloclib/Makefile f
lib/malloclib/alloca.c f
lib/malloclib/i386-alloca.s f
lib/malloclib/calloc.c 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/malloc/stub.c f
lib/malloc/i386-alloca.s f
lib/malloc/x386-alloca.s f
lib/posixheaders/posixdir.h f
lib/posixheaders/posixstat.h f
lib/posixheaders/ansi_stdlib.h f
lib/posixheaders/stdc.h f
lib/posixheaders/memalloc.h f
lib/posixheaders/filecntl.h f
lib/readline/COPYING f
lib/readline/readline.c f
lib/readline/readline.h f
lib/readline/Makefile.in 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/history.h f
lib/readline/Makefile f
lib/readline/chardefs.h f
lib/readline/emacs_keymap.c f
lib/readline/keymaps.h f
lib/readline/vi_keymap.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/keymaps.c f
lib/readline/util.c f
lib/readline/terminal.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/rlman.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/manexamp.c f
lib/readline/examples/histexamp.c f
lib/readline/examples/rltest.c f
lib/readline/examples/Inputrc f
lib/readline/README 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/Makefile.in f
lib/termcap/termcap.c f
lib/termcap/termcap.h f
lib/termcap/tparam.c f
@ -265,62 +288,80 @@ lib/termcap/grot/configure.in f
lib/termcap/grot/COPYING f
lib/termcap/grot/README f
lib/tilde/ChangeLog f
lib/tilde/Makefile f
lib/tilde/Makefile.in f
lib/tilde/doc/tilde.texi f
lib/tilde/doc/Makefile f
lib/tilde/tilde.c f
lib/tilde/tilde.h f
lib/tilde/memalloc.h f
CWRU/misc/open-files.c f
CWRU/misc/sigs.c f
CWRU/misc/pid.c f
CWRU/misc/sigstat.c f
CWRU/misc/bison f
CWRU/misc/aux-mach-desc f
CWRU/PLATFORMS f
CWRU/README f
CWRU/POSIX.NOTES f
CWRU/changelog f
CWRU/sh-redirection-hack f
documentation/Makefile f
documentation/bash.1 f
documentation/bash.ps f
documentation/bash.txt f
documentation/README f
documentation/readline.3 f
documentation/readline.ps f
documentation/readline.txt f
documentation/texinfo.tex f
documentation/features.texi f
documentation/features.info f
documentation/features.dvi f
documentation/features.ps f
documentation/builtins.1 f
documentation/builtins.ps f
documentation/builtins.txt f
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
CWRU/sh-redir-hack f
CWRU/mh-folder-comp f
doc/FAQ f
doc/Makefile.in f
doc/bash.1 f
doc/bashbug.1 f
doc/README f
doc/INTRO f
doc/readline.3 f
doc/texinfo.tex f
doc/bashref.texi f
doc/bashref.info f
doc/builtins.1 f
doc/article.ms f
support/config.guess f
support/config.sub f
support/printenv f 755
support/bash.xbm f
support/FAQ f
support/PORTING f
support/mklinks f
support/mkdirs f
support/clone-bash f
support/mkclone f 755
support/mkdirs f 755
support/mkversion.c f
support/mksignames.c f
support/bashbug.sh f
support/mkmachtype f
support/recho.c f
support/srcdir f
support/zecho.c 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/kshenv f
examples/functions/autoload f
examples/functions/autoload.v2 f
examples/functions/csh-compat f
examples/functions/shcat f
examples/functions/substr2 f
@ -338,18 +379,39 @@ examples/functions/manpage f
examples/functions/fstty f
examples/functions/jj.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/adventure.sh f
examples/scripts/precedence 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/Bash_aliases f
examples/startup-files/Bash_profile f
examples/startup-files/bash-profile f
examples/startup-files/bashrc f
examples/suncmd.termcap f
examples/alias-conv.sh f
examples/misc/suncmd.termcap f
examples/misc/alias-conv.sh f
examples/misc/alias-conv.bash f
examples/misc/cshtobash 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-star.sh f
tests/dollar.right f
@ -357,6 +419,8 @@ tests/exp-tests f
tests/exp.right f
tests/glob-test f
tests/glob.right f
tests/heredoc.tests f
tests/heredoc.right f
tests/ifs-test-1.sh f
tests/ifs-test-2.sh f
tests/ifs-test-3.sh f
@ -368,26 +432,52 @@ tests/input-line.sub f
tests/input.right f
tests/minus-e f
tests/minus-e.right f
tests/more-exp.tests f
tests/more-exp.right f
tests/new-exp.tests 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/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-arith f
tests/run-array f
tests/run-braces f
tests/run-dollars f
tests/run-exp-tests f
tests/run-glob-test f
tests/run-heredoc f
tests/run-ifs-tests f
tests/run-input-test f
tests/run-minus-e f
tests/run-more-exp f
tests/run-new-exp f
tests/run-nquote f
tests/run-posix2 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-strip f
tests/run-test f
tests/run-tilde f
tests/run-varenv f
tests/set-e-test f
tests/set-e.right f
tests/strip.tests f
tests/strip.right f
tests/test-tests f
tests/test.right f
tests/tilde-tests f
tests/tilde.right f
tests/varenv.right f
@ -411,11 +501,43 @@ tests/misc/sigint.t3.sh f
tests/misc/sigint.t4.sh f
tests/misc/test-minus-e.1 f
tests/misc/test-minus-e.2 f
portbash/signals.sh f
portbash/stdio.sh f
portbash/libc.sh f
portbash/mkdesc.sh f
portbash/README f
portbash/strings.sh f
portbash/syscalls.sh f
portbash/pgrp.c f
examples/scripts.v2/PERMISSION f
examples/scripts.v2/README f
examples/scripts.v2/arc2tarz f
examples/scripts.v2/bashrand f
examples/scripts.v2/cdhist.bash f
examples/scripts.v2/corename f
examples/scripts.v2/fman 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
View file

@ -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
View 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
View file

@ -1,10 +1,280 @@
This file documents the bugs fixed between this release, bash-1.14.7,
and the last public bash release, 1.14.6.
This is a terse description of the new features added to bash-2.0 since
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
all available memory was fixed.
a. There is a new invocation option, -D, that dumps translatable strings
in a script.
b. A sign-extension bug that caused a security hole for non-interactive
shells was fixed.
b. The `long' invocation options must now be prefixed with `--'.
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
View 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
View file

@ -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
Again SHell, an interactive shell with Bourne shell syntax (/bin/sh);
This is GNU Bash, version 2.0. Bash is the GNU Project's Bourne
Again SHell, a complete implementation of the POSIX.2 shell spec,
but also with interactive command line editing, job control on
architectures that support it, Csh-like history features and brace
expansion, and a slew of other stuff. For more information on the
features of Bash that are new to this type of shell, see the file
`documentation/features.texi'. There is also a DVI file there, as
well as a large man page.
architectures that support it, csh-like features such as history
substitution and brace expansion, and a slew of other features.
For more information on the features of Bash that are new to this
type of shell, see the file `doc/features.texi'. There is also a
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
process, so no intervention should be necessary. If you want to
use gcc, type `make CC=gcc CPPNAME='$(CC) -E''.
See the file CWRU/POSIX.NOTES for a discussion of how Bash differs
from the POSIX.2 spec and a description of the Bash `posix mode'.
You may want to read the file INSTALL in this directory for more
information if the make fails.
There are some user-visible incompatibilities between this version
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
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.
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
using the `bashbug' program that is built and installed at the same
time as bash.
The discussion list "bug-bash@prep.ai.mit.edu" often contains information
about new ports of Bash, or discussions of new features or behavior
changes that people would like. This mailing list is also available
as a usenet newsgroup: gnu.bash.bug.
The discussion list `bug-bash@prep.ai.mit.edu' often contains
information about new ports of Bash, or discussions of new
features or behavior changes that people would like. This
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
include:
When you send a bug report to bug-bash@prep.ai.mit.edu, please include:
* the version number of Bash
* 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 recipe for recreating the bug reliably
* a fix for the bug if you have one!
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
like this shell to be the best that we can make it.

269
RELEASE
View file

@ -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
View 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
])

197
alias.c
View file

@ -19,12 +19,19 @@
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 (ALIAS)
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include "bashansi.h"
#include "config.h"
#include "command.h"
#include "general.h"
#include "hash.h"
#include "externs.h"
#include "alias.h"
static int qsort_alias_compare ();
@ -44,22 +51,18 @@ initialize_aliases ()
}
/* Scan the list of aliases looking for one with NAME. Return NULL
if the alias doesn't exist, else a pointer to the assoc. */
ASSOC *
if the alias doesn't exist, else a pointer to the alias_t. */
alias_t *
find_alias (name)
char *name;
{
BUCKET_CONTENTS *al;
if (!aliases)
return ((ASSOC *)NULL);
else
al = find_hash_item (name, aliases);
if (aliases == 0)
return ((alias_t *)NULL);
if (al)
return ((ASSOC *)al->data);
else
return ((ASSOC *)NULL);
al = find_hash_item (name, aliases);
return (al ? (alias_t *)al->data : (alias_t *)NULL);
}
/* Return the value of the alias for NAME, or NULL if there is none. */
@ -67,11 +70,13 @@ char *
get_alias_value (name)
char *name;
{
ASSOC *alias = find_alias (name);
if (alias)
return (alias->value);
else
alias_t *alias;
if (aliases == 0)
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,
@ -80,10 +85,15 @@ void
add_alias (name, value)
char *name, *value;
{
ASSOC *temp = (ASSOC *)NULL;
BUCKET_CONTENTS *elt;
alias_t *temp;
int n;
if (!aliases)
initialize_aliases ();
{
initialize_aliases ();
temp = (alias_t *)NULL;
}
else
temp = find_alias (name);
@ -91,20 +101,39 @@ add_alias (name, value)
{
free (temp->value);
temp->value = savestring (value);
n = value[strlen (value) - 1];
if (n == ' ' || n == '\t')
temp->flags |= AL_EXPANDNEXT;
}
else
{
BUCKET_CONTENTS *elt;
temp = (ASSOC *)xmalloc (sizeof (ASSOC));
temp = (alias_t *)xmalloc (sizeof (alias_t));
temp->name = savestring (name);
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->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
the number of aliases left in the table, or -1 if the alias didn't
exist. */
@ -114,93 +143,59 @@ remove_alias (name)
{
BUCKET_CONTENTS *elt;
if (!aliases)
if (aliases == 0)
return (-1);
elt = remove_hash_item (name, aliases);
if (elt)
{
ASSOC *t;
t = (ASSOC *)elt->data;
free (t->name);
free (t->value);
free_alias_data (elt->data);
free (elt->key); /* alias name */
free (t);
return (aliases->nentries);
}
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. */
void
delete_all_aliases ()
{
register int i;
if (!aliases)
if (aliases == 0)
return;
for (i = 0; i < aliases->nbuckets; i++)
{
register BUCKET_CONTENTS *bp;
bp = get_hash_bucket (i, aliases);
delete_alias_list (bp);
}
flush_hash_table (aliases, free_alias_data);
free (aliases);
aliases = (HASH_TABLE *)NULL;
}
/* Return an array of aliases that satisfy the conditions tested by FUNCTION.
If FUNCTION is NULL, return all aliases. */
static ASSOC **
static alias_t **
map_over_aliases (function)
Function *function;
{
register int i;
register BUCKET_CONTENTS *tlist;
ASSOC *alias, **list = (ASSOC **)NULL;
int list_index = 0, list_size = 0;
alias_t *alias, **list;
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);
while (tlist)
{
alias = (ASSOC *)tlist->data;
alias = (alias_t *)tlist->data;
if (!function || (*function) (alias))
{
if (list_index + 1 >= list_size)
list = (ASSOC **)
xrealloc ((char *)list, (list_size += 20) * sizeof (ASSOC *));
list = (alias_t **)
xrealloc ((char *)list, (list_size += 20) * sizeof (alias_t *));
list[list_index++] = alias;
list[list_index] = (ASSOC *)NULL;
list[list_index] = (alias_t *)NULL;
}
tlist = tlist->next;
}
@ -210,31 +205,31 @@ map_over_aliases (function)
static void
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
qsort_alias_compare (as1, as2)
ASSOC **as1, **as2;
alias_t **as1, **as2;
{
int result;
if ((result = (*as1)->name[0] - (*as2)->name[0]) == 0)
result = strcmp ((*as1)->name, (*as2)->name);
return (result);
}
/* Return a sorted list of all defined aliases */
ASSOC **
/* Return a sorted list of all defined aliases */
alias_t **
all_aliases ()
{
ASSOC **list;
alias_t **list;
if (!aliases)
return ((ASSOC **)NULL);
return ((alias_t **)NULL);
list = map_over_aliases ((Function *)NULL);
if (list)
@ -246,12 +241,10 @@ char *
alias_expand_word (s)
char *s;
{
ASSOC *r = find_alias (s);
alias_t *r;
if (r)
return (savestring (r->value));
else
return ((char *)NULL);
r = find_alias (s);
return (r ? savestring (r->value) : (char *)NULL);
}
/* Return non-zero if CHARACTER is a member of the class of characters
@ -391,7 +384,7 @@ skipws (string, start)
so all characters show up (e.g. foo'' and foo""bar) */
static int
rd_token (string, start)
char *string;
char *string;
int start;
{
register int i;
@ -408,7 +401,7 @@ rd_token (string, start)
/* If this character is a quote character, we want to call skipquotes
to get the whole quoted portion as part of this word. That word
will not generally match an alias, even if te unquoted word would
have. The presence of the quotes in the token serves then to
have. The presence of the quotes in the token serves then to
inhibit expansion. */
if (quote_char (string[i]))
{
@ -431,7 +424,7 @@ alias_expand (string)
register int i, j, start;
char *token = xmalloc (line_len);
int tl, real_start, expand_next, expand_this_token;
ASSOC *alias;
alias_t *alias;
line[0] = i = 0;
expand_next = 0;
@ -462,8 +455,7 @@ alias_expand (string)
expanding it if there is not enough room. */
j = strlen (line);
tl = i - start; /* number of characters just skipped */
if (1 + j + tl >= line_len)
line = (char *)xrealloc (line, line_len += (50 + tl));
RESIZE_MALLOCED_BUFFER (line, j, (tl + 1), line_len, (tl + 50));
strncpy (line + j, string + start, tl);
line[j + tl] = '\0';
@ -506,30 +498,35 @@ alias_expand (string)
(expand_this_token || alias_expand_all) &&
(alias = find_alias (token)))
{
char *v = alias->value;
int l = strlen (v);
char *v;
int vlen, llen;
v = alias->value;
vlen = strlen (v);
llen = strlen (line);
/* +3 because we possibly add one more character below. */
if ((l + 3) > line_len - (int)strlen (line))
line = (char *)xrealloc (line, line_len += (50 + l));
RESIZE_MALLOCED_BUFFER (line, llen, (vlen + 3), line_len, (vlen + 50));
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)
expand_next = 1;
}
else
{
int ll = strlen (line);
int tlen = i - real_start; /* tlen == strlen(token) */
int llen, tlen;
if (ll + tlen + 2 > line_len)
line = (char *)xrealloc (line, line_len += 50 + ll + tlen);
llen = strlen (line);
tlen = i - real_start; /* tlen == strlen(token) */
strncpy (line + ll, string + real_start, tlen);
line[ll + tlen] = '\0';
RESIZE_MALLOCED_BUFFER (line, llen, (tlen + 1), line_len, (llen + tlen + 50));
strncpy (line + llen, string + real_start, tlen);
line[llen + tlen] = '\0';
}
command_word = 0;
}
}
#endif /* ALIAS */

45
alias.h
View file

@ -18,33 +18,22 @@
along with Bash; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (_ALIAS_)
#define _ALIAS_
#if !defined (_ALIAS_H_)
#define _ALIAS_H_
#include "hash.h"
#include "hashlib.h"
extern char *xmalloc ();
#if !defined (whitespace)
# 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 {
typedef struct alias {
char *name;
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. */
extern HASH_TABLE *aliases;
@ -52,8 +41,8 @@ extern HASH_TABLE *aliases;
extern void initialize_aliases ();
/* Scan the list of aliases looking for one with NAME. Return NULL
if the alias doesn't exist, else a pointer to the assoc. */
extern ASSOC *find_alias ();
if the alias doesn't exist, else a pointer to the alias. */
extern alias_t *find_alias ();
/* Return the value of the alias for NAME, or NULL if there is none. */
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. */
extern int remove_alias ();
/* Remove all aliases. */
extern void delete_all_aliases ();
/* Return a new line, with any aliases expanded. */
extern char *alias_expand ();
/* 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
View 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
View 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_ */

View file

@ -18,7 +18,15 @@
with Bash; see the file COPYING. If not, write to the Free Software
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 <errno.h>
#include "bashansi.h"
@ -26,7 +34,33 @@
#include "filecntl.h"
#include "shell.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 <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. */
/* Non-zero means to remember lines typed to the shell on the history
@ -35,87 +69,145 @@
int remember_on_history = 1;
/* 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. */
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
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.,
if the user enters:
bash$ for i in a b c
> do
> echo $i
> done
> do
> echo $i
> done
Each line will be individually saved in the history.
bash$ history
10 for i in a b c
11 do
12 echo $i
13 done
14 history
11 do
12 echo $i
13 done
14 history
If the variable command_oriented_history is set, multiple lines
which form one command will be saved as one history entry.
bash$ for i in a b c
> do
> echo $i
> done
bash$ history
> do
> echo $i
> done
bash$ history
10 for i in a b c
do
echo $i
done
11 history
11 history
The user can then recall the whole command all at once instead
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.
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 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. */
extern int interactive;
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 void maybe_add_history (); /* forward declaration */
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. */
void
load_history ()
{
char *hf;
struct stat buf;
/* Truncate history file for interactive shells which desire it.
Note that the history file is automatically truncated to the
size of HISTSIZE if the user does not explicitly set the size
differently. */
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. */
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);
using_history ();
history_lines_in_file = where_history ();
}
read_history (hf);
using_history ();
history_lines_in_file = where_history ();
}
}
@ -123,45 +215,74 @@ load_history ()
void
save_history ()
{
char *hf = get_string_value ("HISTFILE");
char *hf;
struct stat buf;
if (hf && *hf)
hf = get_string_value ("HISTFILE");
if (hf && *hf && stat (hf, &buf) == 0)
{
struct stat buf;
/* Append only the lines that occurred this session to
the history file. */
using_history ();
if (stat (hf, &buf) == 0)
{
/* Append only the lines that occurred this session to
the history file. */
using_history ();
if (history_lines_this_session < where_history () || force_append_history)
append_history (history_lines_this_session, hf);
else
write_history (hf);
if (history_lines_this_session < where_history ())
append_history (history_lines_this_session, hf);
else
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
this session to the history file. */
int
maybe_save_shell_history ()
{
int result = 0;
int result;
char *hf;
struct stat buf;
result = 0;
if (history_lines_this_session)
{
char *hf = get_string_value ("HISTFILE");
hf = get_string_value ("HISTFILE");
if (hf && *hf)
{
struct stat buf;
/* If the file doesn't exist, then create it. */
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)
close (file);
}
@ -170,7 +291,7 @@ maybe_save_shell_history ()
stifled. If the history has been stifled, rewrite the
history file. */
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);
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_this_session = 0;
sv_histsize ("HISTFILESIZE");
}
}
return (result);
}
#if defined (HISTORY_REEDITING)
#if defined (READLINE)
/* Tell readline () that we have some text for it to edit. */
static void
re_edit (text)
char *text;
{
#if defined (READLINE)
if (strcmp (bash_input.name, "readline stdin") == 0)
if (bash_input.type == st_stdin)
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
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 *return_value;
int expanded = 0;
int expanded;
return_value = line;
expanded = 0;
# if defined (BANG_HISTORY)
/* History expand the line. If this results in no errors, then
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);
@ -230,7 +365,7 @@ pre_process_line (line, print_changes, addit)
{
if (expanded < 0)
internal_error (history_value);
else
else if (hist_verify == 0)
fprintf (stderr, "%s\n", history_value);
}
@ -239,13 +374,22 @@ pre_process_line (line, print_changes, addit)
{
free (history_value);
# if defined (HISTORY_REEDITING)
# if defined (READLINE)
/* New hack. We can allow the user to edit the
failed history expansion. */
re_edit (line);
# endif /* HISTORY_REEDITING */
if (history_reediting && expanded < 0)
re_edit (line);
# endif /* READLINE */
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,
@ -259,7 +403,7 @@ pre_process_line (line, print_changes, addit)
if (addit && remember_on_history && *return_value)
maybe_add_history (return_value);
if (!expanded)
if (expanded == 0)
return_value = savestring (line);
return (return_value);
@ -270,43 +414,46 @@ void
maybe_add_history (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
and subsequent lines of a multi-line command when
command_oriented_history is enabled. */
if (command_oriented_history && current_command_line_count > 1)
h = 0;
else
h = history_control;
{
bash_add_history (line);
return;
}
switch (h)
switch (history_control)
{
case 0:
bash_add_history (line);
should_add = 1;
break;
case 1:
if (*line != ' ')
bash_add_history (line);
should_add = 1;
break;
case 3:
if (*line == ' ')
break;
break;
/* FALLTHROUGH if case == 3 (`ignoreboth') */
case 2:
{
HIST_ENTRY *temp;
using_history ();
temp = previous_history ();
using_history ();
temp = previous_history ();
if (temp == 0 || STREQ (temp->line, line) == 0)
should_add = 1;
if (!temp || (STREQ (temp->line, line) == 0))
bash_add_history (line);
using_history ();
}
using_history ();
break;
}
if (should_add && history_should_ignore (line) == 0)
bash_add_history (line);
}
/* Add a line to the history list.
@ -318,18 +465,16 @@ static void
bash_add_history (line)
char *line;
{
int add_it = 1;
int add_it, offset, curlen;
HIST_ENTRY *current, *old;
char *chars_to_add, *new_line;
add_it = 1;
if (command_oriented_history && current_command_line_count > 1)
{
register int offset;
register HIST_ENTRY *current, *old;
char *chars_to_add, *new_line;
chars_to_add = history_delimiting_chars ();
chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
using_history ();
current = previous_history ();
if (current)
@ -337,11 +482,9 @@ bash_add_history (line)
/* If the previous line ended with an escaped newline (escaped
with backslash, but otherwise unquoted), then remove the quoted
newline, since that is what happens when the line is parsed. */
int curlen;
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 - 1] = '\0';
@ -349,22 +492,18 @@ bash_add_history (line)
chars_to_add = "";
}
offset = where_history ();
new_line = (char *) xmalloc (1
+ curlen
+ strlen (line)
+ strlen (chars_to_add));
sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
offset = where_history ();
old = replace_history_entry (offset, new_line, current->data);
free (new_line);
if (old)
{
/* Note that the old data is not freed, since it was simply
copied to the new history entry. */
if (old->line)
free (old->line);
FREE (old->line);
free (old);
}
add_it = 0;
@ -383,8 +522,144 @@ int
history_number ()
{
using_history ();
if (get_string_value ("HISTSIZE"))
return (history_base + where_history ());
else
return (1); /* default to command number 1 */
return (get_string_value ("HISTSIZE") ? history_base + where_history () : 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 */

View file

@ -18,8 +18,8 @@
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (__BASHHIST_H__)
#define __BASHHIST_H__
#if !defined (_BASHHIST_H_)
#define _BASHHIST_H_
extern int remember_on_history;
extern int history_lines_this_session;
@ -32,11 +32,20 @@ extern int command_oriented_history;
extern int history_expansion_inhibited;
# 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 save_history ();
extern int maybe_append_history ();
extern int maybe_save_shell_history ();
extern char *pre_process_line ();
extern int history_number ();
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
View 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
View 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_ */

File diff suppressed because it is too large Load diff

33
bashline.h Normal file
View 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
View 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 */

View file

@ -18,8 +18,8 @@
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (__BASHTYPES_H)
# define __BASHTYPES_H
#if !defined (_BASHTYPES_H_)
# define _BASHTYPES_H_
#if defined (CRAY)
# define word __word
@ -31,4 +31,4 @@
# undef word
#endif
#endif /* __BASHTYPES_H */
#endif /* _BASHTYPES_H_ */

98
bashwait.h Normal file
View 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 */

View file

@ -22,8 +22,15 @@
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 (BRACE_EXPANSION) && defined (READLINE)
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
@ -71,7 +78,7 @@ really_munge_braces (array, real_start, real_end, gcd_zero)
return (savestring (array[0]));
}
result = (char *) xmalloc (result_size = 1);
result = xmalloc (result_size = 1);
*result = '\0';
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
top level, and there isn't a consistent prefix. */
result_size += 1;
result = (char *) xrealloc (result, result_size);
result = xrealloc (result, result_size);
strcpy (result, "{");
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,
insert the prefix and an opening brace. */
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);
strcat (result, "{");
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 = (char *) xrealloc (result, result_size);
result = xrealloc (result, result_size);
strcat (result, subterm);
strcat (result, ",");
free (subterm);
@ -164,3 +171,4 @@ bash_brace_completion ()
rl_attempted_completion_function = orig_attempt_func;
rl_completion_entry_function = orig_entry_func;
}
#endif /* BRACE_EXPANSION && READLINE */

View file

@ -18,12 +18,15 @@
along with Bash; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Stuff in curly braces gets expanded after variable and command
substitution, but before filename globbing.
/* Stuff in curly braces gets expanded before all other shell expansions. */
(Actually, this should be true for the sake of efficiency, but it
isn't because of quoting hacks. Once I rebuild quoting it will be
true. */
#include "config.h"
#if defined (BRACE_EXPANSION)
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STRING_H)
# include <string.h>
@ -32,7 +35,7 @@
#endif /* !HAVE_STRING_H */
#if defined (SHELL)
#include "shell.h"
# include "shell.h"
#endif /* SHELL */
#include "general.h"
@ -61,7 +64,7 @@ brace_expand (text)
register int start;
char *preamble, *postamble, *amble;
char **tack, **result;
int i, c;
int i, j, c;
/* Find the text of the preamble. */
i = 0;
@ -74,7 +77,7 @@ brace_expand (text)
result = (char **)xmalloc (2 * sizeof (char *));
result[0] = preamble;
result[1] = (char *)NULL;
/* Special case. If we never found an exciting character, then
the preamble is all of the text, so just return that. */
if (c != '{')
@ -85,11 +88,9 @@ brace_expand (text)
c = brace_gobbler (text, &i, '}');
/* What if there isn't a matching close brace? */
if (!c)
if (c == 0)
{
#if defined (NOTDEF)
register int j;
/* Well, if we found an unquoted BRACE_ARG_SEPARATOR between START
and I, then this should be an error. Otherwise, it isn't. */
for (j = start; j < i; j++)
@ -103,7 +104,7 @@ brace_expand (text)
if (text[j] == brace_arg_separator)
{
free_array (result);
report_error ("Missing `}'");
report_error ("missing `}'");
throw_to_top_level ();
}
}
@ -120,28 +121,24 @@ brace_expand (text)
#if defined (SHELL)
/* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then
just return without doing any expansion. */
{
register int j;
for (j = 0; amble[j]; j++)
{
if (amble[j] == '\\')
{
j++;
continue;
}
if (amble[j] == brace_arg_separator)
break;
}
for (j = 0; amble[j]; j++)
{
if (amble[j] == '\\')
{
j++;
continue;
}
if (amble[j] == brace_arg_separator)
break;
}
if (!amble[j])
{
free (amble);
free (preamble);
result[0] = savestring (text);
return (result);
}
}
if (!amble[j])
{
free (amble);
free (preamble);
result[0] = savestring (text);
return (result);
}
#endif /* SHELL */
postamble = &text[i + 1];
@ -244,12 +241,12 @@ brace_gobbler (text, indx, satisfy)
quoted = c;
continue;
}
if (c == satisfy && !level && !quoted)
if (c == satisfy && level == 0 && quoted == 0)
{
/* We ignore an open brace surrounded by whitespace, and also
an open brace followed immediately by a close brace, that
was preceded with whitespace. */
an open brace followed immediately by a close brace preceded
by whitespace. */
if (c == '{' &&
((!i || brace_whitespace (text[i - 1])) &&
(brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
@ -257,10 +254,8 @@ brace_gobbler (text, indx, satisfy)
#if defined (SHELL)
/* If this is being compiled as part of bash, ignore the `{'
in a `${}' construct */
if ((c != '{') || !i || (text[i - 1] != '$'))
#else /* !SHELL */
if ((c != '{') || !i)
#endif /* !SHELL */
if ((c != '{') || i == 0 || (text[i - 1] != '$'))
#endif /* SHELL */
break;
}
@ -286,10 +281,10 @@ array_concat (arr1, arr2)
register int i, j, len, len1, len2;
register char **result;
if (!arr1)
if (arr1 == 0)
return (copy_array (arr2));
if (!arr2)
if (arr2 == 0)
return (copy_array (arr1));
len1 = array_len (arr1);
@ -369,3 +364,4 @@ main ()
*/
#endif /* TEST */
#endif /* BRACE_EXPANSION */

View file

@ -19,6 +19,11 @@
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "config.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "command.h"
#include "general.h"
@ -28,8 +33,10 @@
/* Flags describing various things about a builtin. */
#define BUILTIN_ENABLED 0x1 /* This builtin is enabled. */
#define STATIC_BUILTIN 0x2 /* This builtin is not dynamically loaded. */
#define SPECIAL_BUILTIN 0x4 /* This is a Posix `special' builtin. */
#define BUILTIN_DELETED 0x2 /* This has been deleted with enable -d. */
#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. */
struct builtin {
@ -38,8 +45,11 @@ struct builtin {
int flags; /* One of the #defines above. */
char **long_doc; /* NULL terminated array of strings. */
char *short_doc; /* Short version of documenation. */
char *handle; /* for future use */
};
/* Found in builtins.c, created by builtins/mkbuiltins. */
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;

View file

@ -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
View 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

View file

@ -23,85 +23,108 @@ $BUILTIN alias
$FUNCTION alias_builtin
$DEPENDS_ON ALIAS
$PRODUCES alias.c
$SHORT_DOC alias [ name[=value] ... ]
`alias' with no arguments prints the list of aliases in the form
NAME=VALUE on standard output. An alias is defined for each NAME
whose VALUE is given. A trailing space in VALUE causes the next
word to be checked for alias substitution. Alias returns true
unless a NAME is given for which no alias has been defined.
$SHORT_DOC alias [-p] [name[=value] ... ]
`alias' with no arguments or with the -p option prints the list
of aliases in the form alias NAME=VALUE on standard output.
Otherwise, an alias is defined for each NAME whose VALUE is given.
A trailing space in VALUE causes the next word to be checked for
alias substitution when the alias is expanded. Alias returns
true unless a NAME is given for which no alias has been defined.
$END
#include "../config.h"
#include <config.h>
#if defined (ALIAS)
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
# include <stdio.h>
# include "../shell.h"
# include "../alias.h"
# include "common.h"
# include "bashgetopt.h"
extern int interactive;
static void print_alias ();
/* Hack the alias command in a Korn shell way. */
int
alias_builtin (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;
ASSOC **alias_list;
switch (offset)
{
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);
alias_list = all_aliases ();
if (!alias_list)
if (alias_list == 0)
return (EXECUTION_FAILURE);
for (i = 0; alias_list[i]; i++)
print_alias (alias_list[i]);
for (offset = 0; alias_list[offset]; offset++)
print_alias (alias_list[offset]);
free (alias_list); /* XXX - Do not free the strings. */
if (list == 0)
return (EXECUTION_SUCCESS);
}
else
any_failed = 0;
while (list)
{
while (list)
name = list->word->word;
for (offset = 0; name[offset] && name[offset] != '='; offset++)
;
if (offset && name[offset] == '=')
{
register char *value, *name = list->word->word;
register int offset;
name[offset] = '\0';
value = name + offset + 1;
for (offset = 0; name[offset] && name[offset] != '='; offset++)
;
if (offset && name[offset] == '=')
{
name[offset] = '\0';
value = name + offset + 1;
add_alias (name, value);
}
add_alias (name, value);
}
else
{
t = find_alias (name);
if (t)
print_alias (t);
else
{
ASSOC *t = find_alias (name);
if (t)
print_alias (t);
else
{
if (interactive)
builtin_error ("`%s' not found", name);
any_failed++;
}
if (interactive)
builtin_error ("`%s' not found", name);
any_failed++;
}
list = list->next;
}
list = list->next;
}
if (any_failed)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
#endif /* ALIAS */
@ -115,33 +138,37 @@ $END
#if defined (ALIAS)
/* Remove aliases named in LIST from the aliases database. */
int
unalias_builtin (list)
register WORD_LIST *list;
{
register ASSOC *alias;
int any_failed = 0;
register alias_t *alias;
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;
if (ISOPTION (word, 'a'))
switch (opt)
{
delete_all_aliases ();
list = list->next;
}
else if (ISOPTION (word, '-'))
{
list = list->next;
case 'a':
aflag = 1;
break;
}
else
{
bad_option (word);
return (EXECUTION_FAILURE);
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (aflag)
{
delete_all_aliases ();
return (EXECUTION_SUCCESS);
}
aflag = 0;
while (list)
{
alias = find_alias (list->word->word);
@ -151,27 +178,25 @@ unalias_builtin (list)
else
{
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;
}
if (any_failed)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
return (aflag ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
/* Output ALIAS in such a way as to allow it to be read back in. */
static void
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);
free (value);

View file

@ -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
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <errno.h>
#include "shell.h"
#include <config.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))
@ -41,14 +48,21 @@ char *opts;
{
register int c;
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;
loptend = (WORD_LIST *)NULL; /* No non-option arguments */
return -1;
}
if (list != lhead || !lhead) {
if (list != lhead || lhead == 0) {
/* Hmmm.... called with a different word list. Reset. */
sp = 1;
lcurrent = lhead = list;
@ -56,7 +70,7 @@ char *opts;
}
if (sp == 1) {
if (!lcurrent ||
if (lcurrent == 0 ||
(lcurrent->word->word[0] != '-' || lcurrent->word->word[1] == '\0')) {
lhead = (WORD_LIST *)NULL;
loptend = lcurrent;
@ -84,23 +98,46 @@ char *opts;
return('?');
}
if (*++cp == ':') {
/* Option requires an argument. */
if (*++cp == ':' || *cp == ';') {
/* `:': Option requires an argument. */
/* `;': option argument may be missing */
/* We allow -l2 as equivalent to -l 2 */
if (lcurrent->word->word[sp+1] != '\0') {
list_optarg = &(lcurrent->word->word[sp+1]);
if (lcurrent->word->word[sp+1]) {
list_optarg = lcurrent->word->word + sp + 1;
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);
sp = 1;
list_optarg = (char *)NULL;
return('?');
} else {
lcurrent = lcurrent->next;
list_optarg = lcurrent->word->word;
lcurrent = lcurrent->next;
}
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 {
if (lcurrent->next && legal_number(lcurrent->next->word->word, (long *)0)) {
lcurrent = lcurrent->next;
list_optarg = lcurrent->word->word;
lcurrent = lcurrent->next;
} else
list_optarg = (char *)NULL;
}
} else {
/* No argument, just return the option. */
if (lcurrent->word->word[++sp] == '\0') {

View file

@ -21,10 +21,12 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES bind.c
#include <config.h>
$BUILTIN bind
$DEPENDS_ON READLINE
$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
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'.
@ -34,49 +36,75 @@ Arguments we accept:
emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,
vi-command, and vi-insert.
-l List names of functions.
-v List function names and bindings.
-d Dump functions and bindings such that they
can be read back in.
-P List function names and bindings.
-p List functions and bindings in a form that can be
reused as input.
-r keyseq Remove the binding for KEYSEQ.
-f filename Read key bindings from FILENAME.
-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
#include <stdio.h>
#include "../shell.h"
#if defined (READLINE)
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
#include <readline/readline.h>
#include <readline/history.h>
#include "../shell.h"
#include "../bashline.h"
#include "bashgetopt.h"
#include "common.h"
static int query_bindings ();
extern int bash_readline_initialized;
extern int no_line_editing;
#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
bind_builtin (list)
WORD_LIST *list;
{
int return_code = EXECUTION_SUCCESS;
int return_code;
FILE *old_rl_outstream;
Keymap kmap, saved_keymap;
int lflag, dflag, fflag, vflag, qflag, mflag, opt;
char *initfile, *map_name, *fun_name;
int flags, opt;
char *initfile, *map_name, *fun_name, *remove_seq;
if (no_line_editing)
return (EXECUTION_FAILURE);
kmap = saved_keymap = (Keymap) NULL;
lflag = dflag = vflag = fflag = qflag = mflag = 0;
initfile = map_name = fun_name = (char *)NULL;
flags = 0;
initfile = map_name = fun_name = remove_seq = (char *)NULL;
return_code = EXECUTION_SUCCESS;
if (!bash_readline_initialized)
initialize_readline ();
@ -88,39 +116,49 @@ bind_builtin (list)
rl_outstream = stdout;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "lvdf:q:m:")) != EOF)
while ((opt = internal_getopt (list, "lvpVPsSf:q:m:r:")) != EOF)
{
switch (opt)
{
case 'l':
lflag++;
flags |= LFLAG;
break;
case 'v':
vflag++;
flags |= VFLAG;
break;
case 'd':
dflag++;
case 'p':
flags |= PFLAG;
break;
case 'f':
fflag++;
flags |= FFLAG;
initfile = list_optarg;
break;
case 'm':
mflag++;
flags |= MFLAG;
map_name = list_optarg;
break;
case 'q':
qflag++;
flags |= QFLAG;
fun_name = list_optarg;
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:
builtin_error (USAGE);
builtin_usage ();
BIND_RETURN (EX_USAGE);
}
}
@ -130,12 +168,12 @@ bind_builtin (list)
/* First, see if we need to install a special keymap for this
command. Then start on the arguments. */
if (mflag && map_name)
if ((flags & MFLAG) && map_name)
{
kmap = rl_get_keymap_by_name (map_name);
if (!kmap)
{
builtin_error ("`%s': illegal keymap name", map_name);
builtin_error ("`%s': invalid keymap name", map_name);
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
to use some of these options together. */
/* Now hack the option arguments */
if (lflag)
rl_list_funmap_names (0);
if (flags & LFLAG)
rl_list_funmap_names ();
if (vflag)
rl_function_dumper (0);
if (dflag)
if (flags & PFLAG)
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)
{
@ -167,9 +217,18 @@ bind_builtin (list)
}
}
if (qflag && fun_name)
if ((flags & QFLAG) && 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. */
while (list)
{

View file

@ -27,8 +27,14 @@ $SHORT_DOC break [n]
Exit from within a FOR, WHILE or UNTIL loop. If N is specified,
break N levels.
$END
#include <config.h>
#if defined (HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include "../shell.h"
#include "common.h"
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
as the first argument. */
int
break_builtin (list)
WORD_LIST *list;
{
@ -75,6 +82,7 @@ $END
/* Set up to continue x levels, where x defaults to 1, but can be specified
as the first argument. */
int
continue_builtin (list)
WORD_LIST *list;
{
@ -103,7 +111,7 @@ check_loop_level ()
{
#if defined (BREAK_COMPLAINS)
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 */
return (loop_level);

View file

@ -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
builtin within the function itself.
$END
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../shell.h"
#include "common.h"
extern char *this_command_name;
/* Run the command mentioned in list directly, without going through the
normal alias/function/builtin/filename lookup process. */
int
builtin_builtin (list)
WORD_LIST *list;
{

File diff suppressed because it is too large Load diff

View file

@ -28,10 +28,32 @@ $SHORT_DOC :
No effect; the command does nothing. A zero exit code is returned.
$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
colon_builtin (ignore)
char *ignore;
{
return (0);
}
/* Return an unsuccessful result. */
int
false_builtin (ignore)
char *ignore;
{
return (1);
}

View file

@ -23,7 +23,7 @@ $PRODUCES command.c
$BUILTIN command
$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
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
@ -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.
$END
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../shell.h"
#include "../execute_cmd.h"
#include "../flags.h"
#include "bashgetopt.h"
#include "common.h"
extern int subshell_environment;
@ -52,9 +57,11 @@ int
command_builtin (list)
WORD_LIST *list;
{
int result, verbose = 0, use_standard_path = 0, opt;
char *old_path;
int result, verbose, use_standard_path, opt;
char *old_path, *standard_path;
COMMAND *command;
verbose = use_standard_path = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "pvV")) != -1)
{
@ -69,73 +76,80 @@ command_builtin (list)
case 'v':
verbose = 4;
break;
default:
report_bad_option ();
builtin_error ("usage: command [-pvV] [command [arg...]]");
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (!list)
if (list == 0)
return (EXECUTION_SUCCESS);
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);
if (!found)
if (found == 0)
builtin_error ("%s: not found", list->word->word);
any_found += found;
list = list->next;
}
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");
/* 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. */
{
COMMAND *command;
if (use_standard_path)
{
old_path = get_string_value ("PATH");
if (old_path)
old_path = savestring (old_path);
else
{
old_path = xmalloc (1);
old_path[0] = '\0';
}
add_unwind_protect ((Function *)restore_path, old_path);
if (use_standard_path)
{
char *standard_path;
standard_path = get_standard_path ();
bind_variable ("PATH", standard_path ? standard_path : "");
FREE (standard_path);
}
old_path = get_string_value ("PATH");
if (old_path)
old_path = savestring (old_path);
else
old_path = savestring ("");
add_unwind_protect ((Function *)restore_path, old_path);
standard_path = get_standard_path ();
bind_variable ("PATH", standard_path);
free (standard_path);
}
command = make_bare_simple_command ();
command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
command->value.Simple->redirects = (REDIRECT *)NULL;
command->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
command->value.Simple->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
/* If we're in a subshell, see if we can get away without forking
again, since we've already forked to run this builtin. */
if (subshell_environment)
{
command->flags |= CMD_NO_FORK;
command->value.Simple->flags |= CMD_NO_FORK;
}
add_unwind_protect ((char *)dispose_command, command);
result = execute_command (command);
}
command = make_bare_simple_command ();
command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
command->value.Simple->redirects = (REDIRECT *)NULL;
command->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
again, since we've already forked to run this builtin. */
if (subshell_environment)
{
command->flags |= CMD_NO_FORK;
command->value.Simple->flags |= CMD_NO_FORK;
}
#endif
add_unwind_protect ((char *)dispose_command, command);
result = execute_command (command);
run_unwind_frame ("command_builtin");
@ -158,7 +172,7 @@ restore_path (var)
static char *
get_standard_path ()
{
#if defined (_CS_PATH) && !defined (hpux_7) && !defined (NetBSD)
#if defined (_CS_PATH) && defined (HAVE_CONFSTR)
char *p;
size_t len;
@ -167,11 +181,11 @@ get_standard_path ()
*p = '\0';
confstr (_CS_PATH, p, len);
return (p);
#else /* !_CSPATH || hpux_7 || NetBSD */
#else /* !_CSPATH || !HAVE_CONFSTR */
# if defined (CS_PATH)
return (savestring (CS_PATH));
# else
return (savestring (STANDARD_UTILS_PATH));
# endif /* !CS_PATH */
#endif /* !_CS_PATH || hpux_7 */
#endif /* !_CS_PATH || !HAVE_CONFSTR */
}

File diff suppressed because it is too large Load diff

View file

@ -21,23 +21,23 @@
#if !defined (__COMMON_H)
# define __COMMON_H
#include "../stdc.h"
#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 char **make_builtin_argv ();
extern int get_numeric_arg ();
extern void remember_args ();
extern void no_args ();
extern int no_options ();
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_dollar_vars (), pop_dollar_vars ();
extern void dispose_saved_dollar_vars ();
@ -53,17 +53,55 @@ extern void set_working_directory ();
extern int get_job_spec ();
#endif
extern int parse_and_execute ();
extern void parse_and_execute_cleanup ();
extern void initialize_shell_builtins ();
extern int display_signal_list ();
/* It's OK to declare a function as returning a Function * without
providing a definition of what a `Function' is. */
extern struct builtin *builtin_address_internal ();
extern Function *find_shell_builtin ();
extern Function *builtin_address ();
extern Function *find_special_builtin ();
extern void initialize_shell_builtins ();
extern char *single_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 */

View file

@ -23,39 +23,50 @@ $PRODUCES declare.c
$BUILTIN declare
$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
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:
-f to select from among function names only,
-r to make NAMEs readonly,
-x to make NAMEs export,
-i to make NAMEs have the `integer' attribute set.
-a to make NAMEs arrays (if supported)
-f to select from among function names only
-F to display function names without definitions
-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
`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
used in a function, makes NAMEs local, as with the `local' command.
$END
$BUILTIN typeset
$FUNCTION declare_builtin
$SHORT_DOC typeset [-[frxi]] name[=value] ...
$SHORT_DOC typeset [-afFrxi] [-p] name[=value] ...
Obsolete. See `declare'.
$END
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#include "../bashansi.h"
#include "../shell.h"
#include "common.h"
#include "builtext.h"
extern int variable_context, array_needs_making;
@ -84,7 +95,7 @@ local_builtin (list)
return (declare_internal (list, 1));
else
{
builtin_error ("Can only be used in a function");
builtin_error ("can only be used in a function");
return (EXECUTION_FAILURE);
}
}
@ -95,14 +106,14 @@ declare_internal (list, local_var)
register WORD_LIST *list;
int local_var;
{
int flags_on = 0, flags_off = 0;
int any_failed = 0;
int flags_on, flags_off, *flags, any_failed, assign_error, pflag, nodefs;
char *t;
SHELL_VAR *var;
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0;
while (list)
{
register char *t = list->word->word;
int *flags;
t = list->word->word;
if (t[0] == '-' && t[1] == '-' && t[2] == '\0')
{
list = list->next;
@ -112,16 +123,18 @@ declare_internal (list, local_var)
if (*t != '+' && *t != '-')
break;
if (*t == '+')
flags = &flags_off;
else
flags = &flags_on;
t++;
flags = (*t++ == '+') ? &flags_off : &flags_on;
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++;
else if (*t == 'x')
*flags |= att_exported, t++, array_needs_making = 1;
@ -129,9 +142,14 @@ declare_internal (list, local_var)
*flags |= att_readonly, t++;
else if (*t == 'i')
*flags |= att_integer, t++;
#if defined (ARRAY_VARS)
else if (*t == 'a')
*flags |= att_array, t++;
#endif
else
{
builtin_error ("unknown option: `-%c'", *t);
builtin_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
some variables. */
if (!list)
if (list == 0) /* declare -[afFirx] */
{
/* Show local variables defined at this context level if this is
the `local' builtin. */
@ -162,25 +180,45 @@ declare_internal (list, local_var)
}
else
{
if (!flags_on)
if (flags_on == 0)
set_builtin ((WORD_LIST *)NULL);
else
set_or_show_attributes ((WORD_LIST *)NULL, flags_on);
set_or_show_attributes ((WORD_LIST *)NULL, flags_on, nodefs);
}
fflush (stdout);
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
/* There are arguments left, so we are making variables. */
while (list)
while (list) /* declare [-afFirx] name [name ...] */
{
char *value, *name = savestring (list->word->word);
int offset = assignment (name);
char *value, *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';
value = name + offset + 1;
@ -188,10 +226,21 @@ declare_internal (list, local_var)
else
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)
{
builtin_error ("%s: not a legal variable name", name);
any_failed++;
builtin_error ("`%s': not a valid identifier", name);
assign_error++;
NEXT_VARIABLE ();
}
@ -200,7 +249,14 @@ declare_internal (list, local_var)
not global ones. */
if (variable_context)
make_local_variable (name);
{
#if defined (ARRAY_VARS)
if ((flags_on & att_array) || making_array_special)
make_local_array_variable (name);
else
#endif
make_local_variable (name);
}
/* 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'. */
@ -210,36 +266,35 @@ declare_internal (list, local_var)
if (flags_on & att_function)
{
if (offset)
if (offset) /* declare -f [-rix] foo=bar */
{
builtin_error ("Can't use `-f' to make functions");
return (EXECUTION_FAILURE);
}
else
else /* declare -f [-rx] name [name...] */
{
SHELL_VAR *find_function (), *funvar;
var = find_function (name);
funvar = find_function (name);
if (funvar)
if (var)
{
if (readonly_p (funvar) && (flags_off & att_readonly))
if (readonly_p (var) && (flags_off & att_readonly))
{
builtin_error ("%s: readonly function", name);
any_failed++;
NEXT_VARIABLE ();
}
/* declare -[Ff] name [name...] */
if (flags_on == att_function && flags_off == 0)
{
char *result = named_function_string
(name, (COMMAND *)function_cell (funvar), 1);
printf ("%s\n", result);
t = nodefs ? var->name
: named_function_string (name, function_cell (var), 1);
printf ("%s\n", t);
}
else
else /* declare -[fF] -[rx] name [name...] */
{
funvar->attributes |= flags_on;
funvar->attributes &= ~flags_off;
var->attributes |= flags_on;
var->attributes &= ~flags_off;
}
}
else
@ -247,15 +302,21 @@ declare_internal (list, local_var)
NEXT_VARIABLE ();
}
}
else
else /* declare -[airx] name [name...] */
{
SHELL_VAR *var;
var = find_variable (name);
if (!var)
var = bind_variable (name, "");
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, "");
}
/* Cannot use declare +r to turn off readonly attribute. */
if (readonly_p (var) && (flags_off & att_readonly))
{
builtin_error ("%s: readonly variable", name);
@ -263,22 +324,55 @@ declare_internal (list, local_var)
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_off;
#if defined (ARRAY_VARS)
if (offset && assigning_array_special)
assign_array_var_from_string (var, value);
else
#endif
if (offset)
{
free (var->value);
if (integer_p (var))
{
long val, evalexp ();
char *itos ();
val = evalexp (value);
var->value = itos ((int)val);
}
else
var->value = savestring (value);
t = make_variable_value (var, value);
FREE (var->value);
var->value = t;
}
}
@ -286,5 +380,8 @@ declare_internal (list, local_var)
NEXT_VARIABLE ();
}
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
return (assign_error ? EX_BADASSIGN
: ((any_failed == 0) ? EXECUTION_SUCCESS
: EXECUTION_FAILURE));
}

View file

@ -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.
$PRODUCES echo.c
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include "../shell.h"
@ -33,6 +39,7 @@ following backslash-escaped characters is turned on:
\a alert (bell)
\b backspace
\c suppress trailing newline
\E escape character
\f form feed
\n new line
\r carriage return
@ -60,109 +67,91 @@ $END
/* 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
echo syntax from Version 9 unix systems. */
echo syntax from Version 9 Unix systems. */
int
echo_builtin (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)
/* System V machines already have a /bin/sh with a v9 behaviour. We
give Bash the identical behaviour for these machines so that the
existing system shells won't barf. */
do_v9 = 1;
#else
do_v9 = 0;
#endif /* DEFAULT_ECHO_TO_USG */
while (list && list->word->word[0] == '-')
{
register char *temp;
register int i;
display_return = 1;
for (; list && (temp = list->word->word) && *temp == '-'; list = list->next)
{
/* If it appears that we are handling options, then make sure that
all of the options specified are actually valid. Otherwise, the
string should just be echoed. */
temp = &(list->word->word[1]);
temp++;
for (i = 0; temp[i]; i++)
{
if (strchr (VALID_ECHO_OPTIONS, temp[i]) == 0)
goto just_echo;
break;
}
if (!*temp)
goto just_echo;
/* echo - and echo -<nonopt> both mean to just echo the arguments. */
if (*temp == 0 || temp[i])
break;
/* All of the options in TEMP are valid options to ECHO.
Handle them. */
while (*temp)
while (i = *temp++)
{
if (*temp == 'n')
display_return = 0;
switch (i)
{
case 'n':
display_return = 0;
break;
#if defined (V9_ECHO)
else if (*temp == 'e')
do_v9 = 1;
else if (*temp == 'E')
do_v9 = 0;
case 'e':
do_v9 = 1;
break;
case 'E':
do_v9 = 0;
break;
#endif /* V9_ECHO */
else
goto just_echo;
temp++;
default:
goto just_echo; /* XXX */
}
}
list = list->next;
}
just_echo:
if (list)
while (list)
{
#if defined (V9_ECHO)
if (do_v9)
i = 0;
temp = do_v9 ? ansicstr (list->word->word, STRLEN (list->word->word), &i)
: list->word->word;
if (temp)
{
while (list)
{
register char *s = list->word->word;
register int c;
while (c = *s++)
{
if (c == '\\' && *s)
{
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);
}
list = list->next;
if (list)
putchar(' ');
}
printf ("%s", temp);
fflush (stdout); /* Fix for bug in SunOS 5.5 printf(3) */
}
else
#endif /* V9_ECHO */
print_word_list (list, " ");
if (do_v9 && temp)
free (temp);
list = list->next;
if (i)
{
display_return = 0;
break;
}
if (list)
putchar(' ');
}
if (display_return)
printf ("\n");
putchar ('\n');
fflush (stdout);
return (EXECUTION_SUCCESS);
}

View file

@ -23,20 +23,54 @@ $PRODUCES enable.c
$BUILTIN enable
$FUNCTION enable_builtin
$SHORT_DOC enable [-n] [name ...]
$SHORT_DOC enable [-pnds] [-a] [-f filename] [name ...]
Enable and disable builtin shell commands. This allows
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
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
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include "../bashansi.h"
#include "../shell.h"
#include "../builtins.h"
#include "../flags.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 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 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,
then print out a list of shell commands showing which are enabled and
which are disabled. */
int
enable_builtin (list)
WORD_LIST *list;
{
int result = 0, any_failed = 0;
int disable_p, all_p;
int result, flags;
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;
list = list->next;
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;
else
switch (opt)
{
bad_option (arg);
return (EXECUTION_FAILURE);
case 'a':
flags |= AFLAG;
break;
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);
}
}
if (!list)
{
int filter;
list = loptend;
if (all_p)
filter = ENABLED | DISABLED;
else if (disable_p)
filter = DISABLED;
else
filter = ENABLED;
#if defined (RESTRICTED_SHELL)
/* Restricted shells cannot load new builtins. */
if (restricted && (flags & (FFLAG|DFLAG)))
{
builtin_error ("restricted");
return (EXECUTION_FAILURE);
}
#endif
if (list == 0 || (flags & PFLAG))
{
filter = (flags & AFLAG) ? (ENABLED | DISABLED)
: (flags & NFLAG) ? DISABLED : ENABLED;
if (flags & SFLAG)
filter |= SPECIAL;
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
{
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);
any_failed++;
result = EXECUTION_FAILURE;
}
list = list->next;
}
}
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
return (result);
}
/* List some builtins.
@ -111,19 +201,18 @@ list_some_builtins (filter)
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;
if ((filter & ENABLED) &&
(shell_builtins[i].flags & BUILTIN_ENABLED))
{
printf ("enable %s\n", shell_builtins[i].name);
}
if ((filter & SPECIAL) &&
(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);
else if ((filter & DISABLED) &&
((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);
}
}
@ -134,23 +223,202 @@ enable_shell_command (name, disable_p)
char *name;
int disable_p;
{
register int i;
int found = 0;
struct builtin *b;
for (i = 0; i < num_shell_builtins; i++)
{
if (!shell_builtins[i].function)
continue;
b = builtin_address_internal (name, 1);
if (b == 0)
return (EXECUTION_FAILURE);
if (STREQ (name, shell_builtins[i].name))
{
found++;
if (disable_p)
b->flags &= ~BUILTIN_ENABLED;
else
b->flags |= BUILTIN_ENABLED;
if (disable_p)
shell_builtins[i].flags &= ~BUILTIN_ENABLED;
else
shell_builtins[i].flags |= BUILTIN_ENABLED;
}
}
return (found);
return (EXECUTION_SUCCESS);
}
#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

View file

@ -27,19 +27,24 @@ $SHORT_DOC eval [arg ...]
Read ARGs as input to the shell and execute the resulting command(s).
$END
#include <config.h>
#if defined (HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include "../shell.h"
#include "bashgetopt.h"
extern int parse_and_execute ();
/* Parse the string that these words make, and execute the command found. */
int
eval_builtin (list)
WORD_LIST *list;
{
int result;
if (no_options (list))
return (EX_USAGE);
/* Note that parse_and_execute () frees the string it is passed. */
if (list)
result = parse_and_execute (string_list (list), "eval", -1);
else
result = EXECUTION_SUCCESS;
return (result);
return (list ? parse_and_execute (string_list (list), "eval", -1) : EXECUTION_SUCCESS);
}

211
builtins/evalfile.c Normal file
View 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
View 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);
}

View file

@ -23,141 +23,190 @@ $PRODUCES exec.c
$BUILTIN exec
$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.
If FILE is not specified, the redirections take effect in this
shell. If the first argument is `-', then place a dash in the
zeroth arg passed to FILE. If the file cannot be exec'ed and
the shell is not interactive, then the shell exits, unless the
shell variable "no_exit_on_failed_exec" exists.
shell. If the first argument is `-l', then place a dash in the
zeroth arg passed to FILE, as login does. If the `-c' option
is supplied, FILE is executed with a null environment. The `-a'
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
#include "../shell.h"
#include <config.h>
#include <sys/types.h>
#include "../posixstat.h"
#include <signal.h>
#include <errno.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../shell.h"
#include "../execute_cmd.h"
#include "common.h"
#if defined (JOB_CONTROL)
# include "../jobs.h"
#endif
#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! */
#if !defined (errno)
extern int errno;
#endif /* !errno */
extern int interactive, subshell_environment;
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
exec_builtin (list)
WORD_LIST *list;
{
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. */
dispose_redirects (redirection_undo_list);
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);
#if defined (RESTRICTED_SHELL)
if (restricted)
{
builtin_error ("restricted");
return (EXECUTION_FAILURE);
}
if (restricted)
{
builtin_error ("restricted");
return (EXECUTION_FAILURE);
}
#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
the search path. */
if (absolute_program (args[0]))
command = args[0];
else
command = find_user_command (args[0]);
if (!command)
{
builtin_error ("%s: not found", args[0]);
exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
goto failed_exec;
}
/* A command with a slash anywhere in its name is not looked up in $PATH. */
command = absolute_program (args[0]) ? args[0] : search_for_command (args[0]);
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 (dash_name)
{
char *new_name = xmalloc (2 + strlen (args[0]));
new_name[0] = '-';
strcpy (new_name + 1, args[0]);
free (args[0]);
args[0] = new_name;
}
if (command == 0)
{
builtin_error ("%s: not found", args[0]);
exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
goto failed_exec;
}
/* 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
exported environment to include the new value. */
adjust_shell_level (-1);
command = full_pathname (command);
if (argv0)
{
free (args[0]);
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,
preserving the appearance. After we do that, we need to change the
exported environment to include the new value. */
if (cleanenv == 0)
adjust_shell_level (-1);
if (cleanenv)
env = (char **)NULL;
else
{
maybe_make_export_env ();
env = export_env;
}
#if defined (HISTORY)
maybe_save_shell_history ();
maybe_save_shell_history ();
#endif /* HISTORY */
restore_original_signals ();
restore_original_signals ();
#if defined (JOB_CONTROL)
if (subshell_environment == 0)
end_job_control ();
if (subshell_environment == 0)
end_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))
{
builtin_error ("%s: cannot execute: %s", command, strerror (errno));
exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
}
else
file_error (command);
failed_exec:
if (command)
free (command);
if (subshell_environment ||
(!interactive && !find_variable ("no_exit_on_failed_exec")))
exit (exit_value);
initialize_traps ();
reinitialize_signals ();
#if defined (JOB_CONTROL)
restart_job_control ();
#endif /* JOB_CONTROL */
return (exit_value);
if (executable_file (command) == 0)
{
builtin_error ("%s: cannot execute: %s", command, strerror (errno));
exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
}
else
file_error (command);
failed_exec:
if (command)
free (command);
if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
exit_shell (exit_value);
initialize_traps ();
reinitialize_signals ();
#if defined (JOB_CONTROL)
restart_job_control ();
#endif /* JOB_CONTROL */
return (exit_value);
}

View file

@ -1,5 +1,5 @@
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.
@ -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.
$END
#include <stdio.h>
#include <config.h>
#include <sys/types.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../shell.h"
#include "../jobs.h"
#include "common.h"
#include "builtext.h" /* for jobs_builtin */
extern int interactive, login_shell;
extern int last_command_exit_value;
static int exit_or_logout ();
static int sourced_logout = 0;
static int sourced_logout;
int
exit_builtin (list)
@ -65,9 +73,9 @@ int
logout_builtin (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);
}
else
@ -87,7 +95,7 @@ exit_or_logout (list)
#if defined (JOB_CONTROL)
int exit_immediate_okay;
exit_immediate_okay = (!interactive ||
exit_immediate_okay = (interactive == 0 ||
last_shell_builtin == exit_builtin ||
last_shell_builtin == logout_builtin ||
last_shell_builtin == jobs_builtin);
@ -97,7 +105,7 @@ exit_or_logout (list)
{
register int 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");
@ -113,17 +121,20 @@ exit_or_logout (list)
/* Get return value if present. This means that you can type
`logout 5' to a shell, and it returns 5. */
if (list)
exit_value = get_numeric_arg (list);
else
exit_value = last_command_exit_value;
exit_value = list ? get_numeric_arg (list) : last_command_exit_value;
/* Run our `~/.bash_logout' file if it exists, and this is a login shell. */
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;
/* Exit the program. */
longjmp (top_level, EXITPROG);
jump_to_top_level (EXITPROG);
/*NOTREACHED*/
}

View file

@ -46,23 +46,32 @@ runs the last command beginning with `cc' and typing `r' re-executes
the last command.
$END
#include <stdio.h>
#include "../bashansi.h"
#include "../shell.h"
#include <config.h>
#if defined (HISTORY)
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "bashtypes.h"
#include "posixstat.h"
#include <sys/file.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include "../bashansi.h"
#include <errno.h>
#include "../shell.h"
#include "../builtins.h"
#include "../flags.h"
#include "../maxpath.h"
#include "../bashhist.h"
#include <readline/history.h>
#include "bashgetopt.h"
#include "common.h"
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
#if !defined (errno)
extern int errno;
#endif /* !errno */
@ -100,8 +109,8 @@ extern int unlink ();
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 int fc_gethnum ();
static char *fc_dosubs (), *fc_gethist (), *fc_readline ();
static int fc_gethnum (), fc_number ();
static void fc_replhist (), fc_addhist ();
/* Data structure describing a list of global replacements to perform. */
@ -111,8 +120,6 @@ typedef struct repl {
char *rep;
} 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. */
#define histline(i) (hlist[(i)]->line)
#define histdata(i) (hlist[(i)]->data)
@ -143,61 +150,51 @@ fc_builtin (list)
int numbering, reverse, listing, execute;
int histbeg, histend, last_hist, retval, first, opt;
FILE *stream;
REPL *rlist = (REPL *) NULL, *rl;
char *ename = NULL, *command, *newcom, *line;
REPL *rlist, *rl;
char *ename, *command, *newcom, *line;
HIST_ENTRY **hlist;
char fn[MAXPATHLEN];
char fn[64];
numbering = 1;
reverse = listing = execute = 0;
ename = (char *)NULL;
/* Parse out the options and set which of the two forms we're in. */
while (list && *list->word->word == '-')
reset_internal_getopt ();
lcurrent = list; /* XXX */
while (fc_number (loptend = lcurrent) == 0 &&
(opt = internal_getopt (list, ":e:lnrs")) != -1)
{
register char *s = &((list->word->word)[1]);
if (!isletter (*s))
break;
while (opt = *s++)
switch (opt)
{
switch (opt)
{
case 'n':
numbering = 0;
break;
case 'n':
numbering = 0;
break;
case 'l':
listing = 1;
break;
case 'l':
listing = 1;
break;
case 'r':
reverse = 1;
break;
case 'r':
reverse = 1;
break;
case 's':
execute = 1;
break;
case 's':
execute = 1;
break;
case 'e':
list = list->next;
if (list == NULL)
{
builtin_error (USAGE);
return (EX_USAGE);
}
ename = list->word->word;
break;
case 'e':
ename = list_optarg;
break;
default:
builtin_error (USAGE);
return (EX_USAGE);
}
default:
builtin_usage ();
return (EX_USAGE);
}
list = list->next;
}
list = loptend;
if (ename && (*ename == '-') && (ename[1] == '\0'))
execute = 1;
@ -205,6 +202,7 @@ fc_builtin (list)
substitutions). */
if (execute)
{
rlist = (REPL *)NULL;
while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL))
{
*sep++ = '\0';
@ -227,16 +225,13 @@ fc_builtin (list)
to get the replacements in the proper order. */
if (rlist && rlist->next)
rlist = (REPL *) reverse_list ((GENERIC_LIST *) rlist);
rlist = (REPL *)reverse_list ((GENERIC_LIST *) rlist);
hlist = history_list ();
/* If we still have something in list, it is a command spec.
Otherwise, we use the most recent command in time. */
if (list)
command = fc_gethist (list->word->word, hlist);
else
command = fc_gethist ((char *) NULL, hlist);
command = fc_gethist (list ? list->word->word : (char *)NULL, hlist);
if (command == NULL)
{
@ -255,8 +250,8 @@ fc_builtin (list)
command = newcom;
}
printf ("%s\n", command);
fc_replhist (command); /* replace `fc -e -' with command */
fprintf (stderr, "%s\n", command);
fc_replhist (command); /* replace `fc -s' with command */
return (parse_and_execute (command, "fc", -1));
}
@ -283,12 +278,7 @@ fc_builtin (list)
if (list)
histend = fc_gethnum (list->word->word, hlist);
else
{
if (listing)
histend = last_hist;
else
histend = histbeg;
}
histend = listing ? last_hist : histbeg;
}
else
{
@ -301,10 +291,8 @@ fc_builtin (list)
histbeg = 0;
}
else
{
/* For editing, it is the last history command. */
histbeg = histend = last_hist;
}
/* For editing, it is the last history command. */
histbeg = histend = last_hist;
}
/* We print error messages for line specifications out of range. */
@ -317,10 +305,10 @@ fc_builtin (list)
if (histend < histbeg)
{
int t = histend;
i = histend;
histend = histbeg;
histbeg = t;
histbeg = i;
reverse = 1;
}
@ -329,40 +317,25 @@ fc_builtin (list)
else
{
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");
if (!stream)
if (stream == 0)
{
builtin_error ("cannot open temp file %s", fn);
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;
if (numbering)
fprintf (stream, "%d", i + history_base);
if (listing)
fprintf (stream, "\t%c", histdata (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));
}
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)
@ -381,7 +354,12 @@ fc_builtin (list)
command = (char *)xmalloc (3 + strlen (FC_EDIT_COMMAND) + strlen (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. */
@ -435,6 +413,21 @@ fc_builtin (list)
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
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. */
@ -572,58 +565,18 @@ fc_dosubs (command, subs)
char *command;
REPL *subs;
{
register char *new = savestring (command);
register char *new, *t;
register REPL *r;
for (r = subs; r; r = r->next)
for (new = savestring (command), r = subs; r; r = r->next)
{
register char *t;
t = fc_replace (r->pat, r->rep, new);
t = strsub (new, r->pat, r->rep, 1);
free (new);
new = t;
}
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,
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
@ -634,10 +587,9 @@ fc_replhist (command)
{
register int i;
HIST_ENTRY **hlist, *histent, *discard;
char *data;
int n;
if (!command || !*command)
if (command == 0 || *command == '\0')
return;
hlist = history_list ();
@ -665,8 +617,7 @@ fc_replhist (command)
discard = remove_history (i);
if (discard)
{
if (discard->line)
free (discard->line);
FREE (discard->line);
free ((char *) discard);
}
maybe_add_history (command); /* Obeys HISTCONTROL setting. */

View file

@ -30,10 +30,18 @@ JOB_SPEC is not present, the shell's notion of the current job is
used.
$END
#include <config.h>
#include <sys/types.h>
#include <signal.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../shell.h"
#include "../jobs.h"
#include "common.h"
#if defined (JOB_CONTROL)
extern char *this_command_name;
@ -45,23 +53,23 @@ int
fg_builtin (list)
WORD_LIST *list;
{
int fg_bit = 1;
register WORD_LIST *t = list;
int fg_bit;
register WORD_LIST *t;
if (!job_control)
if (job_control == 0)
{
builtin_error ("no job control");
return (EXECUTION_FAILURE);
}
if (no_options (list))
return (EX_USAGE);
/* If the last arg on the line is '&', then start this job in the
background. Else, fg the job. */
while (t && t->next)
t = t->next;
if (t && t->word->word[0] == '&' && !t->word->word[1])
fg_bit = 0;
for (t = list; t && t->next; t = t->next)
;
fg_bit = (t && t->word->word[0] == '&' && t->word->word[1] == '\0') == 0;
return (fg_bg (list, fg_bit));
}
@ -82,12 +90,15 @@ int
bg_builtin (list)
WORD_LIST *list;
{
if (!job_control)
if (job_control == 0)
{
builtin_error ("no job control");
return (EXECUTION_FAILURE);
}
if (no_options (list))
return (EX_USAGE);
return (fg_bg (list, 0));
}
@ -98,27 +109,27 @@ fg_bg (list, foreground)
int foreground;
{
sigset_t set, oset;
int job, status = EXECUTION_SUCCESS, old_async_pid;
int job, status, old_async_pid;
BLOCK_CHILD (set, oset);
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)
builtin_error ("No such job %s", list ? list->word->word : "");
builtin_error ("%s: no such job", list ? list->word->word : "current");
goto failure;
}
/* 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);
goto failure;
}
if (!foreground)
if (foreground == 0)
{
old_async_pid = last_asynchronous_pid;
last_asynchronous_pid = jobs[job]->pgrp; /* As per Posix.2 5.4.2 */
@ -134,7 +145,7 @@ fg_bg (list, foreground)
}
else
{
if (!foreground)
if (foreground == 0)
last_asynchronous_pid = old_async_pid;
failure:

View file

@ -17,6 +17,12 @@
along with this program; 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 "../memalloc.h"
#include "../shell.h"
@ -66,6 +72,9 @@ int sh_opterr = 1;
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
given in OPTSTRING.
@ -102,7 +111,6 @@ sh_getopt (argc, argv, optstring)
char *const *argv;
const char *optstring;
{
int option_index;
char c, *temp;
sh_optarg = 0;
@ -124,10 +132,18 @@ sh_getopt (argc, argv, optstring)
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 we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
/* If we have done all the ARGV-elements, stop the scan. */
if (sh_optind == argc)
return EOF;
@ -158,16 +174,11 @@ sh_getopt (argc, argv, optstring)
c = *nextchar++; sh_charindex++;
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;
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)
BADOPT (c);
@ -175,6 +186,13 @@ sh_getopt (argc, argv, optstring)
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 (nextchar && *nextchar)
@ -191,6 +209,7 @@ sh_getopt (argc, argv, optstring)
NEEDARG (c);
sh_optopt = c;
sh_optarg = ""; /* Needed by getopts. */
c = (optstring[0] == ':') ? ':' : '?';
}
else

View file

@ -51,6 +51,9 @@ extern int sh_opterr;
extern int sh_optopt;
/* Set to 1 when an unrecognized option is encountered. */
extern int sh_badopt;
extern int sh_getopt ();
extern void sh_getopt_restore_state ();

View file

@ -22,7 +22,6 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES getopts.c
$BUILTIN getopts
$DEPENDS_ON GETOPTS_BUILTIN
$FUNCTION getopts_builtin
$SHORT_DOC getopts optstring name [arg]
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.
$END
#include <config.h>
#include <stdio.h>
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../shell.h"
#if defined (GETOPTS_BUILTIN)
#include "common.h"
#include "bashgetopt.h"
#include "getopt.h"
#define G_EOF (-1)
#define G_ILLEGAL_OPT (-2)
#define G_ARG_MISSING (-3)
#define G_EOF -1
#define G_ILLEGAL_OPT -2
#define G_ARG_MISSING -3
extern char *this_command_name;
extern WORD_LIST *rest_of_args;
@ -84,6 +85,25 @@ getopts_reset (newind)
int 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
@ -118,7 +138,7 @@ dogetopts (argc, argv)
int argc;
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 *optstr; /* list of options */
char *name; /* variable to get flag val */
@ -126,7 +146,7 @@ dogetopts (argc, argv)
if (argc < 3)
{
builtin_error("usage: getopts optstring name [arg]");
builtin_usage ();
return (EX_USAGE);
}
@ -156,19 +176,19 @@ dogetopts (argc, argv)
}
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);
}
else
{
register int i;
register WORD_LIST *words;
char **v;
for (i = 0; i < 10 && dollar_vars[i]; i++);
for (words = rest_of_args; words; words = words->next, i++);
for (i = 0; i < 10 && dollar_vars[i]; i++)
;
for (words = rest_of_args; words; words = words->next, i++)
;
v = (char **)xmalloc ((i + 1) * sizeof (char *));
for (i = 0; i < 10 && dollar_vars[i]; 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
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
to a NULL string (that is, optarg[0] == 0). */
to a NULL string (that is, sh_optarg[0] == 0). */
if (ret == '?')
{
if (sh_optarg == NULL)
@ -216,26 +236,25 @@ dogetopts (argc, argv)
if (ret == G_EOF)
{
bind_variable (name, "?");
getopts_bind_variable (name, "?");
return (EXECUTION_FAILURE);
}
if (ret == G_ILLEGAL_OPT)
{
/* Illegal option encountered. */
strval[0] = '?';
strval[1] = '\0';
bind_variable (name, strval);
ret = getopts_bind_variable (name, "?");
if (special_error)
{
strval[0] = (char) sh_optopt;
strval[0] = (char)sh_optopt;
strval[1] = '\0';
bind_variable ("OPTARG", strval);
}
else
makunbound ("OPTARG", shell_variables);
return (EXECUTION_SUCCESS);
return (ret);
}
if (ret == G_ARG_MISSING)
@ -243,31 +262,25 @@ dogetopts (argc, argv)
/* Required argument missing. */
if (special_error)
{
strval[0] = ':';
strval[1] = '\0';
bind_variable (name, strval);
ret = getopts_bind_variable (name, ":");
strval[0] = (char) sh_optopt;
strval[0] = (char)sh_optopt;
strval[1] = '\0';
bind_variable ("OPTARG", strval);
}
else
{
strval[0] = '?';
strval[1] = '\0';
bind_variable (name, strval);
ret = getopts_bind_variable (name, "?");
makunbound ("OPTARG", shell_variables);
}
return (EXECUTION_SUCCESS);
return (ret);
}
bind_variable ("OPTARG", sh_optarg);
strval[0] = (char) ret;
strval[1] = '\0';
bind_variable (name, strval);
return (EXECUTION_SUCCESS);
return (getopts_bind_variable (name, strval));
}
/* The getopts builtin. Build an argv, and call dogetopts with it. */
@ -275,26 +288,27 @@ int
getopts_builtin (list)
WORD_LIST *list;
{
register int i;
char **av;
int ac, ret;
WORD_LIST *t;
if (list == 0)
return EXECUTION_FAILURE;
for (t = list, ac = 0; t; t = t->next, ac++);
ac++;
av = (char **)xmalloc ((1 + ac) * sizeof (char *));
av[ac] = (char *) NULL;
av[0] = this_command_name;
for (t = list, i = 1; t; t = t->next, i++)
av[i] = t->word->word;
reset_internal_getopt ();
while ((ret = internal_getopt (list, "")) != -1)
{
switch (ret)
{
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
av = make_builtin_argv (list, &ac);
ret = dogetopts (ac, av);
free ((char *)av);
return (ret);
}
#endif /* GETOPTS_BUILTIN */

View file

@ -23,182 +23,167 @@ $PRODUCES hash.c
$BUILTIN hash
$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
remembered. The -r option causes the shell to forget all remembered
locations. If no arguments are given, information about remembered
commands is presented.
remembered. If the -p option is supplied, PATHNAME is used as the
full pathname of NAME, and no path search is performed. The -r
option causes the shell to forget all remembered locations. If no
arguments are given, information about remembered commands is displayed.
$END
#include <config.h>
#include <sys/types.h>
#include "../posixstat.h"
#include <stdio.h>
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../shell.h"
#include "../builtins.h"
#include "../flags.h"
#include "../execute_cmd.h"
#include "hashcom.h"
#include "common.h"
#include "../execute_cmd.h"
#include "bashgetopt.h"
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
initialize_filename_hashing ()
{
hashed_filenames = make_hash_table (FILENAME_HASH_BUCKETS);
if (hashing_initialized == 0)
{
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
not empty, then rehash (or hash in the first place) the specified
commands. */
int
hash_builtin (list)
WORD_LIST *list;
{
int expunge_hash_table = 0;
int any_failed = 0;
int expunge_hash_table, opt;
char *word, *pathname;
if (hashing_disabled)
if (hashing_enabled == 0)
{
builtin_error ("hashing disabled");
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;
if (ISOPTION (arg, 'r'))
switch (opt)
{
case 'r':
expunge_hash_table = 1;
list = list->next;
}
else if (ISOPTION (arg, '-'))
{
list = list->next;
break;
}
else if (*arg == '-')
{
bad_option (list->word->word);
builtin_error ("usage: hash [-r] [command ...]");
case 'p':
pathname = list_optarg;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
else
break;
}
list = loptend;
/* We want hash -r to be silent, but hash -- to print hashing info. That
is the reason for the !expunge_hash_table. */
if (!list && !expunge_hash_table)
is the reason for the test of expunge_hash_table. */
if (list == 0 && expunge_hash_table == 0)
{
/* Print information about current hashed info. */
int any_printed = 0;
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");
if (print_hashed_commands () == 0)
printf ("%s: hash table empty\n", this_command_name);
return (EXECUTION_SUCCESS);
}
if (expunge_hash_table)
{
int bucket = 0;
register BUCKET_CONTENTS *item_list, *prev;
flush_hashed_filenames ();
while (bucket < hashed_filenames->nbuckets)
{
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)
for (opt = EXECUTION_SUCCESS; list; list = list->next)
{
/* Add or rehash the specified commands. */
char *word;
char *full_path;
SHELL_VAR *var;
word = list->word->word;
if (absolute_program (word))
if (pathname)
remember_filename (word, pathname, 0, 0);
else
{
list = list->next;
continue;
}
full_path = find_user_command (word);
var = find_function (word);
if (!find_shell_builtin (word) && (!var))
{
if (full_path && executable_file (full_path))
remember_filename (word, full_path, dot_found_in_search, 0);
else
if (absolute_program (word))
{
builtin_error ("%s: not found", word);
any_failed++;
list = list->next;
continue;
}
}
if (full_path)
free (full_path);
list = list->next;
if (add_hashed_command (word))
opt = EXECUTION_FAILURE;
}
}
fflush (stdout);
if (any_failed)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
return (opt);
}
/* Place FILENAME (key) and FULL_PATHNAME (data->path) into the
hash table. CHECK_DOT if non-null is for future calls to
find_hashed_filename (). FOUND is the initial value for
times_found. */
find_hashed_filename (); it means that this file was found
in a directory in $PATH that is not an absolute pathname.
FOUND is the initial value for times_found. */
void
remember_filename (filename, full_pathname, check_dot, found)
char *filename, *full_pathname;
@ -206,17 +191,74 @@ remember_filename (filename, full_pathname, check_dot, found)
{
register BUCKET_CONTENTS *item;
if (hashing_disabled)
if (hashing_enabled == 0)
return;
item = add_hash_item (filename, hashed_filenames);
if (item->data)
free (pathdata(item)->path);
else
{
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)->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;
}
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);
}

View file

@ -18,7 +18,7 @@
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "../hash.h"
#include "../hashlib.h"
#define FILENAME_HASH_BUCKETS 631
@ -26,7 +26,10 @@ extern HASH_TABLE *hashed_filenames;
typedef struct {
char *path; /* The full pathname of the file. */
int check_dot; /* Whether `.' appeared before this one in $PATH. */
int flags;
} 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)

View file

@ -23,112 +23,131 @@ $PRODUCES help.c
$BUILTIN help
$FUNCTION help_builtin
$DEPENDS_ON HELP_BUILTIN
$SHORT_DOC help [pattern ...]
Display helpful information about builtin commands. If PATTERN is
specified, gives detailed help on all commands matching PATTERN,
otherwise a list of the builtins is printed.
$END
#include <config.h>
#if defined (HELP_BUILTIN)
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../shell.h"
#include "../builtins.h"
#include "bashgetopt.h"
#if defined (USE_GLOB_LIBRARY)
# include <glob/glob.h>
#else
# define FNM_NOMATCH 1
#endif /* USE_GLOB_LIBRARY */
#include <glob/fnmatch.h>
#include <glob/glob.h>
static void show_builtin_command_help ();
/* 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
specified. */
int
help_builtin (list)
WORD_LIST *list;
{
if (!list)
{
register int i, j;
char blurb[256];
register int i, j;
char *pattern, *name;
int plen, match_found;
show_shell_version ();
printf (
"Shell commands that are defined internally. Type `help' to see this list.\n\
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];
printf (
"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\
Use `info bash' to find out more about the shell in general.\n\
\n\
A star (*) next to a name means that the command is disabled.\n\
\n");
for (i = 0; i < num_shell_builtins; i++)
{
QUIT;
sprintf (blurb, "%c%s",
(shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*',
shell_builtins[i].short_doc);
for (i = 0; i < num_shell_builtins; i++)
{
QUIT;
blurb[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
strncpy (blurb + 1, shell_builtins[i].short_doc, 34);
blurb[35] = '\0';
printf ("%s", blurb);
blurb[35] = '\0';
printf ("%s", blurb);
if (i % 2)
printf ("\n");
else
for (j = strlen (blurb); j < 35; j++)
putc (' ', stdout);
}
if (i % 2)
printf ("\n");
else
for (j = strlen (blurb); j < 35; j++)
putc (' ', stdout);
}
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);
if (i % 2)
printf ("\n");
}
#endif /* HELP_BUILTIN */

View file

@ -24,156 +24,277 @@ $PRODUCES history.c
$BUILTIN history
$FUNCTION history_builtin
$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
with a `*' have been modified. Argument of N says to list only
the last N lines. Argument `-w' means to write out the current
history file; `-r' means to read it instead. Argument `-a' means
the last N lines. The -c option causes the history list to be
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.
Argument `-n' means to read all history lines not already read
from the history file. If FILENAME is given, then use that file,
else if $HISTFILE has a value, use that, else use ~/.bash_history.
from the history file and append them to the history list. If
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
#include "../shell.h"
#include <config.h>
#if defined (HISTORY)
#include <sys/types.h>
#include <sys/file.h>
#include "../filecntl.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 <readline/history.h>
#include "bashgetopt.h"
#include "common.h"
/* History. Arg of -w FILENAME means write file, arg of -r FILENAME
means read file. Arg of N means only display that many items. */
#if !defined (errno)
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)
WORD_LIST *list;
{
register int i;
int limited = 0, limit = 0;
HIST_ENTRY **hlist;
int flags, opt, result;
char *filename;
while (list)
flags = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "acnpsrw")) != -1)
{
char *arg = list->word->word;
if ((arg[0] == '-') &&
(strlen (arg) == 2) &&
(member (arg[1], "rwan")))
switch (opt)
{
char *file;
int result = EXECUTION_SUCCESS;
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;
}
case 'w': /* Write entire history. */
{
result = write_history (file);
break;
}
case 'r': /* Read entire file. */
{
result = read_history (file);
break;
}
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;
}
}
return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
else if (strcmp (list->word->word, "--") == 0)
{
list = list->next;
case 'a':
flags |= AFLAG;
break;
}
else if (*list->word->word == '-')
{
bad_option (list->word->word);
builtin_error ("usage: history [n] [-rwan [filename]]");
case 'c':
flags |= CFLAG;
break;
case 'n':
flags |= NFLAG;
break;
case 'r':
flags |= RFLAG;
break;
case 'w':
flags |= WFLAG;
break;
case 's':
flags |= SFLAG;
break;
case 'p':
#if defined (BANG_HISTORY)
flags |= PFLAG;
#endif
break;
default:
builtin_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)
{
limited = 1;
limit = get_numeric_arg (list);
}
else
limited = limit = 0;
hlist = history_list ();
if (hlist)
{
for (i = 0; hlist[i]; i++);
for (i = 0; hlist[i]; i++)
;
if (limit < 0)
limit = -limit;
if (!limited)
if ((limited == 0) || ((i -= limit) < 0))
i = 0;
else
if ((i -= limit) < 0)
i = 0;
while (hlist[i])
{
QUIT;
printf ("%5d%c %s\n", i + history_base,
hlist[i]->data ? '*' : ' ', hlist[i]->line);
histdata(i) ? '*' : ' ',
histline(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 */

View file

@ -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.
$PRODUCES inlib.c
#include <config.h>
#include <stdio.h>
#include "../shell.h"

View file

@ -1,5 +1,5 @@
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.
@ -24,24 +24,38 @@ $PRODUCES jobs.c
$BUILTIN jobs
$FUNCTION jobs_builtin
$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
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
notification are printed. JOBSPEC restricts output to that job.
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.
notification are printed. JOBSPEC restricts output to that job. The
-r and -s options restrict output to running and stopped jobs only,
respectively. Without options, the status of all active jobs is
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
#include "../shell.h"
#include <config.h>
#if defined (JOB_CONTROL)
#include <sys/types.h>
#include "../bashtypes.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 "common.h"
#define JSTATE_ANY 0x0
#define JSTATE_RUNNING 0x1
#define JSTATE_STOPPED 0x2
extern int job_control, interactive_shell;
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
status since the last notification are printed. If -x is given,
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
jobs_builtin (list)
WORD_LIST *list;
{
int form = JLIST_STANDARD, execute = 0;
int opt;
int any_failed = 0;
int form, execute, state, opt, any_failed, job;
sigset_t set, oset;
if (!job_control && !interactive_shell)
if (job_control == 0 && interactive_shell == 0)
return (EXECUTION_SUCCESS);
execute = any_failed = 0;
form = JLIST_STANDARD;
state = JSTATE_ANY;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "lpnx")) != -1)
while ((opt = internal_getopt (list, "lpnxrs")) != -1)
{
switch (opt)
{
@ -86,9 +104,15 @@ jobs_builtin (list)
}
execute++;
break;
case 'r':
state = JSTATE_RUNNING;
break;
case 's':
state = JSTATE_STOPPED;
break;
default:
builtin_error ("usage: jobs [-lpn [jobspec]] [-x command [args]]");
builtin_usage ();
return (EX_USAGE);
}
}
@ -100,21 +124,29 @@ jobs_builtin (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);
}
while (list)
{
int job;
sigset_t set, oset;
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
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++;
}
else if (job != DUP_JOB)
@ -169,3 +201,62 @@ execute_list_with_replacements (list)
return (result);
}
#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 */

View file

@ -24,7 +24,7 @@ $PRODUCES kill.c
$BUILTIN kill
$FUNCTION kill_builtin
$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
SIGSPEC is not present, then SIGTERM is assumed. An argument of `-l'
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.
$END
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
#if !defined (errno)
extern int errno;
#endif /* !errno */
#include <config.h>
#include <stdio.h>
#include <errno.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../bashtypes.h"
#include "../shell.h"
#include "../trap.h"
#include "../jobs.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)
extern int interactive;
@ -63,14 +71,17 @@ int
kill_builtin (list)
WORD_LIST *list;
{
int signal = SIGTERM;
int any_succeeded = 0, listing = 0, saw_signal = 0;
char *sigspec = "TERM", *word;
int signal, any_succeeded, listing, saw_signal;
char *sigspec, *word;
pid_t pid;
if (!list)
if (list == 0)
return (EXECUTION_SUCCESS);
any_succeeded = listing = saw_signal = 0;
signal = SIGTERM;
sigspec = "TERM";
/* Process options. */
while (list)
{
@ -81,13 +92,13 @@ kill_builtin (list)
listing++;
list = list->next;
}
else if (ISOPTION (word, 's'))
else if (ISOPTION (word, 's') || ISOPTION (word, 'n'))
{
list = list->next;
if (list)
{
sigspec = list->word->word;
if (sigspec[0] == '0' && !sigspec[1])
if (sigspec[0] == '0' && sigspec[1] == '\0')
signal = 0;
else
signal = decode_signal (sigspec);
@ -95,7 +106,7 @@ kill_builtin (list)
}
else
{
builtin_error ("-s requires an argument");
builtin_error ("%s requires an argument", word);
return (EXECUTION_FAILURE);
}
}
@ -104,6 +115,11 @@ kill_builtin (list)
list = list->next;
break;
}
else if (ISOPTION (word, '?'))
{
builtin_usage ();
return (EXECUTION_SUCCESS);
}
/* If this is a signal specification then process it. We only process
the first one seen; other arguments may signify process groups (e.g,
-num == process group num). */
@ -119,75 +135,7 @@ kill_builtin (list)
}
if (listing)
{
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);
}
return (display_signal_list (list, 0));
/* OK, we are killing processes. */
if (signal == NO_SIG)
@ -215,15 +163,11 @@ kill_builtin (list)
}
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;
}
#if 1
else if (interactive)
/* 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. */
int job;
sigset_t set, oset;
@ -234,7 +178,7 @@ kill_builtin (list)
if (job < 0 || job >= job_slots || !jobs[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);
CONTINUE_OR_FAIL;
}
@ -243,10 +187,7 @@ kill_builtin (list)
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
in that case. */
if (jobs[job]->flags & J_JOBCONTROL)
pid = jobs[job]->pgrp;
else
pid = jobs[job]->pipe->pid;
pid = IS_JOBCONTROL (job) ? jobs[job]->pgrp : jobs[job]->pipe->pid;
UNBLOCK_CHILD (oset);
@ -266,16 +207,13 @@ kill_builtin (list)
}
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_killing:
list = list->next;
}
if (any_succeeded)
return (EXECUTION_SUCCESS);
else
return (EXECUTION_FAILURE);
return (any_succeeded ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
#endif /* JOB_CONTROL */

View file

@ -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.
The levels are listed in order of decreasing precedence.
- unary minus
! logical NOT
* / % multiplication, division, remainder
+ - addition, subtraction
<= >= < > comparison
== != equality inequality
= assignment
-, + unary minus, plus
!, ~ logical and bitwise negation
*, /, % multiplication, division, remainder
+, - addition, subtraction
<<, >> left and right bitwise shifts
<=, >=, <, > comparison
==, != 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
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.
$END
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../shell.h"
#include "common.h"
/* Arithmetic LET function. */
int
let_builtin (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);
}
while (list)
for (; list; list = list->next)
ret = evalexp (list->word->word);
return ((ret == 0L) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
int
exp_builtin (list)
WORD_LIST *list;
{
char *exp;
int ret;
if (list == 0)
{
ret = evalexp (list->word->word);
list = list->next;
builtin_error ("expression expected");
return (EXECUTION_FAILURE);
}
if (ret == 0L)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
exp = string_list (list);
ret = evalexp (exp);
free (exp);
return ((ret == 0L) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}

View file

@ -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
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../config.h"
#include <stdio.h>
@ -50,6 +56,7 @@ extern char *strcpy ();
/* Flag values that builtins can have. */
#define BUILTIN_FLAG_SPECIAL 0x01
#define BUILTIN_FLAG_ASSIGNMENT 0x02
/* If this stream descriptor is non-zero, then write
texinfo documentation to it. */
@ -115,12 +122,41 @@ char *special_builtins[] =
"export", "readonly", "return", "set", "shift", "trap", "unset",
(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
write the information to STRUCTFILE and EXTERNFILE, while
creating the production file if neccessary. */
int
main (argc, argv)
int argc;
char **argv;
@ -305,6 +341,7 @@ copy_string_array (array)
}
/* Add ELEMENT to ARRAY, growing the array if neccessary. */
void
array_add (element, array)
char *element;
ARRAY *array;
@ -324,6 +361,7 @@ array_add (element, array)
}
/* Free an allocated array and data pointer. */
void
array_free (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
builtins found in each $BUILTIN. Plain text found before the $PRODUCES
is ignored, as is "$$ comment text". */
void
extract_info (filename, structfile, externfile)
char *filename;
FILE *structfile, *externfile;
@ -548,6 +587,7 @@ free_builtin (builtin)
}
/* Free all of the memory allocated to a DEF_FILE. */
void
free_defs (defs)
DEF_FILE *defs;
{
@ -592,6 +632,7 @@ strip_whitespace (string)
}
/* Remove only the trailing whitespace from STRING. */
void
remove_trailing_whitespace (string)
char *string;
{
@ -625,6 +666,7 @@ get_arg (for_whom, defs, string)
}
/* Error if not building a builtin. */
void
must_be_building (directive, defs)
char *directive;
DEF_FILE *defs;
@ -645,6 +687,7 @@ current_builtin (directive, defs)
/* Add LINE to the long documentation for the current builtin.
Ignore blank lines until the first non-blank line has been seen. */
void
add_documentation (defs, line)
DEF_FILE *defs;
char *line;
@ -670,38 +713,42 @@ builtin_handler (self, defs, arg)
char *self, *arg;
DEF_FILE *defs;
{
BUILTIN_DESC *new;
char *name;
/* If we are already building a builtin, we cannot start a new one. */
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++;
/* 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 (!defs->builtins)
defs->builtins = array_create (sizeof (BUILTIN_DESC *));
/* If this is the first builtin, create the array to hold them. */
if (!defs->builtins)
defs->builtins = array_create (sizeof (BUILTIN_DESC *));
new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
new->name = name;
new->function = (char *)NULL;
new->shortdoc = (char *)NULL;
new->docname = (char *)NULL;
new->longdoc = (ARRAY *)NULL;
new->dependencies = (ARRAY *)NULL;
new->flags = 0;
new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
new->name = name;
new->function = (char *)NULL;
new->shortdoc = (char *)NULL;
new->docname = (char *)NULL;
new->longdoc = (ARRAY *)NULL;
new->dependencies = (ARRAY *)NULL;
new->flags = 0;
if (is_special_builtin (name))
new->flags |= BUILTIN_FLAG_SPECIAL;
if (is_assignment_builtin (name))
new->flags |= BUILTIN_FLAG_ASSIGNMENT;
if (is_special_builtin (name))
new->flags |= BUILTIN_FLAG_SPECIAL;
array_add ((char *)new, defs->builtins);
building_builtin = 1;
array_add ((char *)new, defs->builtins);
building_builtin = 1;
}
return (0);
}
@ -744,6 +791,7 @@ docname_handler (self, defs, arg)
}
/* How to handle the $SHORT_DOC directive. */
int
short_doc_handler (self, defs, arg)
char *self, *arg;
DEF_FILE *defs;
@ -762,13 +810,16 @@ short_doc_handler (self, defs, arg)
}
/* How to handle the $COMMENT directive. */
int
comment_handler (self, defs)
char *self;
DEF_FILE *defs;
{
return (0);
}
/* How to handle the $DEPENDS_ON directive. */
int
depends_on_handler (self, defs, arg)
char *self, *arg;
DEF_FILE *defs;
@ -788,6 +839,7 @@ depends_on_handler (self, defs, arg)
}
/* How to handle the $PRODUCES directive. */
int
produces_handler (self, defs, arg)
char *self, *arg;
DEF_FILE *defs;
@ -820,12 +872,14 @@ produces_handler (self, defs, arg)
}
/* How to handle the $END directive. */
int
end_handler (self, defs, arg)
char *self, *arg;
DEF_FILE *defs;
{
must_be_building (self, defs);
building_builtin = 0;
return (0);
}
/* **************************************************************** */
@ -835,6 +889,7 @@ end_handler (self, defs, arg)
/* **************************************************************** */
/* Produce an error for DEFS with FORMAT and ARGS. */
void
line_error (defs, format, arg1, arg2)
DEF_FILE *defs;
char *format, *arg1, *arg2;
@ -848,6 +903,7 @@ line_error (defs, format, arg1, arg2)
}
/* Print error message for FILENAME. */
void
file_error (filename)
char *filename;
{
@ -895,7 +951,7 @@ xrealloc (pointer, bytes)
static void
memory_error_and_abort ()
{
fprintf (stderr, "mkbuiltins: Out of virtual memory!\n");
fprintf (stderr, "mkbuiltins: out of virtual memory\n");
abort ();
}
@ -929,6 +985,7 @@ copy_builtin (builtin)
}
/* How to save away a builtin. */
void
save_builtin (builtin)
BUILTIN_DESC *builtin;
{
@ -972,7 +1029,7 @@ char *structfile_header[] = {
" along with Bash; see the file COPYING. If not, write to the Free",
" 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",
" 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",
@ -992,13 +1049,17 @@ char *structfile_footer[] = {
" { (char *)0x0, (Function *)0x0, 0, (char **)0x0, (char *)0x0 }",
"};",
"",
"struct builtin *shell_builtins = static_shell_builtins;",
"struct builtin *current_builtin;",
"",
"int num_shell_builtins =",
"\tsizeof (shell_builtins) / sizeof (struct builtin) - 1;",
"\tsizeof (static_shell_builtins) / sizeof (struct builtin) - 1;",
(char *)NULL
};
/* Write out any neccessary opening information for
STRUCTFILE and EXTERNFILE. */
void
write_file_headers (structfile, externfile)
FILE *structfile, *externfile;
{
@ -1011,7 +1072,7 @@ write_file_headers (structfile, externfile)
fprintf (structfile, "#include \"%s\"\n",
extern_filename ? extern_filename : "builtext.h");
fprintf (structfile, "\nstruct builtin shell_builtins[] = {\n");
fprintf (structfile, "\nstruct builtin static_shell_builtins[] = {\n");
}
if (externfile)
@ -1022,6 +1083,7 @@ write_file_headers (structfile, externfile)
/* Write out any necessary closing information for
STRUCTFILE and EXTERNFILE. */
void
write_file_footers (structfile, externfile)
FILE *structfile, *externfile;
{
@ -1037,6 +1099,7 @@ write_file_footers (structfile, externfile)
/* Write out the information accumulated in DEFS to
STRUCTFILE and EXTERNFILE. */
void
write_builtins (defs, structfile, externfile)
DEF_FILE *defs;
FILE *structfile, *externfile;
@ -1057,8 +1120,7 @@ write_builtins (defs, structfile, externfile)
{
if (builtin->dependencies)
{
if (builtin->function)
write_ifdefs (externfile, builtin->dependencies->array);
write_ifdefs (externfile, builtin->dependencies->array);
write_ifdefs (structfile, builtin->dependencies->array);
}
@ -1083,20 +1145,14 @@ write_builtins (defs, structfile, externfile)
else
fprintf (structfile, "(Function *)0x0, ");
#define SPECIAL_FLAG_STRING "BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN"
#define NORMAL_FLAG_STRING "BUILTIN_ENABLED | STATIC_BUILTIN"
fprintf (structfile, "%s, %s_doc,\n",
(builtin->flags & BUILTIN_FLAG_SPECIAL) ?
SPECIAL_FLAG_STRING :
NORMAL_FLAG_STRING,
fprintf (structfile, "%s%s%s, %s_doc,\n",
"BUILTIN_ENABLED | STATIC_BUILTIN",
(builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
(builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
builtin->docname ? builtin->docname : builtin->name);
#undef SPECIAL_FLAG_STRING
#undef NORMAL_FLAG_STRING
fprintf
(structfile, " \"%s\" },\n",
(structfile, " \"%s\", (char *)NULL },\n",
builtin->shortdoc ? builtin->shortdoc : builtin->name);
/* 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. */
void
write_longdocs (stream, builtins)
FILE *stream;
ARRAY *builtins;
@ -1157,6 +1214,7 @@ write_longdocs (stream, builtins)
DEFINES is a null terminated array of define names.
If a define is preceded by an `!', then the sense of the test is
reversed. */
void
write_ifdefs (stream, defines)
FILE *stream;
char **defines;
@ -1187,6 +1245,7 @@ write_ifdefs (stream, defines)
of the immediately preceding code.
STREAM is the stream to write the information to.
DEFINES is a null terminated array of define names. */
void
write_endifs (stream, defines)
FILE *stream;
char **defines;
@ -1211,6 +1270,7 @@ write_endifs (stream, defines)
/* Write DOCUMENTAION to STREAM, perhaps surrounding it with double-quotes
and quoting special characters in the string. */
void
write_documentation (stream, documentation, indentation, flags)
FILE *stream;
char **documentation;
@ -1218,14 +1278,14 @@ write_documentation (stream, documentation, indentation, flags)
{
register int i, j;
register char *line;
int string_array = (flags & STRING_ARRAY); /* Mutually exclusive. */
int texinfo = (flags & TEXINFO);
int string_array, texinfo;
if (!stream)
return;
string_array = flags & STRING_ARRAY;
if (string_array)
fprintf (stream, " {\n");
fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n");
#if !defined (OLDCODE)
/* XXX -- clean me up; for experiment only */
@ -1233,7 +1293,7 @@ write_documentation (stream, documentation, indentation, flags)
goto end_of_document;
#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. */
if (*line == '#')
@ -1295,17 +1355,31 @@ end_of_document:
#endif /* !OLDCODE */
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
is_special_builtin (name)
char *name;
{
register int i;
for (i = 0; special_builtins[i]; i++)
if (strcmp (name, special_builtins[i]) == 0)
return 1;
return 0;
return (_find_in_table (name, special_builtins));
}
static int
is_assignment_builtin (name)
char *name;
{
return (_find_in_table (name, assignment_builtins));
}

View file

@ -21,6 +21,11 @@
/* 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
pipe size. */
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include <sys/types.h>
@ -29,6 +34,7 @@
#include "../command.h"
#include "../general.h"
#include "../sig.h"
extern int errno;
int nw;

604
builtins/pushd.def Normal file
View 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 */

View file

@ -23,101 +23,170 @@ $PRODUCES read.c
$BUILTIN read
$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
assigned to the first NAME, the second word to the second NAME, etc.
with leftover words assigned to the last NAME. Only the characters
assigned to the first NAME, the second word to the second NAME, and so
on, with leftover words assigned to the last NAME. Only the characters
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,
this signifies `raw' input, and backslash processing is disabled.
zero, unless end-of-file is encountered. If no NAMEs are supplied, the
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
#include <config.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../shell.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;
#if defined (READLINE)
static char *edit_line ();
#endif
static SHELL_VAR *bind_read_variable ();
/* Read the value of the shell variables whose names follow.
The reading is done from the current input stream, whatever
that may be. Successive words of the input line are assigned
to the variables mentioned in LIST. The last variable in LIST
gets the remainder of the words on the line. If no variables
are mentioned in LIST, then the default variable is $REPLY.
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. */
are mentioned in LIST, then the default variable is $REPLY. */
int
read_builtin (list)
WORD_LIST *list;
{
register char *varname;
int size, c, i, fildes, raw_mode, pass_next, saw_escape, retval;
char *input_string, *orig_input_string, *ifs_chars, *t;
FILE *input_stream;
int size, i, raw, pass_next, saw_escape, eof, opt, retval, edit;
char c;
char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
char *e, *t, *t1;
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. */
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'))
{
raw_mode = 1;
list = list->next;
}
else if (ISOPTION (list->word->word, '-'))
{
list = list->next;
switch (opt)
{
case 'r':
raw = 1;
break;
}
else if (*list->word->word == '-')
{
bad_option (list->word->word);
builtin_error ("usage: read [-r] [name ...]");
case 'p':
prompt = list_optarg;
break;
case 'e':
#if defined (READLINE)
edit = 1;
#endif
break;
#if defined (ARRAY_VARS)
case 'a':
arrayname = list_optarg;
break;
#endif
default:
builtin_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");
ifs_chars = var ? value_cell (var) : " \t\n";
input_string = xmalloc (size = 128);
if (ifs_chars == 0) /* XXX */
ifs_chars = ""; /* XXX */
setbuf (input_stream, (char *)NULL);
input_string = xmalloc (size = 128);
begin_unwind_frame ("read_builtin");
add_unwind_protect (xfree, input_string);
add_unwind_protect (stream_close, input_stream);
#if defined (READLINE)
add_unwind_protect (xfree, rlbuf);
#endif
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. */
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)
input_string = xrealloc (input_string, size += 128);
@ -133,7 +202,7 @@ read_builtin (list)
continue;
}
if (c == '\\' && !raw_mode)
if (c == '\\' && raw == 0)
{
pass_next++;
saw_escape++;
@ -157,15 +226,31 @@ read_builtin (list)
interrupt_immediately--;
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;
/* input_string[0] = '\0'; */
var = find_variable (arrayname);
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);
}
free (input_string);
return (retval);
}
else
retval = EXECUTION_SUCCESS;
#endif /* ARRAY_VARS */
if (!list)
{
@ -179,98 +264,140 @@ read_builtin (list)
var = bind_variable ("REPLY", input_string);
var->attributes &= ~att_invisible;
free (input_string);
return (retval);
}
else
/* This code implements the Posix.2 spec for splitting the words
read and assigning them to variables. */
orig_input_string = input_string;
/* Remove IFS white space at the beginning of the input string. If
$IFS is null, no field splitting is performed. */
for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++)
;
input_string = t;
for (; list->next; list = list->next)
{
/* This code implements the Posix.2 spec for splitting the words
read and assigning them to variables. If $IFS is unset, we
use the default value of " \t\n". */
orig_input_string = input_string;
/* Remove IFS white space at the beginning of the input string. If
$IFS is null, no field splitting is performed. */
for (t = input_string; *ifs_chars && spctabnl (*t) && issep (*t); t++)
;
input_string = t;
for (; list->next; list = list->next)
varname = list->word->word;
#if defined (ARRAY_VARS)
if (legal_identifier (varname) == 0 && valid_array_reference (varname) == 0)
#else
if (legal_identifier (varname) == 0)
#endif
{
char *e, *t1;
varname = list->word->word;
if (legal_identifier (varname) == 0)
{
builtin_error ("%s: not a legal variable name", varname);
free (orig_input_string);
return (EXECUTION_FAILURE);
}
/* If there are more variables than words read from the input,
the remaining variables are set to the empty string. */
if (*input_string)
{
/* This call updates INPUT_STRING. */
t = get_word_from_string (&input_string, ifs_chars, &e);
if (t)
*e = '\0';
/* Don't bother to remove the CTLESC unless we added one
somewhere while reading the string. */
if (t && saw_escape)
{
t1 = dequote_string (t);
var = bind_variable (varname, t1);
free (t1);
}
else
var = bind_variable (varname, t);
}
else
{
t = (char *)0;
var = bind_variable (varname, "");
}
stupidly_hack_special_variables (varname);
var->attributes &= ~att_invisible;
if (t)
free (t);
}
if (legal_identifier (list->word->word) == 0)
{
builtin_error ("%s: not a legal variable name", list->word->word);
builtin_error ("`%s': not a valid identifier", varname);
free (orig_input_string);
return (EXECUTION_FAILURE);
}
/* 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
remaining words and their intervening separators. */
input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars,
saw_escape);
if (saw_escape)
/* If there are more variables than words read from the input,
the remaining variables are set to the empty string. */
if (*input_string)
{
t = dequote_string (input_string);
var = bind_variable (list->word->word, t);
free (t);
/* This call updates INPUT_STRING. */
t = get_word_from_string (&input_string, ifs_chars, &e);
if (t)
*e = '\0';
/* Don't bother to remove the CTLESC unless we added one
somewhere while reading the string. */
if (t && saw_escape)
{
t1 = dequote_string (t);
var = bind_read_variable (varname, t1);
free (t1);
}
else
var = bind_read_variable (varname, t);
}
else
var = bind_variable (list->word->word, input_string);
stupidly_hack_special_variables (list->word->word);
{
t = (char *)0;
var = bind_read_variable (varname, "");
}
FREE (t);
if (var == 0)
{
free (orig_input_string);
return (EXECUTION_FAILURE);
}
stupidly_hack_special_variables (varname);
var->attributes &= ~att_invisible;
free (orig_input_string);
}
/* 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)
#endif
{
builtin_error ("`%s': not a valid identifier", list->word->word);
free (orig_input_string);
return (EXECUTION_FAILURE);
}
/* 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
remaining words and their intervening separators. */
input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
if (saw_escape)
{
t = dequote_string (input_string);
var = bind_read_variable (list->word->word, t);
free (t);
}
else
var = bind_read_variable (list->word->word, input_string);
stupidly_hack_special_variables (list->word->word);
if (var)
var->attributes &= ~att_invisible;
free (orig_input_string);
return (retval);
}
/* This way I don't have to know whether fclose () is a
function or a macro. */
static int
stream_close (file)
FILE *file;
static SHELL_VAR *
bind_read_variable (name, value)
char *name, *value;
{
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

View file

@ -43,6 +43,15 @@ in the variable REPLY. COMMANDS are executed after each selection
until a break or return command is executed.
$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
$SHORT_DOC case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
Selectively execute COMMANDS based upon WORD matching PATTERN. The
@ -97,10 +106,12 @@ $END
$BUILTIN variables
$DOCNAME variable_help
$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
when the argument to `cd' is not found in the current
directory.
GLOBIGNORE A colon-separated list of patterns describing filenames to
be ignored by pathname expansion.
#if defined (HISTORY)
HISTFILE The name of the file where your command history is stored.
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.
#endif /* HISTORY */
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.
IGNOREEOF Controls the action of the shell on receipt of an EOF
character as the sole input. If set, then the value
of it is the number of EOF characters that can be seen
in a row on an empty line before the shell will exit
(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.
MAILPATH A colon-separated list of filenames which Bash checks
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
looking for commands.
PROMPT_COMMAND A command to be executed before the printing of each
primary prompt.
PS1 The primary 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.
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
itself is first looked for in the list of currently
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
the command must be a prefix of a stopped job.
#if defined (HISTORY)
command_oriented_history
Non-null means to save multiple-line commands together on
a single history line.
# if defined (BANG_HISTORY)
histchars Characters controlling history expansion and quick
substitution. The first character is the history
@ -143,12 +158,7 @@ histchars Characters controlling history expansion and quick
the `quick substitution' character, usually `^'. The
third is the `history comment' character, usually `#'.
# endif /* BANG_HISTORY */
HISTCONTROL Set to a value of `ignorespace', it means don't enter
lines which begin with a space or tab on the history
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.
HISTIGNORE A colon-separated list of patterns used to decide which
command should be saved on the history list.
#endif /* HISTORY */
$END

View file

@ -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.
$END
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../shell.h"
#include "common.h"
extern int last_command_exit_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
specified as an argument. if no argument is given, then the last
@ -42,16 +48,13 @@ int
return_builtin (list)
WORD_LIST *list;
{
return_catch_value = get_numeric_arg (list);
if (!list)
return_catch_value = last_command_exit_value;
return_catch_value = list ? get_numeric_arg (list) : last_command_exit_value;
if (return_catch_flag)
longjmp (return_catch, 1);
else
{
builtin_error ("Can only `return' from a function");
builtin_error ("can only `return' from a function or sourced script");
return (EXECUTION_FAILURE);
}
}

View file

@ -21,62 +21,79 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES set.c
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include "../bashansi.h"
#include "../shell.h"
#include "../flags.h"
#include "common.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 noclobber, no_brace_expansion, posixly_correct;
extern int noclobber, posixly_correct, ignoreeof, eof_encountered_limit;
#if defined (READLINE)
extern int rl_editing_mode, no_line_editing;
#endif /* READLINE */
#define USAGE_STRING "set [--abefhknotuvxldHCP] [-o option] [arg ...]"
$BUILTIN set
$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.
-b Notify of job termination immediately.
-e Exit immediately if a command exits with a non-zero status.
-f Disable file name generation (globbing).
-h Locate and remember function commands as functions are
defined. Function commands are normally looked up when
the function is executed.
-h Remember the location of commands as they are looked up.
-i Force the shell to be an "interactive" one. Interactive shells
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.
-m Job control is enabled.
-n Read commands but do not execute them.
-o option-name
Set the variable corresponding to option-name:
allexport same as -a
braceexpand the shell will perform brace expansion
braceexpand same as -B
#if defined (READLINE)
emacs use an emacs-style line editing interface
#endif /* READLINE */
errexit same as -e
hashall same as -h
#if defined (BANG_HISTORY)
histexpand same as -H
#endif /* BANG_HISTORY */
ignoreeof the shell will not exit upon reading EOF
interactive-comments
allow comments to appear in interactive commands
keyword same as -k
monitor same as -m
noclobber disallow redirection to existing files
noclobber same as -C
noexec same as -n
noglob same as -f
nohash same as -d
notify save as -b
nounset same as -u
physical same as -P
posix change the behavior of bash where the default
operation differs from the 1003.2 standard to
match the standard
privileged same as -p
onecmd same as -t
physical same as -P
posix change the behavior of bash where the default
operation differs from the 1003.2 standard to
match the standard
privileged same as -p
verbose same as -v
#if defined (READLINE)
vi use a vi-style line editing interface
@ -85,15 +102,14 @@ $SHORT_DOC set [--abefhknotuvxldHCP] [-o option] [arg ...]
-p Turned on whenever the real and effective user ids do not match.
Disables processing of the $ENV file and importing of shell
functions. Turning this option off causes the effective uid and
gid to be set to the real uid and gid.
gid to be set to the real uid and gid.
-t Exit after reading and executing one command.
-u Treat unset variables as an error when substituting.
-v Print shell input lines as they are read.
-x Print commands and their arguments as they are executed.
-l Save and restore the binding of the NAME in a FOR command.
-d Disable the hashing of commands that are looked up for execution.
Normally, commands are remembered in a hash table, and once
found, do not have to be looked up again.
#if defined (BRACE_EXPANSION)
-B the shell will perform brace expansion
#endif /* BRACE_EXPANSION */
#if defined (BANG_HISTORY)
-H Enable ! style history substitution. This flag is on
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.
$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
option letter. */
struct {
@ -117,201 +147,354 @@ struct {
int letter;
} o_options[] = {
{ "allexport", 'a' },
#if defined (BRACE_EXPANSION)
{ "braceexpand",'B' },
#endif
{ "errexit", 'e' },
{ "hashall", 'h' },
#if defined (BANG_HISTORY)
{ "histexpand", 'H' },
#endif /* BANG_HISTORY */
{ "keyword", 'k' },
{ "monitor", 'm' },
{ "noclobber", 'C' },
{ "noexec", 'n' },
{ "noglob", 'f' },
{ "nohash", 'd' },
#if defined (JOB_CONTROL)
{ "notify", 'b' },
#endif /* JOB_CONTROL */
{"nounset", 'u' },
{"physical", 'P' },
{"privileged", 'p' },
{"verbose", 'v' },
{"xtrace", 'x' },
{(char *)NULL, 0},
{ "nounset", 'u' },
{ "onecmd", 't' },
{ "physical", 'P' },
{ "privileged", 'p' },
{ "verbose", 'v' },
{ "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"
void
list_minus_o_opts ()
list_minus_o_opts (mode)
int mode;
{
register int i;
char *on = "on", *off = "off";
int *on_or_off, value;
printf (MINUS_O_FORMAT, "braceexpand", (no_brace_expansion == 0) ? on : off);
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)
for (value = i = 0; o_options[i].name; i++)
{
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);
if (on_or_off == FLAG_UNKNOWN)
on_or_off = &zero;
printf (MINUS_O_FORMAT, o_options[i].name, (*on_or_off == 1) ? on : off);
on_or_off = &value;
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);
}
}
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;
char *option_name;
{
ignoreeof = on_or_off == FLAG_ON;
unbind_variable ("ignoreeof");
if (ignoreeof)
bind_variable ("IGNOREEOF", "10");
else
unbind_variable ("IGNOREEOF");
sv_ignoreeof ("IGNOREEOF");
return 0;
}
#if defined (READLINE)
/* 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)
{
rl_variable_bind ("editing-mode", option_name);
if (interactive)
with_input_from_stdin ();
no_line_editing = 0;
}
else
{
isemacs = rl_editing_mode == 1;
if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
{
if (interactive)
with_input_from_stream (stdin, "stdin");
no_line_editing = 1;
}
}
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 */
#if defined (HISTORY)
static int
bash_set_history (on_or_off, option_name)
int on_or_off;
char *option_name;
{
if (on_or_off == FLAG_ON)
{
bash_history_enable ();
if (history_lines_this_session == 0)
load_history ();
}
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 = -1;
int option_char;
VFunction *set_func;
register int i;
if (STREQ (option_name, "braceexpand"))
for (i = 0; binary_o_options[i].name; i++)
{
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");
if (on_or_off == FLAG_ON)
bind_variable ("IGNOREEOF", "10");
stupidly_hack_special_variables ("IGNOREEOF");
}
#if defined (READLINE)
else if ((STREQ (option_name, "emacs")) || (STREQ (option_name, "vi")))
{
if (on_or_off == FLAG_ON)
if (STREQ (option_name, binary_o_options[i].name))
{
rl_variable_bind ("editing-mode", option_name);
SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
return (EXECUTION_SUCCESS);
}
}
if (interactive)
with_input_from_stdin ();
no_line_editing = 0;
}
else
{
int isemacs = (rl_editing_mode == 1);
if ((isemacs && STREQ (option_name, "emacs")) ||
(!isemacs && STREQ (option_name, "vi")))
{
if (interactive)
with_input_from_stream (stdin, "stdin");
no_line_editing = 1;
}
else
builtin_error ("not in %s editing mode", option_name);
}
}
#endif /* READLINE */
else if (STREQ (option_name, "interactive-comments"))
interactive_comments = (on_or_off == FLAG_ON);
else if (STREQ (option_name, "posix"))
for (i = 0, option_char = -1, set_func = 0; o_options[i].name; i++)
{
posixly_correct = (on_or_off == FLAG_ON);
unbind_variable ("POSIXLY_CORRECT");
unbind_variable ("POSIX_PEDANTIC");
if (on_or_off == FLAG_ON)
{
bind_variable ("POSIXLY_CORRECT", "");
stupidly_hack_special_variables ("POSIXLY_CORRECT");
}
if (STREQ (option_name, o_options[i].name))
{
option_char = o_options[i].letter;
break;
}
}
else
if (option_char == -1)
{
register int i;
for (i = 0; o_options[i].name; i++)
{
if (STREQ (option_name, o_options[i].name))
{
option_char = o_options[i].letter;
break;
}
}
if (option_char == -1)
{
builtin_error ("%s: unknown option name", option_name);
return (EXECUTION_FAILURE);
}
if (change_flag (option_char, on_or_off) == FLAG_ERROR)
{
bad_option (option_name);
return (EXECUTION_FAILURE);
}
builtin_error ("%s: unknown option name", option_name);
return (EXECUTION_FAILURE);
}
if (change_flag (option_char, on_or_off) == FLAG_ERROR)
{
bad_option (option_name);
return (EXECUTION_FAILURE);
}
return (EXECUTION_SUCCESS);
}
static void
print_all_shell_variables ()
{
SHELL_VAR **vars;
vars = all_shell_variables ();
if (vars)
{
print_var_list (vars);
free (vars);
}
vars = all_shell_functions ();
if (vars)
{
print_var_list (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 = 0;
int on_or_off, flag_name, force_assignment, opts_changed;
WORD_LIST *l;
register char *arg;
if (!list)
if (list == 0)
{
SHELL_VAR **vars;
vars = all_shell_variables ();
if (vars)
{
print_var_list (vars);
free (vars);
}
vars = all_shell_functions ();
if (vars)
{
print_var_list (vars);
free (vars);
}
print_all_shell_variables ();
return (EXECUTION_SUCCESS);
}
/* Check validity of flag arguments. */
if (*list->word->word == '-' || *list->word->word == '+')
{
register char *arg;
WORD_LIST *save_list = list;
while (list && (arg = list->word->word))
for (l = list; l && (arg = l->word->word); l = l->next)
{
char c;
@ -319,8 +502,7 @@ set_builtin (list)
break;
/* `-' or `--' signifies end of flag arguments. */
if (arg[0] == '-' &&
(!arg[1] || (arg[1] == '-' && !arg[2])))
if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
break;
while (c = *++arg)
@ -331,30 +513,28 @@ set_builtin (list)
s[0] = c; s[1] = '\0';
bad_option (s);
if (c == '?')
printf ("usage: %s\n", USAGE_STRING);
builtin_usage ();
return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
}
list = list->next;
}
list = save_list;
}
/* Do the set command. While the list consists of words starting with
'-' or '+' treat them as flags, otherwise, start assigning them to
$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
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;
/* `set --' unsets the positional parameters. */
if (string[1] == '-')
if (arg[1] == '-')
force_assignment = 1;
/* Until told differently, the old shell behaviour of
@ -364,20 +544,19 @@ set_builtin (list)
{
change_flag ('x', '+');
change_flag ('v', '+');
opts_changed = 1;
}
break;
}
if ((on_or_off = *string) &&
(on_or_off == '-' || on_or_off == '+'))
if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
{
int i = 1;
while (flag_name = string[i++])
while (flag_name = *++arg)
{
if (flag_name == '?')
{
printf ("usage: %s\n", USAGE_STRING);
builtin_usage ();
return (EXECUTION_SUCCESS);
}
else if (flag_name == 'o') /* -+o option-name */
@ -387,36 +566,47 @@ set_builtin (list)
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;
}
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;
}
list = list->next; /* Skip over option name. */
opts_changed = 1;
if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
return (EXECUTION_FAILURE);
}
else
{
if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
{
char opt[3];
opt[0] = on_or_off;
opt[1] = flag_name;
opt[2] = '\0';
bad_option (opt);
set_shellopts ();
return (EXECUTION_FAILURE);
}
}
else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
{
char opt[3];
opt[0] = on_or_off;
opt[1] = flag_name;
opt[2] = '\0';
bad_option (opt);
builtin_usage ();
set_shellopts ();
return (EXECUTION_FAILURE);
}
opts_changed = 1;
}
}
else
@ -429,6 +619,9 @@ set_builtin (list)
/* Assigning $1 ... $n */
if (list || force_assignment)
remember_args (list, 1);
/* Set up new value of $SHELLOPTS */
if (opts_changed)
set_shellopts ();
return (EXECUTION_SUCCESS);
}
@ -443,13 +636,17 @@ function. Some variables (such as PATH and IFS) cannot be unset; also
see readonly.
$END
#define NEXT_VARIABLE() any_failed++; list = list->next; continue;
int
unset_builtin (list)
WORD_LIST *list;
{
int unset_function = 0, unset_variable = 0, opt;
int any_failed = 0;
int unset_function, unset_variable, unset_array, opt, any_failed;
char *name;
unset_function = unset_variable = unset_array = any_failed = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "fv")) != -1)
{
@ -462,7 +659,8 @@ unset_builtin (list)
unset_variable = 1;
break;
default:
return (EXECUTION_FAILURE);
builtin_usage ();
return (EX_USAGE);
}
}
@ -476,53 +674,69 @@ unset_builtin (list)
while (list)
{
SHELL_VAR *var;
int tem;
#if defined (ARRAY_VARS)
char *t;
#endif
name = list->word->word;
if (!unset_function &&
find_name_in_list (name, non_unsettable_vars) > -1)
#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);
if (var && !unset_function && non_unsettable_p (var))
{
builtin_error ("%s: cannot unset", name);
any_failed++;
NEXT_VARIABLE ();
}
/* Posix.2 says that unsetting readonly variables is an error. */
if (var && readonly_p (var))
{
builtin_error ("%s: cannot unset: readonly %s",
name, unset_function ? "function" : "variable");
NEXT_VARIABLE ();
}
/* Unless the -f option is supplied, the name refers to a variable. */
#if defined (ARRAY_VARS)
if (var && unset_array)
{
if (array_p (var) == 0)
{
builtin_error ("%s: not an array variable", name);
NEXT_VARIABLE ();
}
else
tem = unbind_array_element (var, t);
}
else
{
SHELL_VAR *var;
int tem;
#endif /* ARRAY_VARS */
tem = makunbound (name, unset_function ? shell_functions : shell_variables);
var = unset_function ? find_function (name) : find_variable (name);
/* 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
that name does not exist, a function by that name, if any,
shall be unset.'' */
if (tem == -1 && !unset_function && !unset_variable)
tem = makunbound (name, shell_functions);
/* Posix.2 says that unsetting readonly variables is an error. */
if (var && readonly_p (var))
{
builtin_error ("%s: cannot unset: readonly %s",
name, unset_function ? "function" : "variable");
any_failed++;
list = list->next;
continue;
}
if (tem == -1)
any_failed++;
else if (!unset_function)
stupidly_hack_special_variables (name);
/* Unless the -f option is supplied, the name refers to a
variable. */
tem = makunbound
(name, unset_function ? shell_functions : shell_variables);
/* 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
that name does not exist, a function by that name, if any,
shall be unset.'' */
if ((tem == -1) && !unset_function && !unset_variable)
tem = makunbound (name, shell_functions);
if (tem == -1)
any_failed++;
else if (!unset_function)
stupidly_hack_special_variables (name);
}
list = list->next;
}
if (any_failed)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}

View file

@ -21,6 +21,15 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$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 "common.h"
#include "bashgetopt.h"
@ -30,7 +39,7 @@ extern char *this_command_name;
$BUILTIN export
$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
subsequently executed commands. If the -f option is given,
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
exported attribute from variables named in LIST. An argument of
-f indicates that the names present in LIST refer to functions. */
int
export_builtin (list)
register WORD_LIST *list;
{
return (set_or_show_attributes (list, att_exported));
return (set_or_show_attributes (list, att_exported, 0));
}
$BUILTIN readonly
$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
not be changed by subsequent assignment. If the -f option is given,
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
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.
$END
/* For each variable name in LIST, make that variable readonly. Given an
empty LIST, print out all existing readonly variables. */
int
readonly_builtin (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
ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
remaining names in LIST. */
int
set_or_show_attributes (list, attribute)
set_or_show_attributes (list, attribute, nodefs)
register WORD_LIST *list;
int attribute;
int attribute, nodefs;
{
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. */
reset_internal_getopt ();
while ((opt = internal_getopt (list, "nfp")) != -1)
while ((opt = internal_getopt (list, "anfp")) != -1)
{
switch (opt)
{
@ -94,10 +108,15 @@ set_or_show_attributes (list, attribute)
case 'f':
functions_only = 1;
break;
#if defined (ARRAY_VARS)
case 'a':
arrays_only = 1;
break;
#endif
case 'p':
break;
default:
builtin_error ("usage: %s [-nfp] [varname]", this_command_name);
builtin_usage ();
return (EX_USAGE);
}
}
@ -108,85 +127,56 @@ set_or_show_attributes (list, attribute)
if (attribute & att_exported)
array_needs_making = 1;
/* Cannot undo readonly status. */
/* Cannot undo readonly status, silently disallowed. */
if (undo && (attribute & att_readonly))
attribute &= ~att_readonly;
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);
if (!var)
if (var == 0)
{
builtin_error ("%s: not a function", name);
any_failed++;
}
else
{
if (undo)
var->attributes &= ~attribute;
else
var->attributes |= attribute;
}
SETVARATTR (var, attribute, undo);
list = list->next;
if (attribute == att_exported)
array_needs_making++;
continue;
}
/* xxx [-np] name[=value] */
assign = assignment (name);
if (assign)
name[assign] = '\0';
if (legal_identifier (name) == 0)
{
builtin_error ("%s: not a legal variable name", name);
any_failed++;
builtin_error ("`%s': not a valid identifier", name);
assign_error++;
list = list->next;
continue;
}
if (assign)
if (assign) /* xxx [-np] name=value */
{
name[assign] = '=';
/* This word has already been expanded once with command
and parameter expansion. Call do_assignment_no_expand (),
which does not do command or parameter substitution. */
do_assignment_no_expand (name);
which does not do command or parameter substitution. If
the assignment is not performed correctly, flag an error. */
if (do_assignment_no_expand (name) == 0)
assign_error++;
name[assign] = '\0';
}
if (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 */
set_var_attribute (name, attribute, undo);
list = list->next;
}
}
@ -204,50 +194,133 @@ set_or_show_attributes (list, attribute)
else
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)
{
for (i = 0; var = variable_list[i]; i++)
{
if ((var->attributes & attribute) && !invisible_p (var))
{
char flags[6];
flags[0] = '\0';
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));
}
}
}
#if defined (ARRAY_VARS)
if (arrays_only && array_p (var) == 0)
continue;
#endif
if ((var->attributes & attribute) && invisible_p (var) == 0)
show_var_attributes (var, nodefs);
}
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 */
}

View file

@ -21,13 +21,16 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES shift.c
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../shell.h"
#include "common.h"
$BUILTIN shift
$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.
$END
int print_shift_error;
/* 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
anything in it, it is a number which says where to start the
@ -44,34 +49,28 @@ int
shift_builtin (list)
WORD_LIST *list;
{
int times, number;
WORD_LIST *args;
int times;
register int count;
WORD_LIST *temp;
times = get_numeric_arg (list);
if (!times)
if (times == 0)
return (EXECUTION_SUCCESS);
if (times < 0)
else if (times < 0)
{
builtin_error ("shift count must be >= 0");
return (EXECUTION_FAILURE);
}
args = list_rest_of_args ();
number = list_length (args);
dispose_words (args);
if (times > number)
else if (times > number_of_args ())
{
builtin_error ("shift count must be <= $#");
if (print_shift_error)
builtin_error ("shift count must be <= $#");
return (EXECUTION_FAILURE);
}
while (times-- > 0)
{
register int count;
if (dollar_vars[1])
free (dollar_vars[1]);
@ -80,8 +79,7 @@ shift_builtin (list)
if (rest_of_args)
{
WORD_LIST *temp = rest_of_args;
temp = rest_of_args;
dollar_vars[9] = savestring (temp->word->word);
rest_of_args = rest_of_args->next;
temp->next = (WORD_LIST *)NULL;
@ -90,6 +88,5 @@ shift_builtin (list)
else
dollar_vars[9] = (char *)NULL;
}
return (EXECUTION_SUCCESS);
}

343
builtins/shopt.def Normal file
View 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);
}

View file

@ -36,34 +36,34 @@ in $PATH are used to find the directory containing FILENAME.
$END
/* 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 <errno.h>
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../shell.h"
#include "../posixstat.h"
#include "../filecntl.h"
#include "../execute_cmd.h"
#include "common.h"
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
#if !defined (errno)
extern int errno;
#endif /* !errno */
/* Variables used here but defined in other files. */
extern int return_catch_flag, return_catch_value;
extern jmp_buf return_catch;
extern int posixly_correct;
extern int interactive, interactive_shell, last_command_exit_value;
#if defined (RESTRICTED_SHELL)
extern int restricted;
#endif
/* How many `levels' of sourced files we have. */
int sourcelevel = 0;
/* If non-zero, `.' uses $PATH to look up the script to be sourced. */
int source_uses_path = 1;
/* 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
@ -86,101 +86,51 @@ maybe_pop_dollar_vars ()
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,
close the file, and then execute the string. */
int
source_builtin (list)
WORD_LIST *list;
{
int result, return_val;
int result;
char *filename;
/* Assume the best. */
result = EXECUTION_SUCCESS;
if (list)
{
char *string, *filename;
struct stat finfo;
int fd, tt;
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);
}
return (EXECUTION_FAILURE);
}
if (tt > 80)
tt = 80;
if (check_binary_file ((unsigned char *)string, tt))
{
free (string);
builtin_error ("%s: cannot execute binary file", filename);
free (filename);
return (EX_BINARY_FILE);
}
begin_unwind_frame ("File Sourcing");
if (list->next)
{
push_dollar_vars ();
add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
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 ();
return_catch_flag++;
return_val = setjmp (return_catch);
if (return_val)
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
if (list == 0)
{
builtin_error ("filename argument required");
result = EXECUTION_FAILURE;
builtin_usage ();
return (EX_USAGE);
}
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);
}
#endif
filename = (char *)NULL;
if (source_uses_path)
filename = find_path_file (list->word->word);
if (filename == 0)
filename = savestring (list->word->word);
begin_unwind_frame ("source");
add_unwind_protect ((Function *)xfree, filename);
if (list->next)
{
push_dollar_vars ();
add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
remember_args (list->next, 1);
}
set_dollar_vars_unchanged ();
result = source_file (filename);
run_unwind_frame ("source");
return (result);
}

View file

@ -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.
$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 "../shell.h"
#include "../jobs.h"
#include "common.h"
#include "bashgetopt.h"
#if defined (JOB_CONTROL)
extern int job_control;
static SigHandler *old_cont, *old_tstp;
static SigHandler *old_cont, *old_stop;
/* Continue handler. */
sighandler
@ -46,10 +54,10 @@ suspend_continue (sig)
int sig;
{
set_signal_handler (SIGCONT, old_cont);
set_signal_handler (SIGTSTP, old_tstp);
#if !defined (VOID_SIGHANDLER)
return (0);
#endif /* !VOID_SIGHANDLER */
#if 0
set_signal_handler (SIGSTOP, old_stop);
#endif
SIGRETURN (0);
}
/* Suspending the shell. If -f is the arg, then do the suspend
@ -58,28 +66,45 @@ int
suspend_builtin (list)
WORD_LIST *list;
{
if (!job_control)
int opt, force;
reset_internal_getopt ();
force = 0;
while ((opt = internal_getopt (list, "f")) != -1)
switch (opt)
{
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");
builtin_error ("cannot suspend a shell without job control");
return (EXECUTION_FAILURE);
}
if (list)
if (strcmp (list->word->word, "-f") == 0)
goto do_suspend;
no_args (list);
if (login_shell)
if (force == 0)
{
builtin_error ("Can't suspend a login shell");
return (EXECUTION_FAILURE);
no_args (list);
if (login_shell)
{
builtin_error ("cannot suspend a login shell");
return (EXECUTION_FAILURE);
}
}
do_suspend:
old_cont = (SigHandler *)set_signal_handler (SIGCONT, suspend_continue);
old_tstp = (SigHandler *)set_signal_handler (SIGTSTP, SIG_DFL);
killpg (shell_pgrp, SIGTSTP);
#if 0
old_stop = (SigHandler *)set_signal_handler (SIGSTOP, SIG_DFL);
#endif
killpg (shell_pgrp, SIGSTOP);
return (EXECUTION_SUCCESS);
}

View file

@ -37,12 +37,12 @@ File operators:
-e FILE True if file exists.
-f FILE True if file exists and is a regular file.
-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.
-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.
-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.
-t FD True if FD is opened on a terminal.
-u FILE True if the file is set-user-id.
@ -63,12 +63,16 @@ String operators:
-z STRING True if string is empty.
-n STRING
or STRING True if string is not empty.
STRING True if string is not empty.
STRING1 = STRING2
True if the strings are equal.
STRING1 != STRING2
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:
@ -88,18 +92,21 @@ $BUILTIN [
$DOCNAME test_bracket
$FUNCTION test_builtin
$SHORT_DOC [ arg... ]
This is a synonym for the "test" shell builtin, excepting that the
last argument must be literally `]', to match the `[' which invoked
the test.
This is a synonym for the "test" builtin, but the last
argument must be a literal `]', to match the opening `['.
$END
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../shell.h"
#include "common.h"
extern char *this_command_name;
/* TEST/[ builtin. */
@ -109,12 +116,11 @@ test_builtin (list)
{
char **argv;
int argc, result;
WORD_LIST *t = list;
/* We let Matthew Bradburn and Kevin Braunsdorf's code do the
actual test command. So turn the list of args into an array
of strings, since that is what his code wants. */
if (!list)
of strings, since that is what their code wants. */
if (list == 0)
{
if (this_command_name[0] == '[' && !this_command_name[1])
builtin_error ("missing `]'");
@ -122,23 +128,9 @@ test_builtin (list)
return (EXECUTION_FAILURE);
}
/* Get the length of the argument list. */
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);
argv = make_builtin_argv (list, &argc);
result = test_command (argc, argv);
free_array (argv);
free ((char *)argv);
return (result);
}

View file

@ -28,62 +28,79 @@ Print the accumulated user and system times for processes run from
the shell.
$END
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include "../bashtypes.h"
#include "../shell.h"
#include <sys/types.h>
#if defined (hpux) || defined (USGr4) || defined (XD88) || defined (USGr3)
# undef HAVE_RESOURCE
#endif /* hpux || USGr4 || XD88 || USGr3 */
#if defined (_POSIX_VERSION) || !defined (HAVE_RESOURCE)
# include <sys/times.h>
#else /* !_POSIX_VERSION && HAVE_RESOURCE */
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <sys/resource.h>
#endif /* !_POSIX_VERSION && HAVE_RESOURCE */
# include <time.h>
#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
information comes from variables in jobs.c used to keep
track of this stuff. */
#if defined (HAVE_SYS_TIMES_H)
# include <sys/times.h>
#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)
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;
getrusage (RUSAGE_SELF, &self);
getrusage (RUSAGE_CHILDREN, &kids); /* terminated child processes */
print_timeval (&self.ru_utime);
print_timeval (stdout, &self.ru_utime);
putchar (' ');
print_timeval (&self.ru_stime);
print_timeval (stdout, &self.ru_stime);
putchar ('\n');
print_timeval (&kids.ru_utime);
print_timeval (stdout, &kids.ru_utime);
putchar (' ');
print_timeval (&kids.ru_stime);
print_timeval (stdout, &kids.ru_stime);
putchar ('\n');
#else /* _POSIX_VERSION || !HAVE_RESOURCE || !RUSAGE_SELF */
# if !defined (BrainDeath)
struct tms t;
times (&t);
#else
# if defined (HAVE_TIMES)
/* 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.
This kind of stupid clock-dependent stuff is exactly the reason 4.2BSD
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 (' ');
print_time_in_hz (t.tms_stime);
print_time_in_hz (stdout, t.tms_stime);
putchar ('\n');
print_time_in_hz (t.tms_cutime);
print_time_in_hz (stdout, t.tms_cutime);
putchar (' ');
print_time_in_hz (t.tms_cstime);
print_time_in_hz (stdout, t.tms_cstime);
putchar ('\n');
# endif /* BrainDeath */
#endif /* _POSIX_VERSION || !HAVE_RESOURCE || !RUSAGE_SELF */
# else /* !HAVE_TIMES */
printf ("0.00 0.00\n0.00 0.00\n");
# endif /* HAVE_TIMES */
#endif /* !HAVE_TIMES */
return (EXECUTION_SUCCESS);
}

View file

@ -23,30 +23,46 @@ $PRODUCES trap.c
$BUILTIN trap
$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
signal(s) SIGNAL_SPEC. If ARG is absent all specified signals are
reset to their original values. If ARG is the null string this
signal is ignored by the shell and by the commands it invokes. 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
commands associated with each signal number. SIGNAL_SPEC is either
a signal name in <signal.h>, or a signal number. The syntax `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 $$".
reset to their original values. If ARG is the null string each
SIGNAL_SPEC is ignored by the shell and by the commands it invokes.
If SIGNAL_SPEC is EXIT (0) the command ARG is executed on exit from
the shell. If SIGNAL_SPEC is DEBUG, ARG is executed after every
command. If ARG is `-p' then the trap commands associated with
each SIGNAL_SPEC are displayed. If no arguments are supplied or if
only `-p' is given, trap prints the list of commands associated with
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
#include <sys/types.h>
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashtypes.h"
#include <signal.h>
#include <stdio.h>
#include "../bashansi.h"
#include "../shell.h"
#include "../trap.h"
#include "common.h"
#include "bashgetopt.h"
static int display_traps ();
/* The trap command:
trap <arg> <signal ...>
trap <signal ...>
trap -l
trap -p [sigspec ...]
trap [--]
Set things up so that ARG is executed when SIGNAL(s) N is recieved.
@ -62,60 +78,44 @@ $END
extern int interactive;
int
trap_builtin (list)
WORD_LIST *list;
{
register int i;
int list_signal_names = 0;
int list_signal_names, display, result, opt;
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 = list->next;
}
else if (ISOPTION (list->word->word, '-'))
{
list = list->next;
break;
}
else if ((*list->word->word == '-') && list->word->word[1])
{
bad_option (list->word->word);
builtin_error ("usage: trap [-l] [arg] [sigspec]");
case 'p':
display++;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
else
break;
}
list = loptend;
if (list_signal_names)
return (display_signal_list ((WORD_LIST *)NULL, 1));
else if (display || list == 0)
return (display_traps (list));
else
{
int column = 0;
char *first_arg;
int operation, sig;
for (i = 0; i < NSIG; i++)
{
printf ("%2d) %s", i, signal_name (i));
if (++column < 4)
printf ("\t");
else
{
printf ("\n");
column = 0;
}
}
if (column != 0)
printf ("\n");
return (EXECUTION_SUCCESS);
}
if (list)
{
char *first_arg = list->word->word;
int operation = SET, any_failed = 0;
if (signal_object_p (first_arg))
operation = SET;
first_arg = list->word->word;
if (first_arg && *first_arg && signal_object_p (first_arg))
operation = REVERT;
else
{
@ -128,15 +128,13 @@ trap_builtin (list)
while (list)
{
int sig;
sig = decode_signal (list->word->word);
if (sig == NO_SIG)
{
builtin_error ("%s: not a signal specification",
list->word->word);
any_failed++;
result = EXECUTION_FAILURE;
}
else
{
@ -183,22 +181,52 @@ trap_builtin (list)
}
list = list->next;
}
return ((!any_failed) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
for (i = 0; i < NSIG; i++)
{
char *t, *p;
p = trap_list[i];
if (p == (char *)DEFAULT_SIG)
continue;
t = (p == (char *)IGNORE_SIG) ? (char *)NULL : single_quote (p);
printf ("trap -- %s %s\n", t ? t : "''", signal_name (i));
if (t)
free (t);
}
return (EXECUTION_SUCCESS);
return (result);
}
static void
showtrap (i)
int i;
{
char *t, *p;
p = trap_list[i];
if (p == (char *)DEFAULT_SIG)
return;
t = (p == (char *)IGNORE_SIG) ? (char *)NULL : single_quote (p);
printf ("trap -- %s %s\n", t ? t : "''", signal_name (i));
if (t)
free (t);
}
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);
}

View file

@ -23,26 +23,38 @@ $PRODUCES type.c
$BUILTIN type
$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
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, shell reserved word, shell function, shell builtin, disk file,
or unfound, respectively.
If the -path flag is used, either returns the name of the disk file
that would be exec'ed, or nothing if -type wouldn't return `file'.
If the -p flag is used, either returns the name of the disk 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
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
#include <stdio.h>
#include <sys/types.h>
#include <config.h>
#include "../bashtypes.h"
#include "../posixstat.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include "../bashansi.h"
#include "../shell.h"
#include "../execute_cmd.h"
@ -52,7 +64,7 @@ $END
#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
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
file
*/
int
type_builtin (list)
WORD_LIST *list;
{
int path_only, type_only, all, verbose;
int successful_finds;
if (list == 0)
return (EXECUTION_SUCCESS);
path_only = type_only = all = 0;
successful_finds = 0;
if (!list)
return (EXECUTION_SUCCESS);
while (list && *(list->word->word) == '-')
{
char *flag = &(list->word->word[1]);
@ -108,7 +121,7 @@ type_builtin (list)
else
{
bad_option (flag);
builtin_error ("usage: type [-all | -path | -type ] name [name ...]");
builtin_usage ();
return (EX_USAGE);
}
list = list->next;
@ -116,7 +129,7 @@ type_builtin (list)
if (type_only)
verbose = 1;
else if (!path_only)
else if (path_only == 0)
verbose = 2;
else if (path_only)
verbose = 3;
@ -156,22 +169,29 @@ type_builtin (list)
* ALL says whether or not to look for all occurrences of COMMAND, or
* return after finding it once.
*/
int
describe_command (command, verbose, all)
char *command;
int verbose, all;
{
int found = 0, i, found_file = 0;
char *full_path = (char *)NULL;
int found, i, found_file;
char *full_path;
SHELL_VAR *func;
#if defined (ALIAS)
alias_t *alias;
#endif
found = found_file = 0;
full_path = (char *)NULL;
#if defined (ALIAS)
/* Command is an alias? */
ASSOC *alias = find_alias (command);
alias = find_alias (command);
if (alias)
{
if (verbose == 1)
printf ("alias\n");
puts ("alias");
else if (verbose == 2)
printf ("%s is aliased to `%s'\n", command, alias->value);
else if (verbose == 4)
@ -193,7 +213,7 @@ describe_command (command, verbose, all)
if (i >= 0)
{
if (verbose == 1)
printf ("keyword\n");
puts ("keyword");
else if (verbose == 2)
printf ("%s is a shell keyword\n", command);
else if (verbose == 4)
@ -211,7 +231,7 @@ describe_command (command, verbose, all)
if (func)
{
if (verbose == 1)
printf ("function\n");
puts ("function");
else if (verbose == 2)
{
#define PRETTY_PRINT_FUNC 1
@ -240,7 +260,7 @@ describe_command (command, verbose, all)
if (find_shell_builtin (command))
{
if (verbose == 1)
printf ("builtin\n");
puts ("builtin");
else if (verbose == 2)
printf ("%s is a shell builtin\n", command);
else if (verbose == 4)
@ -261,7 +281,7 @@ describe_command (command, verbose, all)
if (f & FS_EXECABLE)
{
if (verbose == 1)
printf ("file\n");
puts ("file");
else if (verbose == 2)
printf ("%s is %s\n", command, command);
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 (verbose == 1)
printf ("file\n");
puts ("file");
else if (verbose == 2)
printf ("%s is hashed (%s)\n", command, full_path);
else if (verbose == 3 || verbose == 4)
@ -308,7 +328,7 @@ describe_command (command, verbose, all)
found = 1;
if (verbose == 1)
printf ("file\n");
puts ("file");
else if (verbose == 2)
printf ("%s is %s\n", command, full_path);
else if (verbose == 3 || verbose == 4)

File diff suppressed because it is too large Load diff

View file

@ -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).
$END
#include <stdio.h>
#include <sys/types.h>
#include <config.h>
#include "../bashtypes.h"
#include "../filecntl.h"
#include <sys/file.h>
#if defined (HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <stdio.h>
#include "../shell.h"
#include "../posixstat.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
of -S means display the umask in a symbolic mode. */
int
umask_builtin (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++;
continue;
}
else if (ISOPTION (list->word->word, '-'))
{
list = list->next;
break;
}
else if (*(list->word->word) == '-')
{
bad_option (list->word->word);
builtin_error ("usage: umask [-S] [mode]");
default:
builtin_usage ();
return (EX_USAGE);
}
else
break;
}
list = loptend;
if (list)
{
int new_umask;
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
by specifying a number out of range. This is a problem
with those shells. We don't change the umask if the input
is lousy. */
if (new_umask == -1)
if (umask_value == -1)
{
builtin_error ("`%s' is not an octal number from 000 to 777",
list->word->word);
@ -98,26 +101,25 @@ umask_builtin (list)
}
else
{
new_umask = symbolic_umask (list);
if (new_umask == -1)
umask_value = symbolic_umask (list);
if (umask_value == -1)
return (EXECUTION_FAILURE);
}
umask (new_umask);
umask (umask_value);
if (print_symbolically)
print_symbolic_umask (new_umask);
print_symbolic_umask (umask_value);
}
else /* Display the UMASK for this user. */
{
int old_umask;
old_umask = umask (022);
umask (old_umask);
umask_value = umask (022);
umask (umask_value);
if (print_symbolically)
print_symbolic_umask (old_umask);
print_symbolic_umask (umask_value);
else
printf ("%03o\n", old_umask);
printf ("%03o\n", umask_value);
}
fflush (stdout);
return (EXECUTION_SUCCESS);
}
@ -176,7 +178,7 @@ symbolic_umask (list)
um = umask (022);
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
again before being returned. */
umc = ~um;
@ -266,7 +268,7 @@ symbolic_umask (list)
break;
default:
builtin_error ("bad operation character: %c", op);
builtin_error ("bad symbolic mode operator: %c", op);
return (-1);
}

View file

@ -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
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$BUILTIN wait
$FUNCTION wait_builtin
$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.
$END
#include <sys/types.h>
#include <config.h>
#include "../bashtypes.h"
#include <signal.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../shell.h"
#include "../jobs.h"
#include "common.h"
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
0. If a list of pids or job specs are given, return the exit status of
the last one waited for. */
#define WAIT_RETURN(s) do { run_unwind_frame ("wait_builtin"); return (s); } while (0)
int
wait_builtin (list)
WORD_LIST *list;
{
int status = EXECUTION_SUCCESS;
int status;
if (no_options (list))
return (EX_USAGE);
begin_unwind_frame ("wait_builtin");
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
currently active background processes. */
if (!list)
if (list == 0)
{
wait_for_background_pids ();
status = EXECUTION_SUCCESS;
goto return_status;
WAIT_RETURN (EXECUTION_SUCCESS);
}
status = EXECUTION_SUCCESS;
while (list)
{
pid_t pid;
@ -89,9 +103,8 @@ wait_builtin (list)
}
else
{
builtin_error ("`%s' is not a pid or legal job spec", w);
status = EXECUTION_FAILURE;
goto return_status;
builtin_error ("`%s' is not a pid or valid job spec", w);
WAIT_RETURN (EXECUTION_FAILURE);
}
}
#if defined (JOB_CONTROL)
@ -107,7 +120,7 @@ wait_builtin (list)
if (job < 0 || job >= job_slots || !jobs[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);
status = 127; /* As per Posix.2, section 4.70.2 */
list = list->next;
@ -121,12 +134,11 @@ wait_builtin (list)
#endif /* JOB_CONTROL */
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;
}
list = list->next;
}
return_status:
run_unwind_frame ("wait_builtin");
return (status);
WAIT_RETURN (status);
}

View file

@ -19,8 +19,8 @@
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (_COMMAND_H)
#define _COMMAND_H
#if !defined (_COMMAND_H_)
#define _COMMAND_H_
#include "stdc.h"
@ -33,18 +33,45 @@ enum r_instruction {
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: */
enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
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. */
typedef struct word_desc {
char *word; /* Zero terminated string. */
int dollar_present; /* Non-zero means dollar sign present. */
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. */
int flags; /* Flags associated with this word. */
} WORD_DESC;
/* A linked list of words. */
@ -92,6 +119,8 @@ typedef struct element {
#define CMD_NO_FUNCTIONS 0x10 /* Ignore functions during command lookup. */
#define CMD_INHIBIT_EXPANSION 0x20 /* Do not expand the command words. */
#define CMD_NO_FORK 0x40 /* Don't fork; just call execve */
#define CMD_TIME_PIPELINE 0x80 /* Time a pipeline */
#define CMD_TIME_POSIX 0x100 /* time -p; use POSIX.2 time output spec. */
/* What a command looks like. */
typedef struct command {
@ -184,19 +213,16 @@ typedef struct simple_com {
int line; /* line number the command starts on */
} SIMPLE_COM;
/* The "function_def" command. This isn't really a command, but it is
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. */
/* The "function definition" command. */
typedef struct function_def {
int ignore; /* See description of CMD flags. */
WORD_DESC *name; /* The name of the function. */
COMMAND *command; /* The parsed execution tree. */
int line; /* Line number the function def starts on. */
} FUNCTION_DEF;
/* A command that is `grouped' allows pipes to take effect over
the entire command structure. */
/* A command that is `grouped' allows pipes and redirections to affect all
commands in the group. */
typedef struct group_com {
int ignore; /* See description of CMD flags. */
COMMAND *command;
@ -212,4 +238,4 @@ extern REDIRECT *copy_redirect __P((REDIRECT *));
extern REDIRECT *copy_redirects __P((REDIRECT *));
extern COMMAND *copy_command __P((COMMAND *));
#endif /* _COMMAND_H */
#endif /* _COMMAND_H_ */

186
config.h
View file

@ -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
View 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
View 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_ */

View file

@ -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
View 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" */

6273
configure vendored

File diff suppressed because it is too large Load diff

462
configure.in Normal file
View 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
])

View file

@ -20,8 +20,14 @@
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"
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
@ -34,27 +40,28 @@ WORD_DESC *
copy_word (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));
new_word->word = savestring (word->word);
return (new_word);
}
/* Copy the chain of words in LIST. Return a pointer to
/* Copy the chain of words in LIST. Return a pointer to
the new chain. */
WORD_LIST *
copy_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;
new_list = temp;
new_list->word = copy_word (list->word);
list = list->next;
}
return (REVERSE_LIST (new_list, WORD_LIST *));
}
@ -63,7 +70,9 @@ static PATTERN_LIST *
copy_case_clause (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->action = copy_command (clause->action);
return (new_clause);
@ -73,14 +82,13 @@ static PATTERN_LIST *
copy_case_clauses (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_list = new_clause;
clauses = clauses->next;
}
return (REVERSE_LIST (new_list, PATTERN_LIST *));
}
@ -90,14 +98,16 @@ REDIRECT *
copy_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)));
switch (redirect->instruction)
{
case r_reading_until:
case r_deblank_reading_until:
new_redirect->here_doc_eof = savestring (redirect->here_doc_eof);
/* There is NO BREAK HERE ON PURPOSE!!!! */
/*FALLTHROUGH*/
case r_appending_to:
case r_output_direction:
case r_input_direction:
@ -107,34 +117,34 @@ copy_redirect (redirect)
case r_output_force:
case r_duplicating_input_word:
case r_duplicating_output_word:
new_redirect->redirectee.filename =
copy_word (redirect->redirectee.filename);
new_redirect->redirectee.filename = copy_word (redirect->redirectee.filename);
break;
}
return (new_redirect);
}
REDIRECT *
copy_redirects (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;
new_list = temp;
list = list->next;
}
return (REVERSE_LIST (new_list, REDIRECT *));
}
static FOR_COM *
copy_for_command (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->name = copy_word (com->name);
new_for->map_list = copy_word_list (com->map_list);
@ -142,26 +152,13 @@ copy_for_command (com)
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 *
copy_group_command (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);
return (new_group);
}
@ -170,8 +167,9 @@ static CASE_COM *
copy_case_command (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->word = copy_word (com->word);
new_case->clauses = copy_case_clauses (com->clauses);
@ -182,8 +180,9 @@ static WHILE_COM *
copy_while_command (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->test = copy_command (com->test);
new_while->action = copy_command (com->action);
@ -194,8 +193,9 @@ static IF_COM *
copy_if_command (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->test = copy_command (com->test);
new_if->true_case = copy_command (com->true_case);
@ -220,8 +220,9 @@ static FUNCTION_DEF *
copy_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->command = copy_command (com->command);
return (new_def);
@ -234,72 +235,68 @@ COMMAND *
copy_command (command)
COMMAND *command;
{
COMMAND *new_command = (COMMAND *)NULL;
COMMAND *new_command;
if (command)
if (command == NULL)
return (command);
new_command = (COMMAND *)xmalloc (sizeof (COMMAND));
FASTCOPY ((char *)command, (char *)new_command, sizeof (COMMAND));
new_command->flags = command->flags;
new_command->line = command->line;
if (command->redirects)
new_command->redirects = copy_redirects (command->redirects);
switch (command->type)
{
new_command = (COMMAND *)xmalloc (sizeof (COMMAND));
FASTCOPY ((char *)command, (char *)new_command, sizeof (COMMAND));
new_command->flags = command->flags;
new_command->line = command->line;
if (command->redirects)
new_command->redirects = copy_redirects (command->redirects);
switch (command->type)
{
case cm_for:
new_command->value.For = copy_for_command (command->value.For);
break;
case cm_for:
new_command->value.For = copy_for_command (command->value.For);
break;
#if defined (SELECT_COMMAND)
case cm_select:
new_command->value.Select = copy_select_command (command->value.Select);
break;
case cm_select:
new_command->value.Select =
(SELECT_COM *)copy_for_command ((FOR_COM *)command->value.Select);
break;
#endif
case cm_group:
new_command->value.Group = copy_group_command (command->value.Group);
break;
case cm_group:
new_command->value.Group = copy_group_command (command->value.Group);
break;
case cm_case:
new_command->value.Case = copy_case_command (command->value.Case);
break;
case cm_until:
case cm_while:
new_command->value.While = copy_while_command (command->value.While);
break;
case cm_if:
new_command->value.If = copy_if_command (command->value.If);
break;
case cm_simple:
new_command->value.Simple = copy_simple_command (command->value.Simple);
break;
case cm_connection:
{
CONNECTION *new_connection;
case cm_case:
new_command->value.Case = copy_case_command (command->value.Case);
break;
new_connection = (CONNECTION *)xmalloc (sizeof (CONNECTION));
new_connection->connector = command->value.Connection->connector;
new_connection->first =
copy_command (command->value.Connection->first);
new_connection->second =
copy_command (command->value.Connection->second);
new_command->value.Connection = new_connection;
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:
new_command->value.Function_def =
copy_function_def (command->value.Function_def);
case cm_until:
case cm_while:
new_command->value.While = copy_while_command (command->value.While);
break;
case cm_if:
new_command->value.If = copy_if_command (command->value.If);
break;
case cm_simple:
new_command->value.Simple = copy_simple_command (command->value.Simple);
break;
case cm_connection:
{
CONNECTION *new_connection;
new_connection = (CONNECTION *)xmalloc (sizeof (CONNECTION));
new_connection->connector = command->value.Connection->connector;
new_connection->first = copy_command (command->value.Connection->first);
new_connection->second = copy_command (command->value.Connection->second);
new_command->value.Connection = new_connection;
break;
}
case cm_function_def:
new_command->value.Function_def = copy_function_def (command->value.Function_def);
break;
}
return (new_command);
}

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,13 @@
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 "bashansi.h"
#include "shell.h"
/* Dispose of the command structure passed. */
@ -25,7 +32,8 @@ void
dispose_command (command)
COMMAND *command;
{
if (!command) return;
if (command == 0)
return;
if (command->redirects)
dispose_redirects (command->redirects);
@ -33,8 +41,17 @@ dispose_command (command)
switch (command->type)
{
case cm_for:
#if defined (SELECT_COMMAND)
case cm_select:
#endif
{
register FOR_COM *c = command->value.For;
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_words (c->map_list);
dispose_command (c->action);
@ -42,18 +59,6 @@ dispose_command (command)
break;
}
#if defined (SELECT_COMMAND)
case cm_select:
{
register SELECT_COM *c = command->value.Select;
dispose_word (c->name);
dispose_words (c->map_list);
dispose_command (c->action);
free (c);
break;
}
#endif
case cm_group:
{
dispose_command (command->value.Group->command);
@ -63,12 +68,13 @@ dispose_command (command)
case cm_case:
{
register CASE_COM *c = command->value.Case;
PATTERN_LIST *t, *p = c->clauses;
register CASE_COM *c;
PATTERN_LIST *t, *p;
c = command->value.Case;
dispose_word (c->word);
while (p)
for (p = c->clauses; p; )
{
dispose_words (p->patterns);
dispose_command (p->action);
@ -83,8 +89,9 @@ dispose_command (command)
case cm_until:
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->action);
free (c);
@ -93,7 +100,9 @@ dispose_command (command)
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->true_case);
dispose_command (c->false_case);
@ -103,7 +112,9 @@ dispose_command (command)
case cm_simple:
{
register SIMPLE_COM *c = command->value.Simple;
register SIMPLE_COM *c;
c = command->value.Simple;
dispose_words (c->words);
dispose_redirects (c->redirects);
free (c);
@ -112,7 +123,9 @@ dispose_command (command)
case cm_connection:
{
register CONNECTION *c = command->value.Connection;
register CONNECTION *c;
c = command->value.Connection;
dispose_command (c->first);
dispose_command (c->second);
free (c);
@ -121,7 +134,9 @@ dispose_command (command)
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_command (c->command);
free (c);
@ -129,7 +144,7 @@ dispose_command (command)
}
default:
report_error ("Attempt to free unknown command type `%d'.\n", command->type);
programming_error ("dispose_command: bad command type `%d'", command->type);
break;
}
free (command);
@ -140,8 +155,7 @@ void
dispose_word (word)
WORD_DESC *word;
{
if (word->word)
free (word->word);
FREE (word->word);
free (word);
}
@ -151,6 +165,7 @@ dispose_words (list)
WORD_LIST *list;
{
WORD_LIST *t;
while (list)
{
t = list;
@ -189,7 +204,7 @@ dispose_redirects (list)
case r_reading_until:
case r_deblank_reading_until:
free (t->here_doc_eof);
/* ... */
/*FALLTHROUGH*/
case r_output_direction:
case r_input_direction:
case r_inputa_direction:
@ -200,6 +215,8 @@ dispose_redirects (list)
case r_duplicating_input_word:
case r_duplicating_output_word:
dispose_word (t->redirectee.filename);
/* FALLTHROUGH */
default:
break;
}
free (t);

1098
doc/FAQ Normal file

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more