Bash-5.3-beta release

This commit is contained in:
Chet Ramey
2024-12-17 09:51:38 -05:00
parent aadb6ffb93
commit f223b24c4b
319 changed files with 57094 additions and 42486 deletions
+78 -1
View File
@@ -14,11 +14,14 @@
*.dSYM
.build
.made
.*~
config.h
buildconf.h
config.status
config.cache
config.log
configure~
autom4te.cache
@@ -40,6 +43,7 @@ builtins/psize.aux
doc/Makefile
examples/loadables/Makefile
examples/loadables/Makefile.inc
examples/loadables/Makefile.sample
examples/loadables/perl/Makefile
lib/glob/Makefile
lib/intl/Makefile
@@ -59,7 +63,6 @@ lib/intl/ref-del.sed
po/Makefile
po/Makefile.in
po/POTFILES
po/stamp-po
support/bash.pc
support/man2html
@@ -85,31 +88,105 @@ tests/recho
tests/xcase
tests/zecho
# doc files created as part of making dvi versions from texinfo source
doc/bashref.aux
doc/bashref.bt
doc/bashref.bts
doc/bashref.cp
doc/bashref.cps
doc/bashref.fn
doc/bashref.fns
doc/bashref.ky
doc/bashref.pg
doc/bashref.rw
doc/bashref.rws
doc/bashref.toc
doc/bashref.tp
doc/bashref.vr
doc/bashref.vrs
lib/readline/doc/history.aux
lib/readline/doc/history.bt
lib/readline/doc/history.cp
lib/readline/doc/history.cps
lib/readline/doc/history.fn
lib/readline/doc/history.fns
lib/readline/doc/history.ky
lib/readline/doc/history.log
lib/readline/doc/history.pg
lib/readline/doc/history.toc
lib/readline/doc/history.tp
lib/readline/doc/history.vr
lib/readline/doc/history.vrs
lib/readline/doc/rlman.aux
lib/readline/doc/rlman.bt
lib/readline/doc/rlman.cp
lib/readline/doc/rlman.cps
lib/readline/doc/rlman.fn
lib/readline/doc/rlman.fns
lib/readline/doc/rlman.ky
lib/readline/doc/rlman.log
lib/readline/doc/rlman.pg
lib/readline/doc/rlman.toc
lib/readline/doc/rlman.tp
lib/readline/doc/rlman.vr
lib/readline/doc/rlman.vrs
lib/readline/doc/rluserman.aux
lib/readline/doc/rluserman.bt
lib/readline/doc/rluserman.cp
lib/readline/doc/rluserman.cps
lib/readline/doc/rluserman.fn
lib/readline/doc/rluserman.fns
lib/readline/doc/rluserman.ky
lib/readline/doc/rluserman.log
lib/readline/doc/rluserman.pg
lib/readline/doc/rluserman.toc
lib/readline/doc/rluserman.tp
lib/readline/doc/rluserman.vr
lib/readline/doc/rluserman.vrs
doc/oldbash.texi
doc/newbash.texi
# example loadable builtins
examples/loadables/accept
examples/loadables/asort
examples/loadables/basename
examples/loadables/cat
examples/loadables/csv
examples/loadables/cut
examples/loadables/dirname
examples/loadables/dsv
examples/loadables/fdflags
examples/loadables/finfo
examples/loadables/getconf
examples/loadables/head
examples/loadables/hello
examples/loadables/id
examples/loadables/kv
examples/loadables/ln
examples/loadables/logname
examples/loadables/mkdir
examples/loadables/mkfifo
examples/loadables/mktemp
examples/loadables/mypid
examples/loadables/necho
examples/loadables/pathchk
examples/loadables/print
examples/loadables/printenv
examples/loadables/push
examples/loadables/pushd
examples/loadables/pushd.c
examples/loadables/realpath
examples/loadables/rm
examples/loadables/rmdir
examples/loadables/seq
examples/loadables/setpgid
examples/loadables/sleep
examples/loadables/stat
examples/loadables/strftime
examples/loadables/strptime
examples/loadables/sync
examples/loadables/tee
examples/loadables/truefalse
+183
View File
@@ -1,3 +1,186 @@
This document details the changes between this version, bash-5.3-beta, and
the previous version, bash-5.3-alpha.
1. Changes to Bash
a. Per POSIX, a null pathname argument to `cd' is now an error.
b. Fixes for command completion when the directory portion of the pathname
contains characters that require quoting.
c. Fix to prevent redirections from undergoing word expansion twice.
d. Fix for rare parsing issue with for loops where a newline appears before
`in'.
e. The bash build process now assumes a C90 compilation environment and a
POSIX.1-1990 execution environment.
f. Fixed a bug where bash's internal redirection flags could collide with
the system's open/fcntl flags.
g. Fixed a problem with `jobs' run from a trap or `bind -x' command printing
the status of terminated foreground jobs.
h. Bash works around a macOS gettext bug with translating the `command not
found' message by caching the translated string.
i. Bash does not try to set the tty state after a process finishes if it is
running a trap, running a readline key binding (bind -x), or executing a
programmable completion.
j. Restricted shells are not allowed to run `enable -f', even when it's
shorthand from `enable f'.
k. Work around an android problem with file descriptors if the read builtin
gets both -u and -e.
l. Fixed some small memory leaks in bash completion and command parsing and
execution.
m. Fix for crash when timed commands jump back to the top level after SIGINT.
n. Minor fixes for command substitution parsing in the foreground.
o. Fix to reset read builtin buffer after SIGINT.
p. Fix for inconsistency between arrays and scalar variables when declaring
local variables and using values from previous variable contexts.
q. Bash doesn't try to give the terminal back to the original process group
after running a trap unless job control is enabled.
r. Fix to inhibit fork optimizations in functions that set a RETURN trap.
s. Fixes for parsing commands within process substitutions where they should
behave differently than command substitutions, including prohibiting the
special case for redirections that is only available for command
substitutions.
t. Restrict the effect of force_fignore to the cases where FIGNORE should
affect completions.
u. Fix for `read' builtin and invalid multibyte characters that contain the
delimiter character, so the delimiter acts as intended.
v. Fix for `read -e' so it restores the correct completion function if it's
interrupted.
w. Fix an off-by-one error when parsing an improperly-formed printf time
specification.
x. Fix for return status for commands whose return status is being inverted
when set -e is ignored.
y. Fix for checking `read' builtin timeouts after we check for having read
the delimiter.
z. Fixes for integer overflows and size_t variables.
aa. Fixes for the Makefiles to simplify, remove some unused variables, and
clean up what `git' sees after running the various clean targets.
bb. Fix for the `exec' builtin to avoid duplicate error messages.
cc. `printf' now warns if there are no valid characters at all in an integer
argument.
2. Changes to Readline
a. Make sure the bracketed-paste input buffer is null-terminated when read
returns an error.
b. Fixed a small memory leak in execute-named-command if the command doesn't
exist or the function doesn't return.
c. Fix for attempting to change case of invalid multibyte characters.
d. Fix for possible completions that compare identically when using case-
insensitive completion but have different byte lengths.
e. Fix to make non-incremental searches use undo lists and set the history
position the same way as incremental searches.
f. Don't check for signals when handling a received signal.
g. Fix off-by-one error when tokenizing words like $((expr)) while performing
history expansion.
h. Fixes for incremental searches and redisplay in the C locale.
i. Fixes for some use-after-free of the undo list errors when stacking multiple
commands that use rl_maybe_replace_line to save changes to a history entry.
j. Fixes to ensure that completion-prefix-display-length and
colored-completion-prefix are mutually exclusive.
3. New Features in Bash
a. MULTIPLE_COPROCS is now enabled by default.
b. The `bind' builtin interprets additional non-option arguments after -p or
-P as bindable command names and restricts output to the bindings for
those names.
c. Bash now uses the login shell for $BASH if the shell is named `su' or `-su'.
d. Bash now prints job notifications if an interactive shell is running a trap,
even though the shell is not interactive at that moment.
e. Programmable completion allows a new compspec loaded after a completion
function returns 124 to be used in more cases.
f. ./source has a new -p PATH option, which makes it use the PATH argument
instead of $PATH to look for the file.
g. GLOBSORT has a new `numeric' sort specifier, which sorts all-digit strings
as numbers.
h. Documentation has been significantly updated.
i. `wait -n' can now return terminated process substitutions, jobs about
which the user has already been notified (like `wait' without options),
j. `wait -n' removes jobs from the jobs table or list of terminated children
when in posix mode.
k. Changed the `wait' builtin behavior regarding process substitutions to
match the documentation.
l. There is a new `bash_source_fullpath' shopt option, which makes bash put
full pathnames into BASH_SOURCE, and a way to set a default value for it
at configure time.
m. Posix mode now forces job notifications to occur when the new edition of
POSIX specifes (since it now specifies them).
n. Interactive shells don't print job notifications while sourcing scripts.
o. The parser prints more information about the command it's trying to parse
when it encounters EOF before completing the command.
p. Posix mode no longer requires function names to be valid shell identifiers.
q. If `exit' is run in a trap and not supplied an exit status argument, it
uses the value of $? from before the trap only if it's run at the trap's
`top level' and would cause the trap to end (that is, not in a subshell).
This is from Posix interp 1602.
4. New Features in Readline
a. Documentation has been significantly updated.
b. New `force-meta-prefix' bindable variable, which forces the use of ESC as
the meta prefix when using "\M-" in key bindings instead of overloading
convert-meta.
c. The default value for `readline-colored-completion-prefix' no longer has a
leading `.'; the original report was based on a misunderstanding.
d. There is a new bindable command, `export-completions', which writes the
possible completions for a word to the standard output in a defined format.
------------------------------------------------------------------------------
This document details the changes between this version, bash-5.3-alpha, and
the previous version, bash-5.2-release.
+13 -5
View File
@@ -428,6 +428,14 @@ version and versions 2.0 and above.
there are four or fewer, it uses the posix test algorithm on the
subexpression.
68. The bind builtin's -p and -P options treat any arguments remaining after
option processing as bindable command names for which to print any key
bindings.
69. Interactive shells will notify the user of completed jobs while sourcing
a script. Newer versions defer notification until script execution
completes.
Shell Compatibility Level
=========================
@@ -512,10 +520,6 @@ compat42
single quotes are not special within double-quoted word expansions
compat43
- the shell does not print a warning message if an attempt is made to
use a quoted compound assignment as an argument to declare
(declare -a foo='(1 2)'). Later versions warn that this usage is
deprecated.
- word expansion errors are considered non-fatal errors that cause the
current command to fail, even in posix mode (the default behavior is
to make them fatal errors that cause the shell to exit)
@@ -587,7 +591,11 @@ compat51 (set using BASH_COMPAT)
compat52 (set using BASH_COMPAT)
- the test builtin uses its historical algorithm for parsing
expressions composed of five or more primaries.
- the -p and -P options to the bind builtin treat remaining arguments
as bindable command names for which to print any key bindings
- interactive shells will notify the user of completed jobs while
sourcing a script. Newer versions defer notification until script
execution completes.
-------------------------------------------------------------------------------
Copying and distribution of this file, with or without modification,
+1658 -2
View File
File diff suppressed because it is too large Load Diff
+1658 -2
View File
File diff suppressed because it is too large Load Diff
+34 -24
View File
@@ -24,8 +24,8 @@ The simplest way to compile Bash is:
files, some supplemental documentation, a number of example
loadable builtin commands, and a set of header files for developing
loadable builtins. You may need additional privileges to install
bash to your desired destination, so sudo make install might be
required. More information about controlling the locations where
bash to your desired destination, which may require sudo make
install. More information about controlling the locations where
bash and other files are installed is below (*note Installation
Names::).
@@ -107,7 +107,7 @@ you want the object files and executables to go and run the configure
script from the source directory (*note Basic Installation::). 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 '..'.
code in the directory that configure is in and in ...
If you have to use a make that does not support the VPATH variable,
you can compile Bash for one architecture at a time in the source code
@@ -228,7 +228,7 @@ Optional Features
The Bash configure has a number of --enable-FEATURE options, where
FEATURE indicates an optional part of Bash. There are also several
--with-PACKAGE options, where PACKAGE is something like bash-malloc
or purify. To turn off the default use of a package, use
or afs. 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.
@@ -240,18 +240,18 @@ the Bash configure recognizes.
--with-bash-malloc
Use the Bash version of malloc in the directory lib/malloc.
This is not the same malloc that appears in GNU libc, but an
older version originally derived from the 4.2 BSD malloc. This
malloc is very fast, but wastes some space on each allocation.
This option is enabled by default. The NOTES file contains a
list of systems for which this should be turned off, and
configure disables this option automatically for a number of
systems.
This is not the same malloc that appears in GNU libc, but a
custom version originally derived from the 4.2 BSD malloc. This
malloc is very fast, but wastes some space on each allocation,
though it uses several techniques to minimize the waste. This
option is enabled by default. The NOTES file contains a list of
systems for which this should be turned off, and configure
disables this option automatically for a number of systems.
--with-curses
Use the curses library instead of the termcap library. This should
be supplied if your system has an inadequate or incomplete termcap
database.
Use the curses library instead of the termcap library. configure
usually chooses this automatically, since most systems include the
termcap functions in the curses library.
--with-gnu-malloc
A synonym for --with-bash-malloc.
@@ -268,7 +268,9 @@ the Bash configure recognizes.
set to any other value, configure treats it as a directory
pathname and looks for the installed version of Readline in
subdirectories of that directory (include files in PREFIX/include
and the library in PREFIX/lib).
and the library in PREFIX/lib). The Bash default is to link with
a static library built in the lib/readline subdirectory of the
build directory.
--with-libintl-prefix[=PREFIX]
Define this to make Bash link with a locally-installed version of
@@ -276,10 +278,11 @@ the Bash configure recognizes.
--with-libiconv-prefix[=PREFIX]
Define this to make Bash look for libiconv in PREFIX instead of the
standard system locations. There is no version included with Bash.
standard system locations. The Bash distribution does not include
this library.
--enable-minimal-config
This produces a shell with minimal features, close to the
This produces a shell with minimal features, closer to the
historical Bourne shell.
There are several --enable- options that alter how Bash is compiled,
@@ -336,6 +339,12 @@ does not provide the necessary support.
Include support for csh-like history substitution (*note History
Interaction::).
--enable-bash-source-fullpath-default
Set the default value of the bash_source_fullpath shell option
described above under *note The Shopt Builtin:: to be enabled.
This controls how filenames are assigned to the BASH_SOURCE array
variable.
--enable-brace-expansion
Include csh-like brace expansion ( b{a,b}cbac bbc ). See
*note Brace Expansion::, for a complete description.
@@ -352,8 +361,9 @@ does not provide the necessary support.
--enable-command-timing
Include support for recognizing time as a reserved word and for
displaying timing statistics for the pipeline following time
(*note Pipelines::). This allows pipelines as well as shell
builtins and functions to be timed.
(*note Pipelines::). This allows timing pipelines, shell compound
commands, shell builtins, and shell functions, which an external
command cannot do easily.
--enable-cond-command
Include support for the [[ conditional command. (*note
@@ -456,13 +466,13 @@ does not provide the necessary support.
version of the Readline library (*note Command Line Editing::).
--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.
Include support for a “restricted shell”. If this is enabled, Bash
enters a restricted mode when called as rbash. See *note The
Restricted Shell::, for a description of restricted mode.
--enable-select
Include the select compound command, which allows the generation
of simple menus (*note Conditional Constructs::).
Include the select compound command, which allows generation of
simple menus (*note Conditional Constructs::).
--enable-single-help-strings
Store the text displayed by the help builtin as a single string
+15 -7
View File
@@ -149,6 +149,7 @@ bashtypes.h f
mailcheck.h f
xmalloc.h f
pathnames.h.in f
buildconf.h.in f
# order is important here
y.tab.c F
y.tab.h F
@@ -621,6 +622,8 @@ po/it.gmo f
po/it.po f
po/ja.gmo f
po/ja.po f
po/ka.gmo f
po/ka.po f
po/ko.gmo f
po/ko.po f
po/lt.gmo f
@@ -689,11 +692,8 @@ doc/fdl.txt f
#
doc/article.ps f
doc/rose94.ps f
doc/bash.ps f
doc/bashbug.ps f
doc/builtins.ps f
doc/rbash.ps f
doc/bashref.ps f
#doc/bash.ps f
#doc/bashref.ps f
doc/bashref.dvi f
doc/bash.0 f
doc/bashbug.0 f
@@ -705,6 +705,8 @@ doc/bashref.html f
doc/article.pdf f
doc/bash.pdf f
doc/bashref.pdf f
doc/builtins.pdf f
doc/rbash.pdf f
doc/rose94.pdf f
doc/aosa-bash.pdf f
doc/aosa-bash-full.pdf f
@@ -712,7 +714,7 @@ doc/aosa-bash-full.pdf f
support/Makefile.in f
support/bash.pc.in f
support/bashversion.c f
support/checkbashisms f 755
#support/checkbashisms f 755
support/config.guess f
support/config.rpath f 755
support/config.sub f
@@ -727,7 +729,8 @@ support/mkinstalldirs f 755
support/mkversion.sh f 755
support/mksignames.c f
support/signames.c f
support/bashbug.sh f
support/siglen.c f
#support/bashbug.sh f
support/bashbug.sh.in f
support/man2html.c f
support/recho.c f
@@ -860,6 +863,7 @@ examples/functions/notify.bash f
#examples/functions/repeat3 f
examples/functions/seq f
examples/functions/seq2 f
examples/functions/setalrm f
examples/functions/shcat f
examples/functions/shcat2 f
examples/functions/sort-pos-params f
@@ -1044,6 +1048,7 @@ tests/source4.sub f
tests/source5.sub f
tests/source6.sub f
tests/source7.sub f
tests/source8.sub f
tests/case.tests f
tests/case.right f
tests/case1.sub f
@@ -1154,6 +1159,7 @@ tests/errors8.sub f
tests/errors9.sub f
tests/errors10.sub f
tests/errors11.sub f
tests/errors12.sub f
tests/execscript f
tests/exec.right f
tests/exec1.sub f 755
@@ -1171,6 +1177,7 @@ tests/exec12.sub f
tests/exec13.sub f
tests/exec14.sub f
tests/exec15.sub f
tests/exec16.sub f
tests/exp.tests f
tests/exp.right f
tests/exp1.sub f
@@ -1635,6 +1642,7 @@ tests/varenv21.sub f
tests/varenv22.sub f
tests/varenv23.sub f
tests/varenv24.sub f
tests/varenv25.sub f
tests/version f
tests/version.mini f
tests/vredir.tests f
+517 -441
View File
File diff suppressed because it is too large Load Diff
+60 -2
View File
@@ -48,8 +48,8 @@ p. Treat a NULL value for $PATH as equivalent to ".".
p. New loadable builtins: kv, strptime
q. GLOBSORT: new variable to specify how to sort the results of pathname
expansion (name, size, blocks, mtime, atime, ctime, none) in ascending
or descending order.
expansion (name, size, blocks, mtime, atime, ctime, numeric, none) in
ascending or descending order.
r. `compgen' has a new option: -V varname. If supplied, it stores the generated
completions into VARNAME instead of printing them on stdout.
@@ -96,6 +96,53 @@ ee. New test builtin behavior when parsing a parenthesized subexpression and
Added for compatibility with coreutils test, dependent on the shell
compatibility level. Such expressions remain ambiguous.
ff. MULTIPLE_COPROCS is now enabled by default.
gg. The `bind' builtin interprets additional non-option arguments after -p or
-P as bindable command names and restricts output to the bindings for
those names.
hh. Bash now uses the login shell for $BASH if the shell is named `su' or `-su'.
ii. Bash now prints job notifications if an interactive shell is running a trap,
even though the shell is not interactive at that moment.
jj. Programmable completion allows a new compspec loaded after a completion
function returns 124 to be used in more cases.
kk. ./source has a new -p PATH option, which makes it use the PATH argument
instead of $PATH to look for the file.
ll. Documentation has been significantly updated.
mm. `wait -n' can now return terminated process substitutions, jobs about
which the user has already been notified (like `wait' without options),
nn. `wait -n' removes jobs from the jobs table or list of terminated children
when in posix mode.
oo. Changed the `wait' builtin behavior regarding process substitutions to
match the documentation.
pp. There is a new `bash_source_fullpath' shopt option, which makes bash put
full pathnames into BASH_SOURCE, and a way to set a default value for it
at configure time.
qq. Posix mode now forces job notifications to occur when the new edition of
POSIX specifes (since it now specifies them).
rr. Interactive shells don't print job notifications while sourcing scripts.
ss. The parser prints more information about the command it's trying to parse
when it encounters EOF before completing the command.
tt. Posix mode no longer requires function names to be valid shell identifiers.
uu. If `exit' is run in a trap and not supplied an exit status argument, it
uses the value of $? from before the trap only if it's run at the trap's
`top level' and would cause the trap to end (that is, not in a subshell).
This is from Posix interp 1602.
2. New Features in Readline
a. Output a newline if there is no prompt and readline reads an empty line.
@@ -128,6 +175,17 @@ i. Incremental and non-incremental searches now allow ^V/^Q (or, in the former
case, anything bound to quoted-insert) to quote characters in the search
string.
j. Documentation has been significantly updated.
k. New `force-meta-prefix' bindable variable, which forces the use of ESC as
the meta prefix when using "\M-" in key bindings instead of overloading
convert-meta.
l. The default value for `readline-colored-completion-prefix' no longer has a
leading `.'; the original report was based on a misunderstanding.
m. There is a new bindable command, `export-completions', which writes the
possible completions for a word to the standard output in a defined format.
-------------------------------------------------------------------------------
This is a terse description of the new features added to bash-5.2 since
+227 -217
View File
@@ -15,13 +15,13 @@ standard was published in 1992. It was merged with the original IEEE
1003.1 Working Group and is currently maintained by the Austin Group (a
joint working group of the IEEE, The Open Group and ISO/IEC SC22/WG15).
Today the Shell and Utilities are a volume within the set of documents
that make up IEEE Std 1003.1-2017, and thus the former POSIX.2 (from
that make up IEEE Std 1003.1-2024, and thus the former POSIX.2 (from
1992) is now part of the current unified POSIX standard.
The Shell and Utilities volume concentrates on the command interpreter
interface and utility programs commonly executed from the command line
or by other programs. The standard is freely available on the web at
<https://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html>.
<https://pubs.opengroup.org/onlinepubs/9799919799/utilities/contents.html>.
Bash is concerned with the aspects of the shell's behavior defined by
the POSIX Shell and Utilities volume. The shell command language has of
@@ -45,7 +45,7 @@ editing commands were left out due to objections.
Although Bash is an implementation of the POSIX shell specification,
there are areas where the Bash default behavior differs from the
specification. The Bash “posix mode” changes the Bash behavior in these
areas so that it conforms to the standard more closely.
areas so that it conforms more closely to the standard.
Starting Bash with the --posix command-line option or executing set
-o posix while Bash is running will cause Bash to conform more closely
@@ -59,117 +59,146 @@ The following list is what's changed when 'POSIX mode' is in effect:
1. Bash ensures that the POSIXLY_CORRECT variable is set.
2. 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.
2. Bash reads and executes the POSIX startup files ($ENV) rather
than the normal Bash files (*note Bash Startup Files::.
3. Bash will not insert a command without the execute bit set into the
command hash table, even if it returns it as a (last-ditch) result
from a $PATH search.
3. Alias expansion is always enabled, even in non-interactive shells.
4. The message printed by the job control code and builtins when a job
exits with a non-zero status is 'Done(status)'.
5. The message printed by the job control code and builtins when a job
is stopped is 'Stopped(SIGNAME)', where SIGNAME is, for example,
SIGTSTP.
6. Alias expansion is always enabled, even in non-interactive shells.
7. Reserved words appearing in a context where reserved words are
4. Reserved words appearing in a context where reserved words are
recognized do not undergo alias expansion.
8. Alias expansion is performed when initially parsing a command
substitution. The default mode generally defers it, when enabled,
until the command substitution is executed. This means that
command substitution will not expand aliases that are defined after
the command substitution is initially parsed (e.g., as part of a
function definition).
5. Alias expansion is performed when initially parsing a command
substitution. The default (non-posix) mode generally defers it,
when enabled, until the command substitution is executed. This
means that command substitution will not expand aliases that are
defined after the command substitution is initially parsed (e.g.,
as part of a function definition).
9. The POSIX PS1 and PS2 expansions of ! to the history number
and !! to ! are enabled, and parameter expansion is performed
on the values of PS1 and PS2 regardless of the setting of the
promptvars option.
10. The POSIX startup files are executed ($ENV) rather than the
normal Bash files.
11. Tilde expansion is only performed on assignments preceding a
command name, rather than on all assignment statements on the line.
12. The default history file is ~/.sh_history (this is the default
value the shell assigns to $HISTFILE).
13. Redirection operators do not perform filename expansion on the
word in the redirection unless the shell is interactive.
14. Redirection operators do not perform word splitting on the word in
the redirection.
15. Function names must be valid shell names. 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 invalid
name causes a fatal syntax error in non-interactive shells.
16. Function names may not be the same as one of the POSIX special
builtins.
17. Even if a shell function whose name contains a slash was defined
before entering POSIX mode, the shell will not execute a function
whose name contains one or more slashes.
18. POSIX special builtins are found before shell functions during
command lookup, including output printed by the type and
command builtins.
19. When printing shell function definitions (e.g., by type), Bash
does not print the function keyword.
20. Literal tildes that appear as the first character in elements of
the PATH variable are not expanded as described above under *note
Tilde Expansion::.
21. The time reserved word may be used by itself as a command. When
used in this way, it displays timing statistics for the shell and
its completed children. The TIMEFORMAT variable controls the
6. The time reserved word may be used by itself as a simple command.
When used in this way, it displays timing statistics for the shell
and its completed children. The TIMEFORMAT variable controls the
format of the timing information.
22. When parsing and expanding a ${...} expansion that appears within
7. The parser does not recognize time as a reserved word if the next
token begins with a -.
8. When parsing and expanding a ${...} expansion that appears within
double quotes, single quotes are no longer special and cannot be
used to quote a closing brace or other special character, unless
the operator is one of those defined to perform pattern removal.
In this case, they do not have to appear as matched pairs.
23. The parser does not recognize time as a reserved word if the
next token begins with a -.
9. Redirection operators do not perform filename expansion on the word
in a redirection unless the shell is interactive.
24. The ! character does not introduce history expansion within a
10. Redirection operators do not perform word splitting on the word in
a redirection.
11. Function names may not be the same as one of the POSIX special
builtins.
12. Tilde expansion is only performed on assignments preceding a
command name, rather than on all assignment statements on the line.
13. While variable indirection is available, it may not be applied to
the # and ? special parameters.
14. Expanding the * special parameter in a pattern context where the
expansion is double-quoted does not treat the $* as if it were
double-quoted.
15. A double quote character (") is treated specially when it
appears in a backquoted command substitution in the body of a
here-document that undergoes expansion. That means, for example,
that a backslash preceding a double quote character will escape it
and the backslash will be removed.
16. Command substitutions don't set the ? special parameter. The
exit status of a simple command without a command word is still the
exit status of the last command substitution that occurred while
evaluating the variable assignments and redirections in that
command, but that does not happen until after all of the
assignments and redirections.
17. Literal tildes that appear as the first character in elements of
the PATH variable are not expanded as described above under *note
Tilde Expansion::.
18. Command lookup finds POSIX special builtins before shell
functions, including output printed by the type and command
builtins.
19. Even if a shell function whose name contains a slash was defined
before entering POSIX mode, the shell will not execute a function
whose name contains one or more slashes.
20. 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.
21. Bash will not insert a command without the execute bit set into
the command hash table, even if it returns it as a (last-ditch)
result from a $PATH search.
22. The message printed by the job control code and builtins when a
job exits with a non-zero status is 'Done(status)'.
23. The message printed by the job control code and builtins when a
job is stopped is 'Stopped(SIGNAME)', where SIGNAME is, for
example, SIGTSTP.
24. If the shell is interactive, Bash does not perform job
notifications between executing commands in lists separated by ;
or newline. Non-interactive shells print status messages after a
foreground job in a list completes.
25. If the shell is interactive, Bash waits until the next prompt
before printing the status of a background job that changes status
or a foreground job that terminates due to a signal.
Non-interactive shells print status messages after a foreground job
completes.
26. Bash permanently removes jobs from the jobs table after notifying
the user of their termination via the wait or jobs builtins.
It removes the job from the jobs list after notifying the user of
its termination, but the status is still available via wait, as
long as wait is supplied a PID argument.
27. The vi editing mode will invoke the vi editor directly when
the v command is run, instead of checking $VISUAL and
$EDITOR.
28. Prompt expansion enables the POSIX PS1 and PS2 expansions of
! to the history number and !! to !, and Bash performs
parameter expansion on the values of PS1 and PS2 regardless of
the setting of the promptvars option.
29. The default history file is ~/.sh_history (this is the default
value the shell assigns to $HISTFILE).
30. The ! character does not introduce history expansion within a
double-quoted string, even if the histexpand option is enabled.
25. If a POSIX special builtin returns an error status, a
31. When printing shell function definitions (e.g., by type), Bash
does not print the function keyword unless necessary.
32. Non-interactive shells exit if a syntax error in an arithmetic
expansion results in an invalid expression.
33. Non-interactive shells exit if a parameter expansion error occurs.
34. If a POSIX special builtin returns an error status, a
non-interactive shell exits. The fatal errors are those listed in
the POSIX standard, and include things like passing incorrect
options, redirection errors, variable assignment errors for
assignments preceding the command name, and so on.
26. The unset builtin with the -v option specified returns a fatal
error if it attempts to unset a readonly or non-unsettable
variable, or encounters a variable name argument that is an invalid
identifier, which causes a non-interactive shell to exit.
27. When asked to unset a variable that appears in an assignment
statement preceding the command, the unset builtin attempts to
unset a variable of the same name in the current or previous scope
as well. This implements the required "if an assigned variable is
further modified by the utility, the modifications made by the
utility shall persist" behavior.
28. A non-interactive shell exits with an error status if a variable
35. 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 readonly variable.
29. A non-interactive shell exits with an error status if a variable
36. A non-interactive shell exits with an error status if a variable
assignment error occurs in an assignment statement preceding a
special builtin, but not with any other simple command. For any
other simple command, the shell aborts execution of that command,
@@ -177,171 +206,156 @@ The following list is what's changed when 'POSIX mode' is in effect:
perform any further processing of the command in which the error
occurred").
30. A non-interactive shell exits with an error status if the
37. 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 readonly variable or has an invalid
name.
31. Non-interactive shells exit if FILENAME in . FILENAME is not
38. Non-interactive shells exit if FILENAME in . FILENAME is not
found.
32. Non-interactive shells exit if a syntax error in an arithmetic
expansion results in an invalid expression.
33. Non-interactive shells exit if a parameter expansion error occurs.
34. Non-interactive shells exit if there is a syntax error in a script
39. Non-interactive shells exit if there is a syntax error in a script
read with the . or source builtins, or in a string processed by
the eval builtin.
35. While variable indirection is available, it may not be applied to
the # and ? special parameters.
40. Non-interactive shells exit if the export, readonly or unset
builtin commands get an argument that is not a valid identifier,
and they are not operating on shell functions. These errors force
an exit because these are special builtins.
36. Expanding the * special parameter in a pattern context where the
expansion is double-quoted does not treat the $* as if it were
double-quoted.
37. Assignment statements preceding POSIX special builtins persist in
41. Assignment statements preceding POSIX special builtins persist in
the shell environment after the builtin completes.
38. The command builtin does not prevent builtins that take
42. The command builtin does not prevent builtins that take
assignment statements as arguments from expanding them as
assignment statements; when not in POSIX mode, assignment builtins
assignment statements; when not in POSIX mode, declaration commands
lose their assignment statement expansion properties when preceded
by command.
39. The bg builtin uses the required format to describe each job
43. Enabling POSIX mode has the effect of setting the
inherit_errexit option, so subshells spawned to execute command
substitutions inherit the value of the -e option from the parent
shell. When the inherit_errexit option is not enabled, Bash
clears the -e option in such subshells.
44. Enabling POSIX mode has the effect of setting the shift_verbose
option, so numeric arguments to shift that exceed the number of
positional parameters will result in an error message.
45. Enabling POSIX mode has the effect of setting the
interactive_comments option (*note Comments::).
46. The . and source builtins do not search the current directory
for the filename argument if it is not found by searching PATH.
47. When the alias builtin displays alias definitions, it does not
display them with a leading alias unless the -p option is
supplied.
48. The bg builtin uses the required format to describe each job
placed in the background, which does not include an indication of
whether the job is the current or previous job.
40. The output of kill -l prints all the signal names on a single
line, separated by spaces, without the SIG prefix.
49. When the cd builtin is invoked in logical mode, and the pathname
constructed from $PWD and the directory name supplied as an
argument does not refer to an existing directory, cd will fail
instead of falling back to physical mode.
41. The kill builtin does not accept signal names with a SIG
prefix.
50. When the cd builtin cannot change a directory because the length
of the pathname constructed from $PWD and the directory name
supplied as an argument exceeds PATH_MAX when canonicalized, cd
will attempt to use the supplied directory name.
42. The export and readonly builtin commands display their output
51. When the xpg_echo option is enabled, Bash does not attempt to
interpret any arguments to echo as options. echo displays each
argument after converting escape sequences.
52. The export and readonly builtin commands display their output
in the format required by POSIX.
43. If the export and readonly builtin commands get an argument
that is not a valid identifier, and they are not operating on shell
functions, they return an error. This will cause a non-interactive
shell to exit because these are special builtins.
53. When listing the history, the fc builtin does not include an
indication of whether or not a history entry has been modified.
44. The trap builtin displays signal names without the leading
54. The default editor used by fc is ed.
55. fc treats extra arguments as an error instead of ignoring them.
56. If there are too many arguments supplied to fc -s, fc prints
an error message and returns failure.
57. The output of kill -l prints all the signal names on a single
line, separated by spaces, without the SIG prefix.
58. The kill builtin does not accept signal names with a SIG
prefix.
59. The printf builtin uses double (via strtod) to convert
arguments corresponding to floating point conversion specifiers,
instead of long double if it's available. The L length
modifier forces printf to use long double if it's available.
60. The pwd builtin verifies that the value it prints is the same as
the current directory, even if it is not asked to check the file
system with the -P option.
61. The read builtin may be interrupted by a signal for which a trap
has been set. If Bash receives a trapped signal while executing
read, the trap handler executes and read returns an exit status
greater than 128.
62. When the set builtin is invoked without options, it does not
display shell function names and definitions.
63. When the set builtin is invoked without options, it displays
variable values without quotes, unless they contain shell
metacharacters, even if the result contains nonprinting characters.
64. The test builtin compares strings using the current locale when
evaluating the < and > binary operators.
65. The test builtin's -t unary primary requires an argument.
Historical versions of test made the argument optional in certain
cases, and Bash attempts to accommodate those for backwards
compatibility.
66. The trap builtin displays signal names without the leading
SIG.
45. The trap builtin doesn't check the first argument for a possible
67. The trap builtin doesn't check the first argument for a possible
signal specification and revert the signal handling to the original
disposition if it is, unless that argument consists solely of
digits and is a valid signal number. If users want to reset the
handler for a given signal to the original disposition, they should
use - as the first argument.
46. trap -p without arguments displays signals whose dispositions
68. trap -p without arguments displays signals whose dispositions
are set to SIG_DFL and those that were ignored when the shell
started, not just trapped signals.
47. The . and source builtins do not search the current directory
for the filename argument if it is not found by searching PATH.
48. Enabling POSIX mode has the effect of setting the
inherit_errexit option, so subshells spawned to execute command
substitutions inherit the value of the -e option from the parent
shell. When the inherit_errexit option is not enabled, Bash
clears the -e option in such subshells.
49. Enabling POSIX mode has the effect of setting the shift_verbose
option, so numeric arguments to shift that exceed the number of
positional parameters will result in an error message.
50. When the alias builtin displays alias definitions, it does not
display them with a leading alias unless the -p option is
supplied.
51. When the set builtin is invoked without options, it does not
display shell function names and definitions.
52. When the set builtin is invoked without options, it displays
variable values without quotes, unless they contain shell
metacharacters, even if the result contains nonprinting characters.
53. When the cd builtin is invoked in logical mode, and the pathname
constructed from $PWD and the directory name supplied as an
argument does not refer to an existing directory, cd will fail
instead of falling back to physical mode.
54. When the cd builtin cannot change a directory because the length
of the pathname constructed from $PWD and the directory name
supplied as an argument exceeds PATH_MAX when canonicalized, cd
will attempt to use the supplied directory name.
55. The pwd builtin verifies that the value it prints is the same as
the current directory, even if it is not asked to check the file
system with the -P option.
56. When listing the history, the fc builtin does not include an
indication of whether or not a history entry has been modified.
57. The default editor used by fc is ed.
58. fc treats extra arguments as an error instead of ignoring them.
59. If there are too many arguments supplied to fc -s, fc prints
an error message and returns failure.
60. The type and command builtins will not report a non-executable
69. The type and command builtins will not report a non-executable
file as having been found, though the shell will attempt to execute
such a file if it is the only so-named file found in $PATH.
61. The vi editing mode will invoke the vi editor directly when
the v command is run, instead of checking $VISUAL and
$EDITOR.
62. When the xpg_echo option is enabled, Bash does not attempt to
interpret any arguments to echo as options. Each argument is
displayed, after escape characters are converted.
63. The ulimit builtin uses a block size of 512 bytes for the -c
70. The ulimit builtin uses a block size of 512 bytes for the -c
and -f options.
64. The arrival of SIGCHLD when a trap is set on SIGCHLD does not
71. The unset builtin with the -v option specified returns a fatal
error if it attempts to unset a readonly or non-unsettable
variable, which causes a non-interactive shell to exit.
72. When asked to unset a variable that appears in an assignment
statement preceding the command, the unset builtin attempts to
unset a variable of the same name in the current or previous scope
as well. This implements the required "if an assigned variable is
further modified by the utility, the modifications made by the
utility shall persist" behavior.
73. The arrival of SIGCHLD when a trap is set on SIGCHLD does not
interrupt the wait builtin and cause it to return immediately.
The trap command is run once for each child that exits.
65. The read builtin may be interrupted by a signal for which a trap
has been set. If Bash receives a trapped signal while executing
read, the trap handler executes and read returns an exit status
greater than 128.
66. The printf builtin uses double (via strtod) to convert
arguments corresponding to floating point conversion specifiers,
instead of long double if it's available. The L length
modifier forces printf to use long double if it's available.
67. Bash removes an exited background process's status from the list
of such statuses after the wait builtin is used to obtain it.
68. A double quote character (") is treated specially when it
appears in a backquoted command substitution in the body of a
here-document that undergoes expansion. That means, for example,
that a backslash preceding a double quote character will escape it
and the backslash will be removed.
69. The test builtin compares strings using the current locale when
processing the < and > binary operators.
70. The test builtin's -t unary primary requires an argument.
Historical versions of test made the argument optional in certain
cases, and Bash attempts to accommodate those for backwards
compatibility.
71. Command substitutions don't set the ? special parameter. The
exit status of a simple command without a command word is still the
exit status of the last command substitution that occurred while
evaluating the variable assignments and redirections in that
command, but that does not happen until after all of the
assignments and redirections.
74. Bash removes an exited background process's status from the list
of such statuses after the wait builtin returns it.
There is other POSIX behavior that Bash does not implement by default
even when in POSIX mode. Specifically:
@@ -350,11 +364,7 @@ even when in POSIX mode. Specifically:
entries if FCEDIT is unset, rather than defaulting directly to
ed. fc uses ed if EDITOR is unset.
2. A non-interactive shell does not exit if a variable assignment
preceding the command builtin or another non-special builtin
fails.
3. As noted above, Bash requires the xpg_echo option to be enabled
2. As noted above, Bash requires the xpg_echo option to be enabled
for the echo builtin to be fully conformant.
Bash can be configured to be POSIX-conformant by default, by specifying
+3 -1
View File
@@ -2,7 +2,7 @@
=========================
If Bash is started with the name rbash, or the --restricted or -r
option is supplied at invocation, the shell becomes restricted. A
option is supplied at invocation, the shell becomes RESTRICTED. A
restricted shell is used to set up an environment more controlled than
the standard shell. A restricted shell behaves identically to bash
with the exception that the following are disallowed or not performed:
@@ -13,6 +13,8 @@ with the exception that the following are disallowed or not performed:
• Specifying command names containing slashes.
• Specifying a filename containing a slash as an argument to the .
builtin command.
• Using the -p option to the . builtin command to specify a
search path.
• Specifying a filename containing a slash as an argument to the
history builtin command.
• Specifying a filename containing a slash as an argument to the -p
+12 -11
View File
@@ -7,16 +7,16 @@ but also with interactive command line editing, job control on
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/bashref.texi'. There is also a
large Unix-style man page. The man page is the definitive description
of the shell's features.
type of shell, see the file `doc/bashref.info'. There is also a
large Unix-style man page. If the info fie and the man page conflict,
the man page is the definitive description of the shell's features.
See the file POSIX for a discussion of how the Bash defaults differ
from the POSIX spec and a description of the Bash `posix mode'.
There are some user-visible incompatibilities between this version
of Bash and previous widely-distributed versions, bash-4.4, bash-5.0,
and bash-5.1. For details, see the file COMPAT. The NEWS file tersely
of Bash and previous widely-distributed versions, bash-5.0, bash-5.1,
and bash-5.2. The COMPAT file has the details. The NEWS file tersely
lists features that are new in this release.
Bash is free software, distributed under the terms of the [GNU] General
@@ -28,7 +28,7 @@ A number of frequently-asked questions are answered in the file
`doc/FAQ'. (That file is no longer updated.)
To compile Bash, type `./configure', then `make'. Bash auto-configures
the build process, so no further intervention should be necessary. Bash
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
@@ -40,13 +40,14 @@ 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
to customize and control the build process, including how to build in a
directory different from the source directory. 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 `examples/misc/alias-conv.sh'
as a starting point. The script `examples/misc/cshtobash' is a
more ambitious script that attempts to do a more complete job.
as a starting point. The script `examples/misc/cshtobash' is a more
ambitious script that attempts to do a more complete job.
Reporting Bugs
==============
@@ -64,8 +65,8 @@ changes that people would like. This mailing list is also available
as a usenet newsgroup: gnu.bash.bug.
When you send a bug report, please use the `bashbug' program that is
built at the same time as bash. If bash fails to build, try building
bashbug directly with `make bashbug'. If you cannot build `bashbug',
built at the same time as bash. If bash fails to build, try building
bashbug directly with `make bashbug'. If you cannot build `bashbug',
please send mail to bug-bash@gnu.org with the following information:
* the version number and release status of Bash (e.g., 2.05a-release)
Vendored
+9 -32
View File
@@ -935,8 +935,8 @@ AC_CACHE_VAL(bash_cv_termcap_lib,
[AC_CHECK_LIB(termcap, tgetent, bash_cv_termcap_lib=libtermcap,
[AC_CHECK_LIB(tinfo, tgetent, bash_cv_termcap_lib=libtinfo,
[AC_CHECK_LIB(curses, tgetent, bash_cv_termcap_lib=libcurses,
[AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses,
[AC_CHECK_LIB(ncursesw, tgetent, bash_cv_termcap_lib=libncursesw,
[AC_CHECK_LIB(ncursesw, tgetent, bash_cv_termcap_lib=libncursesw,
[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)
@@ -952,6 +952,9 @@ TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libtinfo; then
TERMCAP_LIB=-ltinfo
TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libncursesw; then
TERMCAP_LIB=-lncursesw
TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libncurses; then
TERMCAP_LIB=-lncurses
TERMCAP_DEP=
@@ -1022,7 +1025,7 @@ dnl like _AC_STRUCT_DIRENT(MEMBER) but public
AC_DEFUN(BASH_STRUCT_DIRENT,
[
AC_REQUIRE([AC_HEADER_DIRENT])
AC_CHECK_MEMBERS(struct dirent.$1, bash_cv_dirent_has_$1=yes, bash_cv_dirent_has_$1=no,
AC_CHECK_MEMBERS(struct dirent.$1, [], [],
[[
#include <stdio.h>
#include <sys/types.h>
@@ -1046,35 +1049,9 @@ AC_CHECK_MEMBERS(struct dirent.$1, bash_cv_dirent_has_$1=yes, bash_cv_dirent_has
]])
])
AC_DEFUN(BASH_STRUCT_DIRENT_D_INO,
[AC_REQUIRE([AC_HEADER_DIRENT])
AC_MSG_CHECKING(for struct dirent.d_ino)
AC_CACHE_VAL(bash_cv_dirent_has_d_ino, [BASH_STRUCT_DIRENT([d_ino])])
AC_MSG_RESULT($bash_cv_dirent_has_d_ino)
if test $bash_cv_dirent_has_d_ino = yes; then
AC_DEFINE(HAVE_STRUCT_DIRENT_D_INO)
fi
])
AC_DEFUN(BASH_STRUCT_DIRENT_D_FILENO,
[AC_REQUIRE([AC_HEADER_DIRENT])
AC_MSG_CHECKING(for struct dirent.d_fileno)
AC_CACHE_VAL(bash_cv_dirent_has_d_fileno, [BASH_STRUCT_DIRENT([d_fileno])])
AC_MSG_RESULT($bash_cv_dirent_has_d_fileno)
if test $bash_cv_dirent_has_d_fileno = yes; then
AC_DEFINE(HAVE_STRUCT_DIRENT_D_FILENO)
fi
])
AC_DEFUN(BASH_STRUCT_DIRENT_D_NAMLEN,
[AC_REQUIRE([AC_HEADER_DIRENT])
AC_MSG_CHECKING(for struct dirent.d_namlen)
AC_CACHE_VAL(bash_cv_dirent_has_d_namlen, [BASH_STRUCT_DIRENT([d_namlen])])
AC_MSG_RESULT($bash_cv_dirent_has_d_namlen)
if test $bash_cv_dirent_has_d_namlen = yes; then
AC_DEFINE(HAVE_STRUCT_DIRENT_D_NAMLEN)
fi
])
AC_DEFUN([BASH_STRUCT_DIRENT_D_INO], [BASH_STRUCT_DIRENT([d_ino])])
AC_DEFUN([BASH_STRUCT_DIRENT_D_FILENO], [BASH_STRUCT_DIRENT([d_fileno])])
AC_DEFUN([BASH_STRUCT_DIRENT_D_NAMLEN], [BASH_STRUCT_DIRENT([d_namlen])])
AC_DEFUN(BASH_STRUCT_TIMEVAL,
[AC_MSG_CHECKING(for struct timeval in sys/time.h and time.h)
+7 -8
View File
@@ -276,7 +276,7 @@ bind_array_variable (const char *name, arrayind_t ind, const char *value, int fl
}
if (entry == (SHELL_VAR *) 0)
entry = make_new_array_variable (name);
else if ((readonly_p (entry) && (flags&ASS_FORCE) == 0) || noassign_p (entry))
else if (ASSIGN_DISALLOWED (entry, flags))
{
if (readonly_p (entry))
err_readonly (name);
@@ -298,7 +298,7 @@ bind_array_element (SHELL_VAR *entry, arrayind_t ind, char *value, int flags)
SHELL_VAR *
bind_assoc_variable (SHELL_VAR *entry, const char *name, char *key, const char *value, int flags)
{
if ((readonly_p (entry) && (flags&ASS_FORCE) == 0) || noassign_p (entry))
if (ASSIGN_DISALLOWED (entry, flags))
{
if (readonly_p (entry))
err_readonly (name);
@@ -406,6 +406,9 @@ assign_array_element_internal (SHELL_VAR *entry, const char *name, char *vname,
if (estatep)
nkey = savestring (akey); /* assoc_insert/assoc_replace frees akey */
entry = bind_assoc_variable (entry, vname, akey, value, flags);
/* If we didn't perform the assignment, free the key we allocated */
if (entry == 0 || (ASSIGN_DISALLOWED (entry, flags)))
FREE (akey);
if (estatep)
{
estatep->type = ARRAY_ASSOC;
@@ -476,7 +479,7 @@ find_or_make_array_variable (const char *name, int flags)
if (var == 0)
var = (flags & 2) ? make_new_assoc_variable (name) : make_new_array_variable (name);
else if ((flags & 1) && (readonly_p (var) || noassign_p (var)))
else if ((flags & 1) && ASSIGN_DISALLOWED(var, 0))
{
if (readonly_p (var))
err_readonly (name);
@@ -1359,8 +1362,7 @@ array_expand_index (SHELL_VAR *var, const char *s, int len, int flags)
exp = (char *)xmalloc (len);
strncpy (exp, s, len - 1);
exp[len - 1] = '\0';
#if 1 /* TAG: bash-5.3 */
#if 0
#if 0 /* XXX - not dependent on compatibility mode for now */
if (shell_compatibility_level <= 52 || (flags & AV_NOEXPAND) == 0)
#else
if ((flags & AV_NOEXPAND) == 0)
@@ -1368,9 +1370,6 @@ array_expand_index (SHELL_VAR *var, const char *s, int len, int flags)
t = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH|Q_ARRAYSUB); /* XXX - Q_ARRAYSUB for future use */
else
t = exp;
#else
t = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH|Q_ARRAYSUB); /* XXX - Q_ARRAYSUB for future use */
#endif
savecmd = this_command_name;
this_command_name = (char *)NULL;
eflag = (shell_compatibility_level > 51) ? 0 : EXP_EXPANDED;
+1 -1
View File
@@ -461,7 +461,7 @@ maybe_append_history (char *filename)
fd = open (filename, O_WRONLY|O_CREAT, 0600);
if (fd < 0)
{
builtin_error (_("%s: cannot create: %s"), filename, strerror (errno));
builtin_error ("%s: %s: %s", filename, _("cannot create"), strerror (errno));
return (EXECUTION_FAILURE);
}
close (fd);
+103 -19
View File
@@ -1328,14 +1328,45 @@ bash_transpose_shellwords (int count, int key)
return 0;
}
/* Directory name spelling correction on the current word (not shellword).
COUNT > 1 is not exactly correct yet. */
/* Directory name spelling correction on the current or previous shellword. */
static int
bash_spell_correct_shellword (int count, int key)
{
int wbeg, wend;
int wbeg, wend, n, p;
char *text, *newdir;
/* If we have a negative count, move back that many shellwords and then
move forward. Do it one at a time so we get an accurate count of the
number of words we moved back -- we only want to correct that many. */
if (count < 0)
{
n = 0;
while (rl_point > 0 && count++)
{
p = rl_point;
bash_backward_shellword (1, key);
/* We probably moved to column 0 with leading spaces on the line */
if (rl_point == 0 && WORDDELIM (rl_line_buffer[rl_point]))
{
rl_point = p;
break;
}
n++;
}
count = n;
}
else if (WORDDELIM (rl_line_buffer[rl_point])) /* count > 0 */
{
/* between words with a positive count, move forward to word start */
while (rl_point < rl_end && WORDDELIM (rl_line_buffer[rl_point]))
rl_point++; /* word delims are single-byte characters */
}
/* First make sure we're at the end of the word we want to begin with
so the initial bash_backward_shellword works right. */
if (rl_point < rl_end && WORDDELIM (rl_line_buffer[rl_point]) == 0)
bash_forward_shellword (1, key);
while (count)
{
bash_backward_shellword (1, key);
@@ -1348,7 +1379,10 @@ bash_spell_correct_shellword (int count, int key)
text = rl_copy_text (wbeg, wend);
if (text == 0 || *text == 0)
break;
{
FREE (text);
break;
}
newdir = dirspell (text);
if (newdir)
@@ -1371,7 +1405,7 @@ bash_spell_correct_shellword (int count, int key)
count--;
if (count)
bash_forward_shellword (1, key); /* XXX */
bash_forward_shellword (1, key); /* XXX */
}
return 0;
@@ -1899,11 +1933,21 @@ bash_default_completion (const char *text, int start, int end, int qc, int compf
strvec_dispose (matches);
matches = (char **)0;
}
else if (matches && matches[1] && rl_completion_type == '!')
else if (matches && matches[1] && (rl_completion_type == '!' || rl_completion_type == '@'))
{
rl_completion_suppress_append = 1;
rl_filename_completion_desired = 0;
}
else if (matches && matches[1] && rl_completion_type == '?')
{
size_t ind;
ind = (end > start) ? end - start - 1 : 0;
if (text[ind] == '/')
{
rl_completion_suppress_append = 1;
rl_filename_completion_desired = 0;
}
}
}
return (matches);
@@ -1969,6 +2013,7 @@ command_word_completion_function (const char *hint_text, int state)
static int mapping_over, local_index, searching_path, hint_is_dir;
static int old_glob_ignore_case, globpat;
static SHELL_VAR **varlist = (SHELL_VAR **)NULL;
static int orig_found_quote;
#if defined (ALIAS)
static alias_t **alias_list = (alias_t **)NULL;
#endif /* ALIAS */
@@ -2001,6 +2046,12 @@ command_word_completion_function (const char *hint_text, int state)
glob_matches = (char **)NULL;
}
if (directory_part)
{
free (directory_part);
directory_part = (char *)NULL;
}
globpat = completion_glob_pattern (hint_text);
/* If this is an absolute program name, do not check it against
@@ -2078,7 +2129,9 @@ command_word_completion_function (const char *hint_text, int state)
if (rl_completion_found_quote && rl_completion_quote_character == 0)
dequoted_hint = bash_dequote_filename (hint, 0);
orig_found_quote = rl_completion_found_quote;
path = path_value ("PATH", 0);
path_index = dot_in_path = 0;
@@ -2242,6 +2295,8 @@ globword:
{
char *current_path;
rl_completion_found_quote = orig_found_quote;
/* Get the next directory from the path. If there is none, then we
are all done. */
if (path == 0 || path[path_index] == 0 ||
@@ -2273,13 +2328,28 @@ globword:
free (filename_hint);
fnhint = filename_hint = (char *)NULL;
filename_hint = sh_makepath (current_path, hint, 0);
/* We can have characters that need to be quoted in either the $PATH
element or the dequoted filename. Since we only want to call a
quoting function on the entire path once, and we've already dequoted
the hint text we were passed (dequoted_hint), build the path using
the dequoted hint text and quote it if we need to. Readline will only
call the dequoting function if rl_completion_found_quote != 0, so
we have to force it. */
filename_hint = sh_makepath (current_path, dequoted_hint, 0);
/* Need a quoted version (though it doesn't matter much in most
cases) because rl_filename_completion_function dequotes the
filename it gets, assuming that it's been quoted as part of
the input line buffer. */
#if 1
if (strpbrk (filename_hint, "\"'\\"))
fnhint = sh_backslash_quote (filename_hint, filename_bstab, 0);
#else
if (strpbrk (filename_hint, rl_filename_quote_characters))
#endif
{
fnhint = sh_backslash_quote (filename_hint, filename_bstab, 0);
rl_completion_found_quote = 4; /* just has to be non-zero */
}
else
fnhint = filename_hint;
free (current_path); /* XXX */
@@ -2333,10 +2403,20 @@ globword:
if (temp)
{
temp++;
#if 0
/* We're comparing an unquoted filename read from the directory
(temp, returned by rl_filename_completion_function) against
the possibly-quoted hint text. We should compare against
the dequoted hint text. */
if (igncase == 0)
freetemp = match = strncmp (temp, hint, hint_len) == 0;
else
freetemp = match = strncasecmp (temp, hint, hint_len) == 0;
#else
/* Why duplicate the comparison rl_filename_completion_function
already performs? */
freetemp = match = 1;
#endif
if (match)
temp = savestring (temp);
}
@@ -2421,7 +2501,7 @@ command_subst_completion_function (const char *text, int state)
filename_text = savestring (text);
if (matches)
{
free (matches);
strvec_dispose (matches);
matches = (char **)NULL;
}
@@ -3001,7 +3081,10 @@ _ignore_completion_names (char **names, sh_ignore_func_t *name_func)
char **newnames;
size_t idx, nidx;
char **oldnames;
int oidx;
int oidx, allow_empty;
/* allow_empty is used to make force_fignore apply only to FIGNORE completions. */
allow_empty = (name_func == name_is_acceptable) ? force_fignore : 1;
/* If there is only one completion, see if it is acceptable. If it is
not, free it up. In any case, short-circuit and return. This is a
@@ -3009,7 +3092,7 @@ _ignore_completion_names (char **names, sh_ignore_func_t *name_func)
if there is only one completion; it is the completion itself. */
if (names[1] == (char *)0)
{
if (force_fignore)
if (allow_empty)
if ((*name_func) (names[0]) == 0)
{
free (names[0]);
@@ -3025,7 +3108,7 @@ _ignore_completion_names (char **names, sh_ignore_func_t *name_func)
;
newnames = strvec_create (nidx + 1);
if (force_fignore == 0)
if (allow_empty == 0)
{
oldnames = strvec_create (nidx - 1);
oidx = 0;
@@ -3036,7 +3119,7 @@ _ignore_completion_names (char **names, sh_ignore_func_t *name_func)
{
if ((*name_func) (names[idx]))
newnames[nidx++] = names[idx];
else if (force_fignore == 0)
else if (allow_empty == 0)
oldnames[oidx++] = names[idx];
else
free (names[idx]);
@@ -3047,7 +3130,7 @@ _ignore_completion_names (char **names, sh_ignore_func_t *name_func)
/* If none are acceptable then let the completer handle it. */
if (nidx == 1)
{
if (force_fignore)
if (allow_empty)
{
free (names[0]);
names[0] = (char *)NULL;
@@ -3059,7 +3142,7 @@ _ignore_completion_names (char **names, sh_ignore_func_t *name_func)
return;
}
if (force_fignore == 0)
if (allow_empty == 0)
{
while (oidx)
free (oldnames[--oidx]);
@@ -3686,7 +3769,7 @@ build_history_completion_array (void)
}
/* Sort the complete list of tokens. */
if (dabbrev_expand_active == 0)
if (harry_len > 1 && dabbrev_expand_active == 0)
qsort (history_completion_array, harry_len, sizeof (char *), (QSFUNC *)strvec_strcmp);
}
}
@@ -4515,7 +4598,7 @@ uw_unbind_readline_variables (void *ignore)
int
bash_execute_unix_command (int count, int key)
{
int type;
int type, pflags;
register int i, r;
intmax_t mi;
sh_parser_state_t ps;
@@ -4597,7 +4680,8 @@ bash_execute_unix_command (int count, int key)
add_unwind_protect (uw_unbind_readline_variables, 0);
add_unwind_protect (uw_restore_parser_state, &ps);
add_unwind_protect (uw_rl_set_signals, 0);
r = parse_and_execute (savestring (cmd), "bash_execute_unix_command", SEVAL_NOHIST);
pflags = interactive_shell ? (SEVAL_NOTIFY|SEVAL_NOHIST) : SEVAL_NOHIST;
r = parse_and_execute (savestring (cmd), "bash_execute_unix_command", pflags);
rl_set_signals ();
restore_parser_state (&ps);
+4 -1
View File
@@ -444,9 +444,12 @@ mkseq (intmax_t start, intmax_t end, intmax_t incr, int type, size_t width)
return ((char **)NULL);
}
if (i >= nelem - 1)
break;
n += incr;
}
while (i < nelem - 1);
while (1);
result[i] = (char *)0;
return (result);
+44
View File
@@ -0,0 +1,44 @@
/* buildconf.h -- config definitions from build environment for tools needed
at build time */
/* Copyright (C) 2024 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (BUILDCONF_H_)
#define BUILDCONF_H_
/* assume C90/POSIX-1992 compilation environment if cross-compiling */
/* pacify glibc */
#ifndef _POSIX_C_SOURCE
# define _POSIX_C_SOURCE 2
# define _XOPEN_SOURCE 500
#endif
#define HAVE_LOCALE_H 1
#define HAVE_UNISTD_H 1
/* Don't assume this; it's from C99; let syntax.h define a replacement */
/* #undef HAVE_ISBLANK */
#undef PROCESS_SUBSTITUTION
#undef EXTENDED_GLOB
#endif /* BUILDCONF_H */
+44 -5
View File
@@ -56,6 +56,8 @@ BUILD_DIR = @BUILD_DIR@
LIBBUILD = ${BUILD_DIR}/lib
DEBUG = @DEBUG@
PROFILE_FLAGS = @PROFILE_FLAGS@
CFLAGS = @CFLAGS@
CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ @CROSS_COMPILE@
@@ -77,6 +79,9 @@ BASHINCDIR = ${topdir}/include
RL_INCLUDEDIR = @RL_INCLUDEDIR@
HIST_LIBSRC = ${topdir}/lib/readline
RL_LIBSRC = ${topdir}/lib/readline
INTL_LIBSRC = ${topdir}/lib/intl
INTL_BUILDDIR = ${LIBBUILD}/intl
INTL_LIBDIR = ${INTL_BUILDDIR}
@@ -92,9 +97,10 @@ HELPFILES_TARGET = @HELPFILES_TARGET@
INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$(srcdir) ${INTL_INC}
BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \
BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) \
${INCLUDES} $(STYLE_CFLAGS) $(LOCAL_CFLAGS)
ADDON_CFLAGS=
CCFLAGS = ${ADDON_CFLAGS} $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS)
CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
@@ -108,6 +114,8 @@ DIRECTDEFINE = -D $(srcdir)
HELPDIRDEFINE = @HELPDIRDEFINE@
HELPSTRINGS = @HELPSTRINGS@
STDCKDINT_H = @STDCKDINT_H@
# xxx this is bad style
RL_LIBSRC = $(topdir)/lib/readline
@@ -252,6 +260,8 @@ documentation: builtins.texi
builtins.texi: $(MKBUILTINS)
./$(MKBUILTINS) -documentonly $(DEFSRC)
.PHONY: basic-clean clean maintainer-clean distclean mostlyclean maybe-clean
clean:
$(RM) $(OFILES) $(CREATED_FILES) libbuiltins.a
$(RM) $(MKBUILTINS) gen-helpfiles $(CREATED_OBJECTS)
@@ -265,8 +275,9 @@ distclean maintainer-clean: clean
$(OFILES): $(MKBUILTINS) ../config.h
../version.h: ../config.h ../Makefile Makefile
-( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} version.h )
# sketchy rule here
#../version.h: ../config.h ../Makefile Makefile
# -( cd ${BUILD_DIR} && ${MAKE} ${BASH_MAKEFLAGS} version.h )
# maintainer special - for now
po: builtins.c
@@ -275,7 +286,7 @@ po: builtins.c
${LIBINTL_H}:
@echo making $@ in ${INTL_BUILDDIR}
@(cd ${INTL_BUILDDIR} && \
$(MAKE) $(MFLAGS) libintl.h) || exit 1
$(MAKE) $(BASH_MAKEFLAGS) libintl.h) || exit 1
# dependencies
@@ -556,6 +567,7 @@ printf.o: $(topdir)/bashtypes.h ${srcdir}/common.h $(BASHINCDIR)/chartypes.h
printf.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
printf.o: ../pathnames.h
printf.o: $(BASHINCDIR)/unlocked-io.h
printf.o: ${STDCKDINT_H} ${BASHINCDIR}/intprops-internal.h
pushd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
pushd.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
pushd.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
@@ -683,7 +695,34 @@ mapfile.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
mapfile.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/variables.h $(topdir)/conftypes.h
mapfile.o: $(topdir)/arrayfunc.h ../pathnames.h
#bind.o: $(RL_LIBSRC)chardefs.h $(RL_LIBSRC)readline.h $(RL_LIBSRC)keymaps.h
bind.o: $(RL_LIBSRC)/rlconf.h
bind.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/rlstdc.h
bind.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h
bind.o: $(RL_LIBSRC)/rltypedefs.h ${RL_LIBSRC}/rlmbutil.h
complete.o: $(RL_LIBSRC)/rlconf.h
complete.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/rlstdc.h
complete.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h
complete.o: $(RL_LIBSRC)/rltypedefs.h ${RL_LIBSRC}/rlmbutil.h
history.o: $(RL_LIBSRC)/rlconf.h
history.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/rlstdc.h
history.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h
history.o: $(RL_LIBSRC)/rltypedefs.h ${RL_LIBSRC}/rlmbutil.h
read.o: $(RL_LIBSRC)/rlconf.h
read.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/rlstdc.h
read.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h
read.o: $(RL_LIBSRC)/rltypedefs.h ${RL_LIBSRC}/rlmbutil.h
set.o: $(RL_LIBSRC)/rlconf.h
set.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/rlstdc.h
set.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h
set.o: $(RL_LIBSRC)/rltypedefs.h ${RL_LIBSRC}/rlmbutil.h
common.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h
evalfile.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h
evalstring.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h
bind.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h
fc.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h
history.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h
shopt.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h
# libintl dependencies
bind.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
+23 -17
View File
@@ -1,7 +1,7 @@
This file is bind.def, from which is created bind.c.
It implements the builtin "bind" in Bash.
Copyright (C) 1987-2023 Free Software Foundation, Inc.
Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -57,6 +57,9 @@ Options:
-X List key sequences bound with -x and associated commands
in a form that can be reused as input.
If arguments remain after option processing, the -p and -P options treat
them as readline command names and restrict output to those names.
Exit Status:
bind returns 0 unless an unrecognized option is given or an error occurs.
$END
@@ -114,6 +117,7 @@ bind_builtin (WORD_LIST *list)
Keymap kmap, saved_keymap;
int flags, opt;
char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq, *t;
WORD_LIST *savelist;
if (no_line_editing)
builtin_warning (_("line editing not enabled"));
@@ -220,24 +224,29 @@ bind_builtin (WORD_LIST *list)
if (flags & PFLAG)
{
#if 0 /* TAG:bash-5.3 */
if (list == 0)
if (shell_compatibility_level <= 52 || list == 0)
rl_function_dumper (1);
else
while (list)
{
rl_print_keybinding (list->word->word, kmap, 1);
list = list->next;
}
#else
rl_function_dumper (1);
#endif
{
/* Allow both -p and -P to have a crack at the additional
arguments, just like supplying both -p and -P without
arguments displays the full set of bindings twice in
two separate formats. Otherwise, -p takes all the
arguments and -P prints all the bindings. */
savelist = (flags & PPFLAG) ? list : (WORD_LIST *)NULL;
while (list)
{
rl_print_keybinding (list->word->word, kmap, 1);
list = list->next;
}
list = savelist;
}
}
/* should combine this with the above clause */
if (flags & PPFLAG)
{
#if 0 /* TAG:bash-5.3 */
if (list == 0)
if (shell_compatibility_level <= 52 || list == 0)
rl_function_dumper (0);
else
while (list)
@@ -245,9 +254,6 @@ bind_builtin (WORD_LIST *list)
rl_print_keybinding (list->word->word, kmap, 0);
list = list->next;
}
#else
rl_function_dumper (0);
#endif
}
@@ -268,7 +274,7 @@ bind_builtin (WORD_LIST *list)
if (rl_read_init_file (initfile) != 0)
{
t = printable_filename (initfile, 0);
builtin_error (_("%s: cannot read: %s"), t, strerror (errno));
builtin_error ("%s: %s: %s", t, _("cannot read"), strerror (errno));
if (t != initfile)
free (t);
BIND_RETURN (EXECUTION_FAILURE);
+1 -2
View File
@@ -330,13 +330,11 @@ cd_builtin (WORD_LIST *list)
return (EX_USAGE);
}
#endif
#if 0
else if (list->word->word[0] == '\0')
{
builtin_error (_("null directory")); /* POSIX cd implementation defined */
return (EXECUTION_FAILURE);
}
#endif
else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
{
/* This is `cd -', equivalent to `cd $OLDPWD' */
@@ -429,6 +427,7 @@ cd_builtin (WORD_LIST *list)
builtin_error ("%s: %s", temp, strerror (e));
if (temp != dirname)
free (temp);
/* posix says to return >1 if eflag && no_symlinks?? */
return (EXECUTION_FAILURE);
}
+2 -1
View File
@@ -32,7 +32,8 @@ on disk when a function with the same name exists.
Options:
-p use a default value for PATH that is guaranteed to find all of
the standard utilities
-v print a description of COMMAND similar to the `type' builtin
-v print a single word indicating the command or filename that
invokes COMMAND
-V print a more verbose description of each COMMAND
Exit Status:
+27 -7
View File
@@ -1,6 +1,6 @@
/* common.c - utility functions for all builtins */
/* Copyright (C) 1987-2023 Free Software Foundation, Inc.
/* Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -272,6 +272,13 @@ sh_nojobs (const char *s)
else
builtin_error (_("no job control"));
}
void
sh_invalidjob (const char *s)
{
builtin_error (_("%s: invalid job specification"), s);
}
#endif
#if defined (RESTRICTED_SHELL)
@@ -297,16 +304,16 @@ sh_wrerror (void)
#if defined (DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS) && defined (EPIPE)
if (errno != EPIPE)
#endif /* DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS && EPIPE */
builtin_error (_("write error: %s"), strerror (errno));
builtin_error ("%s: %s", _("write error"), strerror (errno));
}
void
sh_ttyerror (int set)
{
if (set)
builtin_error (_("error setting terminal attributes: %s"), strerror (errno));
builtin_error ("%s: %s", _("error setting terminal attributes"), strerror (errno));
else
builtin_error (_("error getting terminal attributes: %s"), strerror (errno));
builtin_error ("%s: %s", _("error getting terminal attributes"), strerror (errno));
}
int
@@ -531,6 +538,9 @@ get_exitstat (WORD_LIST *list)
return value. */
if (this_shell_builtin == return_builtin && running_trap > 0 && running_trap != DEBUG_TRAP+1 && trap_return_context == funcnest + sourcenest)
return (trap_saved_exit_value);
/* The same interp applies to the exit builtin. */
if (this_shell_builtin == exit_builtin && running_trap > 0 && running_trap != DEBUG_TRAP+1 && trap_return_context == funcnest + sourcenest)
return (trap_saved_exit_value);
return (last_command_exit_value);
}
@@ -596,9 +606,11 @@ get_working_directory (const char *for_whom)
#endif
if (the_current_working_directory == 0)
{
fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"),
(for_whom && *for_whom) ? for_whom : get_name_for_error (),
_(bash_getcwd_errstr), strerror (errno));
fprintf (stderr, "%s: %s: %s: %s\n",
(for_whom && *for_whom) ? for_whom : get_name_for_error (),
_("error retrieving current directory"),
_(bash_getcwd_errstr),
strerror (errno));
return (char *)NULL;
}
}
@@ -691,6 +703,14 @@ get_job_spec (WORD_LIST *list)
if (*word == '%')
word++;
else
#if 1
/* This could be builtin_error or sh_invalidjob() */
builtin_warning (_("%s: job specification requires leading `%%'"), word);
#else
/* TAG:bash-5.4 10/23/2024 */
return (BAD_JOBSPEC);
#endif
if (DIGIT (*word) && all_digits (word))
{
+3
View File
@@ -52,6 +52,7 @@ do { \
#define SEVAL_ONECMD 0x100 /* only allow a single command */
#define SEVAL_NOHISTEXP 0x200 /* inhibit history expansion */
#define SEVAL_NOOPTIMIZE 0x400 /* don't try to set optimization flags */
#define SEVAL_NOTIFY 0x800 /* want job notifications */
/* Flags for describe_command, shared between type.def and command.def */
#define CDESC_ALL 0x001 /* type -a */
@@ -102,6 +103,7 @@ extern void sh_erange (const char *, const char *);
extern void sh_badpid (const char *);
extern void sh_badjob (const char *);
extern void sh_nojobs (const char *);
extern void sh_invalidjob (const char *);
extern void sh_restricted (const char *);
extern void sh_notbuiltin (const char *);
extern void sh_wrerror (void);
@@ -215,6 +217,7 @@ extern int parse_and_execute (char *, const char *, int);
extern int evalstring (char *, const char *, int);
extern void parse_and_execute_cleanup (int);
extern int parse_string (char *, const char *, int, COMMAND **, char **);
extern int should_optimize_fork (COMMAND *, int);
extern int should_suppress_fork (COMMAND *);
extern int can_optimize_connection (COMMAND *);
extern int can_optimize_cat_file (COMMAND *);
+8 -12
View File
@@ -1,7 +1,7 @@
This file is declare.def, from which is created declare.c.
It implements the builtins "declare" and "local" in Bash.
Copyright (C) 1987-2023 Free Software Foundation, Inc.
Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -112,6 +112,9 @@ Define local variables.
Create a local variable called NAME, and give it VALUE. OPTION can
be any option accepted by `declare'.
If any NAME is "-", local saves the set of shell options and restores
them when the function returns.
Local variables can only be used within a function; they are visible
only to the function where they are defined and its children.
@@ -152,12 +155,8 @@ declare_find_variable (const char *name, int mkglobal, int chklocal)
if (mkglobal == 0)
return (find_variable (name));
else if (chklocal)
{
var = find_variable (name);
if (var && local_p (var) && var->context == variable_context)
return var;
return (find_global_variable (name));
}
/* Changed to find variables at previous local scopes 6/12/2024 */
return (find_variable (name));
else
return (find_global_variable (name));
}
@@ -314,7 +313,7 @@ declare_internal (WORD_LIST *list, int local_var)
case 'f':
*flags |= att_function;
break;
case 'G':
case 'G': /* undocumented, used internally */
if (flags == &flags_on)
chklocal = 1;
/*FALLTHROUGH*/
@@ -879,7 +878,7 @@ restart_new_var_name:
NEXT_VARIABLE ();
}
/* Cannot use declare to assign value to readonly or noassign variable. */
else if ((readonly_p (var) || noassign_p (var)) && offset)
else if (ASSIGN_DISALLOWED (var, 0) && offset)
{
if (readonly_p (var))
{
@@ -890,8 +889,6 @@ restart_new_var_name:
EXECUTION_FAILURE would cause set -e to exit the shell. */
NEXT_VARIABLE ();
}
#if 1
/* TAG:bash-5.3 20240216 */
/* Cannot set or unset invalid attributes on readonly variables */
else if (readonly_p (var) && ((flags_on & invalid_readonly_attrs) || (flags_off & invalid_readonly_attrs)))
{
@@ -901,7 +898,6 @@ restart_new_var_name:
any_failed++;
NEXT_VARIABLE ();
}
#endif
#if defined (ARRAY_VARS)
/* Array variable error checking. */
+5 -1
View File
@@ -1,7 +1,7 @@
This file is enable.def, from which is created enable.c.
It implements the builtin "enable" in Bash.
Copyright (C) 1987-2023 Free Software Foundation, Inc.
Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -233,7 +233,11 @@ enable_builtin (WORD_LIST *list)
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
/* If we try to enable a non-existent builtin, and we have dynamic
loading, try the equivalent of `enable -f name name'. */
#if defined (RESTRICTED_SHELL)
if (*command && (flags & NFLAG) == 0 && opt == EX_NOTFOUND && restricted == 0)
#else
if (*command && (flags & NFLAG) == 0 && opt == EX_NOTFOUND)
#endif
{
int dflags, r;
+24 -18
View File
@@ -1,6 +1,6 @@
/* evalfile.c - read and evaluate commands from a file or file descriptor */
/* Copyright (C) 1996-2017,2022-2023 Free Software Foundation, Inc.
/* Copyright (C) 1996-2017,2022-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -58,7 +58,7 @@
extern int errno;
#endif
/* Flags for _evalfile() */
/* Flags for evalfile_internal() */
#define FEVAL_ENOENTOK 0x001
#define FEVAL_BUILTIN 0x002
#define FEVAL_UNWINDPROT 0x004
@@ -74,11 +74,12 @@ extern int errno;
int sourcelevel = 0;
static int
_evalfile (const char *filename, int flags)
evalfile_internal (const char *filename, int flags)
{
volatile int old_interactive;
procenv_t old_return_catch;
int return_val, fd, result, pflags, i, nnull;
int return_val, fd, result, pflags, nnull;
size_t i;
ssize_t nr; /* return value from read(2) */
char *string;
struct stat finfo;
@@ -101,19 +102,19 @@ _evalfile (const char *filename, int flags)
do
{
fd = open (filename, O_RDONLY);
i = errno;
if (fd < 0 && i == EINTR)
result = errno;
if (fd < 0 && result == EINTR)
QUIT;
errno = i;
errno = result;
}
while (fd < 0 && errno == EINTR && (flags & FEVAL_RETRY));
if (fd < 0 || (fstat (fd, &finfo) == -1))
{
i = errno;
result = errno;
if (fd >= 0)
close (fd);
errno = i;
errno = result;
file_error_and_exit:
if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
@@ -185,7 +186,7 @@ file_error_and_exit:
check_binary_file (string, (nr > 80) ? 80 : nr))
{
free (string);
(*errfunc) (_("%s: cannot execute binary file"), filename);
(*errfunc) ("%s: %s", filename, _("cannot execute binary file"));
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
}
@@ -203,7 +204,7 @@ file_error_and_exit:
if ((flags & FEVAL_BUILTIN) && ++nnull > 256)
{
free (string);
(*errfunc) (_("%s: cannot execute binary file"), filename);
(*errfunc) ("%s: %s", filename, _("cannot execute binary file"));
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
}
}
@@ -211,13 +212,14 @@ file_error_and_exit:
if (flags & FEVAL_UNWINDPROT)
{
begin_unwind_frame ("_evalfile");
begin_unwind_frame ("evalfile_internal");
unwind_protect_int (return_catch_flag);
unwind_protect_jmp_buf (return_catch);
if (flags & FEVAL_NONINT)
unwind_protect_int (interactive);
unwind_protect_int (sourcelevel);
unwind_protect_int (want_job_notifications);
unwind_protect_int (retain_fifos);
}
else
@@ -232,6 +234,8 @@ file_error_and_exit:
return_catch_flag++;
sourcelevel++;
if (interactive_shell && shell_compatibility_level <= 52)
want_job_notifications++;
retain_fifos++; /* XXX */
@@ -244,7 +248,7 @@ file_error_and_exit:
GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
# endif
array_push (bash_source_a, (char *)filename);
push_source (bash_source_a, (char *)filename);
t = itos (executing_line_number ());
array_push (bash_lineno_a, t);
free (t);
@@ -296,7 +300,7 @@ file_error_and_exit:
result = parse_and_execute (string, filename, pflags);
if (flags & FEVAL_UNWINDPROT)
run_unwind_frame ("_evalfile");
run_unwind_frame ("evalfile_internal");
else
{
if (flags & FEVAL_NONINT)
@@ -315,6 +319,8 @@ file_error_and_exit:
#endif
return_catch_flag--;
sourcelevel--;
if (interactive_shell && shell_compatibility_level <= 52)
want_job_notifications--;
retain_fifos--;
COPY_PROCENV (old_return_catch, return_catch);
}
@@ -337,7 +343,7 @@ maybe_execute_file (const char *fname, int force_noninteractive)
flags = FEVAL_ENOENTOK|FEVAL_RETRY;
if (force_noninteractive)
flags |= FEVAL_NONINT;
result = _evalfile (filename, flags);
result = evalfile_internal (filename, flags);
free (filename);
return result;
}
@@ -352,7 +358,7 @@ force_execute_file (const char *fname, int force_noninteractive)
flags = FEVAL_RETRY;
if (force_noninteractive)
flags |= FEVAL_NONINT;
result = _evalfile (filename, flags);
result = evalfile_internal (filename, flags);
free (filename);
return result;
}
@@ -367,7 +373,7 @@ fc_execute_file (const char *filename)
remember_on_history is set. We use FEVAL_BUILTIN to return
the result of parse_and_execute. */
flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE|FEVAL_BUILTIN;
return (_evalfile (filename, flags));
return (evalfile_internal (filename, flags));
}
#endif /* HISTORY */
@@ -382,7 +388,7 @@ source_file (const char *filename, int sflags)
/* POSIX shells exit if non-interactive and file error. */
if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0)
flags |= FEVAL_LONGJMP;
rval = _evalfile (filename, flags);
rval = evalfile_internal (filename, flags);
run_return_trap ();
return rval;
+22 -6
View File
@@ -1,6 +1,6 @@
/* evalstring.c - evaluate a string as one or more shell commands. */
/* Copyright (C) 1996-2023 Free Software Foundation, Inc.
/* Copyright (C) 1996-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -109,6 +109,7 @@ should_optimize_fork (COMMAND *command, int subshell)
command->type == cm_simple &&
signal_is_trapped (EXIT_TRAP) == 0 &&
signal_is_trapped (ERROR_TRAP) == 0 &&
(variable_context == 0 || signal_is_trapped (RETURN_TRAP) == 0) &&
any_signals_trapped () < 0 &&
(subshell || (command->redirects == 0 && command->value.Simple->redirects == 0)) &&
((command->flags & CMD_TIME_PIPELINE) == 0) &&
@@ -137,7 +138,7 @@ should_suppress_fork (COMMAND *command)
int
can_optimize_connection (COMMAND *command)
{
return (*bash_input.location.string == '\0' &&
return ((bash_input.type != st_string || *bash_input.location.string == '\0') &&
parser_expanding_alias () == 0 &&
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') &&
command->value.Connection->second->type == cm_simple);
@@ -187,11 +188,11 @@ optimize_shell_function (COMMAND *command)
fc->flags |= CMD_NO_FORK;
fc->value.Simple->flags |= CMD_NO_FORK;
}
else if (fc->type == cm_connection && can_optimize_connection (fc) && should_suppress_fork (fc->value.Connection->second))
else if (fc->type == cm_connection && can_optimize_connection (fc))
{
fc->value.Connection->second->flags |= CMD_NO_FORK;
fc->value.Connection->second->value.Simple->flags |= CMD_NO_FORK;
}
fc->value.Connection->second->flags |= CMD_TRY_OPTIMIZING;
fc->value.Connection->second->value.Simple->flags |= CMD_TRY_OPTIMIZING;
}
}
int
@@ -247,6 +248,8 @@ parse_prologue (char *string, int flags, char *tag)
unwind_protect_int (builtin_ignoring_errexit);
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
unwind_protect_int (interactive);
if (flags & SEVAL_NOTIFY)
unwind_protect_int (want_job_notifications);
#if defined (HISTORY)
if (parse_and_execute_level == 0)
@@ -281,6 +284,9 @@ parse_prologue (char *string, int flags, char *tag)
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
if (flags & SEVAL_NOTIFY)
want_job_notifications = 1;
#if defined (HISTORY)
if (flags & SEVAL_NOHIST)
bash_history_disable ();
@@ -302,6 +308,7 @@ parse_prologue (char *string, int flags, char *tag)
(flags & SEVAL_RESETLINE) -> reset line_number to 1
(flags & SEVAL_NOHISTEXP) -> history_expansion_inhibited -> 1
(flags & SEVAL_NOOPTIMIZE) -> don't try to turn on optimizing flags
(flags & SEVAL_NOTIFY) -> print job status notifications
*/
int
@@ -541,6 +548,9 @@ parse_and_execute (char *string, const char *from_file, int flags)
if ((subshell_environment & SUBSHELL_COMSUB) || executing_funsub)
expand_aliases = expaliases_flag;
/* This functionality is now implemented as part of
subst.c:command_substitute(). */
#if 0
/* See if this is a candidate for $( <file ). */
if (startup_state == 2 &&
(subshell_environment & SUBSHELL_COMSUB) &&
@@ -548,10 +558,12 @@ parse_and_execute (char *string, const char *from_file, int flags)
can_optimize_cat_file (command))
{
int r;
INTERNAL_DEBUG(("parse_and_execute: calling cat_file, parse_and_execute_level = %d", parse_and_execute_level));
r = cat_file (command->value.Simple->redirects);
last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
}
else
#endif
last_result = execute_command_internal
(command, 0, NO_PIPE, NO_PIPE, bitmap);
dispose_command (command);
@@ -694,6 +706,10 @@ parse_string (char *string, const char *from_file, int flags, COMMAND **cmdp, ch
else
dispose_command (global_command);
global_command = (COMMAND *)NULL;
/* Presumably this is an error if we haven't consumed the
entire string, but we let the caller deal with it. */
if (flags & SEVAL_ONECMD)
break;
}
else
{
+16 -13
View File
@@ -1,7 +1,7 @@
This file is exec.def, from which is created exec.c.
It implements the builtin "exec" in Bash.
Copyright (C) 1987-2021,2022 Free Software Foundation, Inc.
Copyright (C) 1987-2021,2022,2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -154,9 +154,9 @@ exec_builtin (WORD_LIST *list)
if (file_isdir (args[0]))
{
#if defined (EISDIR)
builtin_error (_("%s: cannot execute: %s"), args[0], strerror (EISDIR));
builtin_error ("%s: %s: %s", args[0], _("cannot execute"), strerror (EISDIR));
#else
builtin_error (_("%s: cannot execute: %s"), args[0], strerror (errno));
builtin_error ("%s: %s: %s", args[0], _("cannot execute"), strerror (errno));
#endif
exit_value = EX_NOEXEC;
}
@@ -230,23 +230,26 @@ exec_builtin (WORD_LIST *list)
exit_value = shell_execve (command, args, env);
opt = errno;
/* We have to set this to NULL because shell_execve has called realloc()
to stuff more items at the front of the array, which may have caused
the memory to be freed by realloc(). We don't want to free it twice. */
args = (char **)NULL;
if (cleanenv == 0)
adjust_shell_level (1);
if (exit_value == EX_NOTFOUND) /* no duplicate error message */
/* These are the return statuses for which shell_execve will print a message. */
if (exit_value == EX_NOTFOUND || exit_value == EX_BINARY_FILE || exit_value == EX_NOEXEC)
goto failed_exec;
else if (executable_file (command) == 0)
/* These are the errno values for which shell_execve will print a message. */
#if defined (EISDIR)
else if (opt == EISDIR || opt == E2BIG || opt == ENOMEM)
#else
else if (opt == E2BIG || opt == ENOMEM)
#endif
goto failed_exec;
else /* catchall */
{
builtin_error ("%s: %s: %s", command, _("cannot execute"), strerror (opt));
if (executable_file (command) == 0)
exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
errno = opt;
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:
FREE (command);
+3 -2
View File
@@ -1,7 +1,7 @@
This file is exit.def, from which is created exit.c.
It implements the builtins "exit", and "logout" in Bash.
Copyright (C) 1987-2023 Free Software Foundation, Inc.
Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -138,7 +138,8 @@ exit_or_logout (WORD_LIST *list)
/* If we're running the exit trap (running_trap == 1, since running_trap
gets set to SIG+1), and we don't have a argument given to `exit'
(list == 0), use the exit status we saved before running the trap
commands (trap_saved_exit_value). */
commands (trap_saved_exit_value). get_exitstat() handles the case of
running exit from any other trap action (POSIX interp 1602). */
exit_value = (running_trap == 1 && list == 0) ? trap_saved_exit_value : get_exitstat (list);
if (exit_value > EX_SHERRBASE) /* some kind of error */
return (exit_value);
+1 -1
View File
@@ -459,7 +459,7 @@ fc_builtin (WORD_LIST *list)
stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn);
if (stream == 0)
{
builtin_error (_("%s: cannot open temp file: %s"), fn ? fn : "", strerror (errno));
builtin_error ("%s: %s: %s", fn ? fn : "", _("cannot open temp file"), strerror (errno));
FREE (fn);
return (EXECUTION_FAILURE);
}
+4 -2
View File
@@ -1,7 +1,7 @@
This file is fg_bg.def, from which is created fg_bg.c.
It implements the builtins "bg" and "fg" in Bash.
Copyright (C) 1987-2022 Free Software Foundation, Inc.
Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -144,7 +144,9 @@ fg_bg (WORD_LIST *list, int foreground)
if (INVALID_JOB (job))
{
if (job != DUP_JOB)
if (job == BAD_JOBSPEC)
sh_invalidjob (list->word->word);
else if (job != DUP_JOB)
sh_badjob (list ? list->word->word : _("current"));
goto failure;
+2 -2
View File
@@ -1,7 +1,7 @@
This file is getopts.def, from which is created getopts.c.
It implements the builtin "getopts" in Bash.
Copyright (C) 1987-2023 Free Software Foundation, Inc.
Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -117,7 +117,7 @@ getopts_bind_variable (char *name, char *value)
if (valid_identifier (name))
{
v = bind_variable (name, value, 0);
if (v && (readonly_p (v) || noassign_p (v)))
if (v && ASSIGN_DISALLOWED (v, 0))
return (EX_MISCERROR);
return (v ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
+1 -1
View File
@@ -156,7 +156,7 @@ hash_builtin (WORD_LIST *list)
#if defined (RESTRICTED_SHELL)
if (restricted && pathname)
{
if (strchr (pathname, '/'))
if (absolute_program (pathname))
{
sh_restricted (pathname);
return (EXECUTION_FAILURE);
+5 -7
View File
@@ -211,7 +211,7 @@ open_helpfile (const char *name)
fd = open (name, O_RDONLY);
if (fd == -1)
{
builtin_error (_("%s: cannot open: %s"), name, strerror (errno));
builtin_error ("%s: %s: %s", name, _("cannot open"), strerror (errno));
return -1;
}
return fd;
@@ -265,12 +265,10 @@ show_desc (char *name, int i)
line = doc ? doc[0] : (char *)NULL;
printf ("%s - ", name);
for (j = 0; line && line[j]; j++)
{
putchar (line[j]);
if (line[j] == '\n')
break;
}
/* Don't assume LINE ends with a newline. */
for (j = 0; line && line[j] && line[j] != '\n'; j++)
putchar (line[j]);
putchar ('\n');
fflush (stdout);
+1 -1
View File
@@ -282,7 +282,7 @@ history_builtin (WORD_LIST *list)
}
#if defined (RESTRICTED_SHELL)
if (restricted && strchr (filename, '/'))
if (restricted && absolute_program (filename))
{
sh_restricted (filename);
return (EXECUTION_FAILURE);
+8 -4
View File
@@ -138,7 +138,7 @@ jobs_builtin (WORD_LIST *list)
list_all_jobs (form);
/* POSIX says to remove terminated jobs from the list after the jobs
builtin reports their status. */
notify_and_cleanup (); /* the notify part will be a no-op */
notify_and_cleanup (-1); /* the notify part will be a no-op */
break;
case JSTATE_RUNNING:
list_running_jobs (form);
@@ -155,7 +155,7 @@ jobs_builtin (WORD_LIST *list)
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
if ((job == NO_JOB) || jobs == 0 || get_job_by_jid (job) == 0)
if ((job == NO_JOB) || jobs == 0 || INVALID_JOB (job) || get_job_by_jid (job) == 0)
{
sh_badjob (list->word->word);
any_failed++;
@@ -168,7 +168,8 @@ jobs_builtin (WORD_LIST *list)
}
/* POSIX says to remove terminated jobs from the list after the jobs
builtin reports their status. */
notify_and_cleanup ();
if (posixly_correct == 0 || interactive_shell == 0 || interactive == 0)
notify_and_cleanup (-1); /* XXX - why here? list_one_job already deletes dead jobs */
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
@@ -286,7 +287,10 @@ disown_builtin (WORD_LIST *list)
if (job == NO_JOB || jobs == 0 || INVALID_JOB (job))
{
sh_badjob (list ? list->word->word : _("current"));
if (job == BAD_JOBSPEC)
sh_invalidjob (list->word->word);
else
sh_badjob (list ? list->word->word : _("current"));
retval = EXECUTION_FAILURE;
}
else if (nohup_only)
+4
View File
@@ -207,7 +207,11 @@ use_sigspec:
#if defined (JOB_CONTROL)
else if (*list->word->word && *list->word->word != '%')
{
#if 1
sh_badpid (list->word->word);
#else
builtin_error (_("%s: arguments must be process or job IDs"), list->word->word);
#endif
CONTINUE_OR_FAIL;
}
else if (*word)
+2 -2
View File
@@ -2,7 +2,7 @@ This file is mapfile.def, from which is created mapfile.c.
It implements the builtin "mapfile" in Bash.
Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
Copyright (C) 2008-2023 Free Software Foundation, Inc.
Copyright (C) 2008-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -254,7 +254,7 @@ mapfile_builtin (WORD_LIST *list)
if (sh_validfd (fd) == 0)
{
builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
builtin_error ("%d: %s: %s", fd, _("invalid file descriptor"), strerror (errno));
return (EXECUTION_FAILURE);
}
break;
+38 -63
View File
@@ -111,7 +111,7 @@ extern int errno;
SHELL_VAR *v; \
v = builtin_bind_variable (vname, vbuf, bindflags); \
stupidly_hack_special_variables (vname); \
if (v == 0 || readonly_p (v) || noassign_p (v)) \
if (v == 0 || ASSIGN_DISALLOWED (v, 0)) \
retval = EXECUTION_FAILURE; \
if (vbsize > 4096) \
{ \
@@ -209,11 +209,13 @@ static uintmax_t getuintmax (void);
typedef long double floatmax_t;
# define USE_LONG_DOUBLE 1
# define FLOATMAX_CONV "L"
# define FLOATMAX_CONVLEN 1
# define strtofltmax strtold
#else
typedef double floatmax_t;
# define USE_LONG_DOUBLE 0
# define FLOATMAX_CONV ""
# define FLOATMAX_CONVLEN 0
# define strtofltmax strtod
#endif
static double getdouble (void);
@@ -334,7 +336,7 @@ printf_builtin (WORD_LIST *list)
SHELL_VAR *v;
v = builtin_bind_variable (vname, "", 0);
stupidly_hack_special_variables (vname);
return ((v == 0 || readonly_p (v) || noassign_p (v)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
return ((v == 0 || ASSIGN_DISALLOWED (v, 0)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
/* If the format string is empty after preprocessing, return immediately. */
@@ -536,6 +538,7 @@ printf_builtin (WORD_LIST *list)
}
#endif
#if 0 /*TAG:bash-5.4*/
/* If altform, treat like %b */
if (altform == 0)
#endif
{
@@ -594,8 +597,8 @@ printf_builtin (WORD_LIST *list)
break;
*t++ = *fmt++;
}
*t = '\0';
if (*++fmt != 'T')
*t = '\0'; /*(*/
if (*fmt != ')' || *++fmt != 'T')
{
builtin_warning (_("`%c': invalid time format specification"), *fmt);
fmt = start;
@@ -699,7 +702,7 @@ printf_builtin (WORD_LIST *list)
/* check for string length overflow when adjusting precision */
if (ckd_add (&precision, slen, 0))
{
builtin_error (_("%%Q: string length: %s"), strerror (ERANGE));
builtin_error ("%%Q: %s %s", _("string length"), strerror (ERANGE));
precision = -1;
}
}
@@ -781,7 +784,7 @@ printf_builtin (WORD_LIST *list)
floatmax_t p;
p = getfloatmax ();
f = mklong (start, "L", 1);
f = mklong (start, FLOATMAX_CONV, FLOATMAX_CONVLEN);
PF (f, p);
}
else /* posixly_correct */
@@ -824,7 +827,7 @@ printf_builtin (WORD_LIST *list)
static inline void
printf_erange (char *s)
{
builtin_error (_("%s: %s"), s, strerror(ERANGE));
builtin_error ("%s: %s", s, strerror(ERANGE));
conversion_error = 1;
}
@@ -1352,6 +1355,24 @@ getstr (void)
return ret;
}
/* POSIX.2 says ``...a diagnostic message shall be written to standard
error, and the utility shall not exit with a zero exit status, but
shall continue processing any remaining operands and shall write the
value accumulated at the time the error was detected to standard
output.'' */
static inline void
chk_converror (char *s, char *ep)
{
if (*ep || ep == s)
{
sh_invalidnum (s);
conversion_error = 1;
}
else if (errno == ERANGE)
printf_erange (s);
}
/* Don't call getintmax here because it may consume an argument on error, and
we call this to get field width/precision arguments. */
static int
@@ -1369,15 +1390,10 @@ getint (int overflow_retval)
errno = 0;
ret = strtoimax (garglist->word->word, &ep, 0);
overflow = (errno == ERANGE) || (ret < INT_MIN || ret > INT_MAX);
if (overflow = (errno == ERANGE) || (ret < INT_MIN || ret > INT_MAX))
errno = ERANGE; /* force errno */
if (*ep)
{
sh_invalidnum (garglist->word->word);
conversion_error = 1;
}
else if (overflow)
printf_erange (garglist->word->word);
chk_converror (garglist->word->word, ep);
garglist = garglist->next;
return (overflow ? overflow_retval : (int)ret);
@@ -1398,21 +1414,7 @@ getintmax (void)
errno = 0;
ret = strtoimax (garglist->word->word, &ep, 0);
if (*ep)
{
sh_invalidnum (garglist->word->word);
/* POSIX.2 says ``...a diagnostic message shall be written to standard
error, and the utility shall not exit with a zero exit status, but
shall continue processing any remaining operands and shall write the
value accumulated at the time the error was detected to standard
output.'' Yecch. */
#if 0
ret = 0; /* return partially-converted value from strtoimax */
#endif
conversion_error = 1;
}
else if (errno == ERANGE)
printf_erange (garglist->word->word);
chk_converror (garglist->word->word, ep);
garglist = garglist->next;
return (ret);
@@ -1432,18 +1434,8 @@ getuintmax (void)
errno = 0;
ret = strtoumax (garglist->word->word, &ep, 0);
if (*ep)
{
sh_invalidnum (garglist->word->word);
#if 0
/* Same POSIX.2 conversion error requirements as getintmax(). */
ret = 0;
#endif
conversion_error = 1;
}
else if (errno == ERANGE)
printf_erange (garglist->word->word);
chk_converror (garglist->word->word, ep);
garglist = garglist->next;
return (ret);
@@ -1464,13 +1456,7 @@ getdouble (void)
errno = 0;
ret = strtod (garglist->word->word, &ep);
if (*ep)
{
sh_invalidnum (garglist->word->word);
conversion_error = 1;
}
else if (errno == ERANGE)
printf_erange (garglist->word->word);
chk_converror (garglist->word->word, ep);
garglist = garglist->next;
return (ret);
@@ -1491,17 +1477,7 @@ getfloatmax (void)
errno = 0;
ret = strtofltmax (garglist->word->word, &ep);
if (*ep)
{
sh_invalidnum (garglist->word->word);
#if 0
/* Same thing about POSIX.2 conversion error requirements. */
ret = 0;
#endif
conversion_error = 1;
}
else if (errno == ERANGE)
printf_erange (garglist->word->word);
chk_converror (garglist->word->word, ep);
garglist = garglist->next;
return (ret);
@@ -1514,8 +1490,7 @@ asciicode (void)
register intmax_t ch;
#if defined (HANDLE_MULTIBYTE)
wchar_t wc;
size_t slen;
int mblength;
size_t slen, mblength;
#endif
DECLARE_MBSTATE;
@@ -1523,7 +1498,7 @@ asciicode (void)
slen = strlen (garglist->word->word+1);
wc = 0;
mblength = mbrtowc (&wc, garglist->word->word+1, slen, &state);
if (mblength > 0)
if (MB_INVALIDCH (mblength) == 0)
ch = wc; /* XXX */
else
#endif
+112 -39
View File
@@ -1,7 +1,7 @@
This file is read.def, from which is created read.c.
It implements the builtin "read" in Bash.
Copyright (C) 1987-2023 Free Software Foundation, Inc.
Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -122,7 +122,7 @@ struct ttsave
#if defined (READLINE)
static void uw_reset_attempted_completion_function (void *);
static int set_itext (void);
static char *edit_line (char *, char *, unsigned char, int);
static char *edit_line (char *, char *, int, int);
static void set_eol_delim (int);
static void reset_eol_delim (void *);
static void set_readline_timeout (sh_timer *t, time_t, long);
@@ -130,7 +130,7 @@ static void uw_bashline_reset_event_hook (void *);
#endif
static SHELL_VAR *bind_read_variable (char *, char *, int);
#if defined (HANDLE_MULTIBYTE)
static int read_mbchar (int, char *, int, int, int);
static int read_mbchar (int, char *, int, int, int, int);
#endif
static void ttyrestore (struct ttsave *);
static void uw_ttyrestore (void *);
@@ -201,6 +201,21 @@ read_builtin_timeout (int fd)
#endif
}
#if defined (READLINE)
void
reset_rl_instream (FILE *save_instream)
{
fclose (rl_instream);
rl_instream = save_instream;
}
void
uw_reset_rl_instream (void *fp)
{
reset_rl_instream (fp);
}
#endif
/* 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
@@ -224,7 +239,7 @@ read_builtin (WORD_LIST *list)
long ival, uval;
intmax_t intval;
char c;
unsigned char delim;
int delim;
char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
char *e, *t, *t1, *ps2, *tofree;
struct stat tsb;
@@ -340,7 +355,6 @@ read_builtin (WORD_LIST *list)
break;
case 'N':
ignore_delim = 1;
delim = -1;
case 'n':
nflag = 1;
code = valid_number (list_optarg, &intval);
@@ -363,12 +377,12 @@ read_builtin (WORD_LIST *list)
fd = intval;
if (sh_validfd (fd) == 0)
{
builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
builtin_error ("%d: %s: %s", fd, _("invalid file descriptor"), strerror (errno));
return (EXECUTION_FAILURE);
}
break;
case 'd':
delim = *list_optarg;
delim = (unsigned char)*list_optarg;
break;
CASE_HELPOPT;
default:
@@ -543,11 +557,7 @@ read_builtin (WORD_LIST *list)
add_unwind_protect (uw_reset_timeout, NULL);
#if defined (READLINE)
if (edit)
{
add_unwind_protect (uw_reset_attempted_completion_function, NULL);
add_unwind_protect (uw_bashline_reset_event_hook, NULL);
set_readline_timeout (read_timeout, tmsec, tmusec);
}
set_readline_timeout (read_timeout, tmsec, tmusec);
else
#endif
shtimer_set (read_timeout, tmsec, tmusec);
@@ -613,12 +623,34 @@ read_builtin (WORD_LIST *list)
save_instream = 0;
if (edit && fd != 0)
{
int fd2;
FILE *fp2;
if ((fd2 = dup (fd)) < 0 || (fp2 = fdopen (fd2, "r")) == 0)
{
builtin_error ("%d: %s", fd, strerror (errno));
if (fd2 >= 0)
close (fd2);
run_unwind_frame ("read_builtin");
if (free_ifs)
free (ifs_chars);
return (EXECUTION_FAILURE);
}
if (bash_readline_initialized == 0)
initialize_readline ();
unwind_protect_var (rl_instream);
save_instream = rl_instream;
rl_instream = fdopen (fd, "r");
rl_instream = fp2;
add_unwind_protect (uw_reset_rl_instream, save_instream);
fd = fd2;
}
if (edit)
{
add_unwind_protect (uw_reset_attempted_completion_function, NULL);
add_unwind_protect (uw_bashline_reset_event_hook, NULL);
}
#endif
@@ -719,6 +751,7 @@ read_builtin (WORD_LIST *list)
x = errno;
if (retval < 0 && errno == EINTR)
{
ZRESET ();
check_signals (); /* in case we didn't call zread via zreadc */
lastsig = LASTSIG();
if (lastsig == 0)
@@ -737,6 +770,10 @@ read_builtin (WORD_LIST *list)
break;
}
/* Even if read returns a partial buffer, if we got an interrupt we're
going to throw it away. */
ZRESET();
QUIT; /* in case we didn't call check_signals() */
#if defined (READLINE)
}
@@ -792,7 +829,7 @@ read_builtin (WORD_LIST *list)
continue;
}
if (ignore_delim == 0 && (unsigned char)c == delim)
if ((unsigned char)c == delim)
break;
if (c == '\0' && delim != '\0')
@@ -806,7 +843,6 @@ read_builtin (WORD_LIST *list)
add_char:
input_string[i++] = c;
check_read_timeout ();
#if defined (HANDLE_MULTIBYTE)
/* XXX - what if C == 127? Can DEL introduce a multibyte sequence? */
@@ -833,7 +869,7 @@ add_char:
else
# endif
if (locale_utf8locale == 0 || ((c & 0x80) != 0))
i += read_mbchar (fd, input_string, i, c, unbuffered_read);
i += read_mbchar (fd, input_string, i, c, delim, unbuffered_read);
}
#endif
@@ -841,6 +877,8 @@ add_char:
if (nchars > 0 && nr >= nchars)
break;
check_read_timeout ();
}
/* Back up over trailing CTLESC if the input ends with an unescaped
backslash */
@@ -854,7 +892,10 @@ add_char:
saw_escape = 0; /* Avoid dequoting bare CTLNUL */
input_string[i] = '\0';
check_read_timeout ();
/* Don't check the timeout unless we didn't read anything and zread returned
EOF or error. */
if (i == 0 && retval <= 0)
check_read_timeout ();
#if defined (READLINE)
if (edit)
@@ -865,8 +906,10 @@ add_char:
{
t_errno = errno;
if (errno != EINTR)
builtin_error (_("read error: %d: %s"), fd, strerror (errno));
builtin_error ("%d: %s: %s", fd, _("read error"), strerror (errno));
run_unwind_frame ("read_builtin");
if (free_ifs)
free (ifs_chars);
return ((t_errno != EINTR) ? EXECUTION_FAILURE : 128+lastsig);
}
@@ -896,7 +939,7 @@ add_char:
#if defined (READLINE)
if (save_instream)
rl_instream = save_instream; /* can't portably free it */
reset_rl_instream (save_instream);
#endif
discard_unwind_frame ("read_builtin");
@@ -916,6 +959,8 @@ assign_vars:
if (var == 0)
{
free (input_string);
if (free_ifs)
free (ifs_chars);
return EXECUTION_FAILURE; /* readonly or noassign */
}
@@ -930,6 +975,8 @@ assign_vars:
dispose_words (alist);
}
free (input_string);
if (free_ifs)
free (ifs_chars);
return (retval);
}
#endif /* ARRAY_VARS */
@@ -960,12 +1007,14 @@ assign_vars:
}
else
var = bind_variable ("REPLY", input_string, 0);
if (var == 0 || readonly_p (var) || noassign_p (var))
if (var == 0 || ASSIGN_DISALLOWED (var, 0))
retval = EX_MISCERROR;
else
VUNSETATTR (var, att_invisible);
free (input_string);
if (free_ifs)
free (ifs_chars);
return (retval);
}
@@ -990,6 +1039,8 @@ assign_vars:
{
sh_invalidid (varname);
free (orig_input_string);
if (free_ifs)
free (ifs_chars);
return (EXECUTION_FAILURE);
}
@@ -1022,6 +1073,8 @@ assign_vars:
if (var == 0)
{
free (orig_input_string);
if (free_ifs)
free (ifs_chars);
return (EX_MISCERROR);
}
@@ -1039,6 +1092,8 @@ assign_vars:
{
sh_invalidid (list->word->word);
free (orig_input_string);
if (free_ifs)
free (ifs_chars);
return (EXECUTION_FAILURE);
}
@@ -1096,13 +1151,12 @@ bind_read_variable (char *name, char *value, int flags)
SHELL_VAR *v;
v = builtin_bind_variable (name, value, flags);
return (v == 0 ? v
: ((readonly_p (v) || noassign_p (v)) ? (SHELL_VAR *)NULL : v));
return ((v == 0 || ASSIGN_DISALLOWED (v, 0)) ? (SHELL_VAR *)NULL : v);
}
#if defined (HANDLE_MULTIBYTE)
static int
read_mbchar (int fd, char *string, int ind, int ch, int unbuffered)
read_mbchar (int fd, char *string, int ind, int ch, int delim, int unbuffered)
{
char mbchar[MB_LEN_MAX + 1];
int i, n, r;
@@ -1136,8 +1190,21 @@ read_mbchar (int fd, char *string, int ind, int ch, int unbuffered)
mbchar[i++] = c;
continue;
}
else if (ret == (size_t)-1 || ret == (size_t)0 || ret > (size_t)0)
break;
else if (ret == (size_t)-1)
{
/* If we read a delimiter character that makes this an invalid
multibyte character, we can't just add it to the input string
and treat it as a byte. We need to push it back so a subsequent
zread will pick it up. */
if ((unsigned char)c == delim)
{
zungetc ((unsigned char)c);
mbchar[--i] = '\0'; /* unget the delimiter */
}
break; /* invalid multibyte character */
}
else if (ret == (size_t)0 || ret > (size_t)0)
break; /* valid multibyte character */
}
mbchar_return:
@@ -1213,7 +1280,7 @@ set_itext (void)
}
static char *
edit_line (char *p, char *itext, unsigned char delim, int keep_completion_func)
edit_line (char *p, char *itext, int delim, int keep_completion_func)
{
char *ret;
size_t len;
@@ -1253,7 +1320,8 @@ edit_line (char *p, char *itext, unsigned char delim, int keep_completion_func)
len = strlen (ret);
ret = (char *)xrealloc (ret, len + 2);
ret[len++] = delim;
if (delim > 0)
ret[len++] = delim;
ret[len] = '\0';
return ret;
}
@@ -1271,7 +1339,7 @@ static rl_command_func_t *old_delim_func;
static int old_newline_ctype;
static rl_command_func_t *old_newline_func;
static unsigned char delim_char;
static int delim_char;
static void
set_eol_delim (int c)
@@ -1282,19 +1350,21 @@ set_eol_delim (int c)
initialize_readline ();
cmap = rl_get_keymap ();
/* Save the old delimiter char binding */
/* Save the old newline binding and change it to self-insert */
old_newline_ctype = cmap[RETURN].type;
old_newline_func = cmap[RETURN].function;
old_delim_ctype = cmap[c].type;
old_delim_func = cmap[c].function;
/* Change newline to self-insert */
cmap[RETURN].type = ISFUNC;
cmap[RETURN].function = rl_insert;
/* Bind the delimiter character to accept-line. */
cmap[c].type = ISFUNC;
cmap[c].function = rl_newline;
/* Save any binding to the delimiter and bind the delimiter to accept-line */
if (c >= 0)
{
old_delim_ctype = cmap[c].type;
old_delim_func = cmap[c].function;
cmap[c].type = ISFUNC;
cmap[c].function = rl_newline;
}
delim_char = c;
}
@@ -1309,7 +1379,10 @@ reset_eol_delim (void *ignore)
cmap[RETURN].type = old_newline_ctype;
cmap[RETURN].function = old_newline_func;
cmap[delim_char].type = old_delim_ctype;
cmap[delim_char].function = old_delim_func;
if (delim_char >= 0)
{
cmap[delim_char].type = old_delim_ctype;
cmap[delim_char].function = old_delim_func;
}
}
#endif
+12 -6
View File
@@ -52,8 +52,6 @@ $END
#include <stdio.h>
#include "version.h"
#include "../bashintl.h"
#include "../shell.h"
@@ -97,6 +95,7 @@ extern int localvar_unset;
extern int varassign_redir_autoclose;
extern int singlequote_translations;
extern int patsub_replacement;
extern int bash_source_fullpath;
#if defined (EXTENDED_GLOB)
extern int extended_glob;
@@ -177,10 +176,13 @@ static struct {
int *value;
shopt_set_func_t *set_func;
} shopt_vars[] = {
{ "autocd", &autocd, (shopt_set_func_t *)NULL },
#if defined (ARRAY_VARS)
{ "array_expand_once", &expand_once_flag, set_array_expand },
{ "assoc_expand_once", &expand_once_flag, set_array_expand },
#endif
{ "autocd", &autocd, (shopt_set_func_t *)NULL },
#if defined (ARRAY_VARS)
{ "bash_source_fullpath", &bash_source_fullpath, (shopt_set_func_t *)NULL },
#endif
{ "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
{ "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
@@ -375,6 +377,7 @@ reset_shopt_options (void)
varassign_redir_autoclose = 0;
singlequote_translations = 0;
patsub_replacement = PATSUB_REPLACE_DEFAULT;
bash_source_fullpath = BASH_SOURCE_FULLPATH_DEFAULT;
#if defined (JOB_CONTROL)
check_jobs_at_exit = 0;
@@ -684,10 +687,10 @@ set_compatibility_level (char *option_name, int mode)
shell_compatibility_level = 43;
else if (shopt_compat44)
shell_compatibility_level = 44;
else if (oldval > 44 && shell_compatibility_level < DEFAULT_COMPAT_LEVEL)
else if (oldval > 44 && shell_compatibility_level < default_compatibility_level)
;
else
shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
shell_compatibility_level = default_compatibility_level;
/* Make sure the current compatibility level is reflected in BASH_COMPAT */
rhs = itos (shell_compatibility_level);
@@ -705,9 +708,12 @@ set_compatibility_opts (void)
shopt_compat31 = shopt_compat32 = 0;
shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0;
shopt_compat44 = 0;
if (shell_compatibility_level == default_compatibility_level)
return;
switch (shell_compatibility_level)
{
case DEFAULT_COMPAT_LEVEL:
case 52: /* completeness */
case 51: /* completeness */
case 50:
break;
+45 -19
View File
@@ -1,7 +1,7 @@
This file is source.def, from which is created source.c.
It implements the builtins "." and "source" in Bash.
Copyright (C) 1987-2023 Free Software Foundation, Inc.
Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -22,13 +22,14 @@ $PRODUCES source.c
$BUILTIN source
$FUNCTION source_builtin
$SHORT_DOC source filename [arguments]
$SHORT_DOC source [-p path] filename [arguments]
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.
Read and execute commands from FILENAME in the current shell. If the
-p option is supplied, the PATH argument is treated as a colon-
separated list of directories to search for FILENAME. If -p is not
supplied, $PATH is searched to find FILENAME. If any ARGUMENTS are
supplied, they become the positional parameters when FILENAME is executed.
Exit Status:
Returns the status of the last command executed in FILENAME; fails if
@@ -38,13 +39,14 @@ $END
$BUILTIN .
$DOCNAME dot
$FUNCTION source_builtin
$SHORT_DOC . filename [arguments]
$SHORT_DOC . [-p path] filename [arguments]
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.
Read and execute commands from FILENAME in the current shell. If the
-p option is supplied, the PATH argument is treated as a colon-
separated list of directories to search for FILENAME. If -p is not
supplied, $PATH is searched to find FILENAME. If any ARGUMENTS are
supplied, they become the positional parameters when FILENAME is executed.
Exit Status:
Returns the status of the last command executed in FILENAME; fails if
@@ -82,7 +84,8 @@ extern int errno;
static void uw_maybe_pop_dollar_vars (void *);
/* If non-zero, `.' uses $PATH to look up the script to be sourced. */
/* If non-zero, `.' uses $PATH to look up the script to be sourced when -p is
not supplied. */
int source_uses_path = 1;
/* If non-zero, `.' looks in the current directory if the filename argument
@@ -115,11 +118,24 @@ uw_maybe_pop_dollar_vars (void *ignore)
int
source_builtin (WORD_LIST *list)
{
int result;
char *filename, *debug_trap, *x;
int result, search_cwd, opt;
char *filename, *debug_trap, *x, *pathstring;
if (no_options (list))
return (EX_USAGE);
pathstring = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "p:")) != -1)
{
switch (opt)
{
case 'p':
pathstring = list_optarg;
break;
CASE_HELPOPT;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (list == 0)
@@ -130,24 +146,34 @@ source_builtin (WORD_LIST *list)
}
#if defined (RESTRICTED_SHELL)
if (restricted && strchr (list->word->word, '/'))
if (restricted && (pathstring || absolute_program (list->word->word)))
{
sh_restricted (list->word->word);
return (EXECUTION_FAILURE);
}
#endif
/* normalize pathstring */
if (pathstring && *pathstring == 0)
pathstring = ".";
/* XXX - If we supply -p PATH, don't default to searching $PWD */
search_cwd = pathstring == 0 && source_searches_cwd;
filename = (char *)NULL;
/* XXX -- should this be absolute_pathname? */
if (posixly_correct && strchr (list->word->word, '/'))
if (posixly_correct && absolute_program (list->word->word))
filename = savestring (list->word->word);
else if (absolute_pathname (list->word->word))
filename = savestring (list->word->word);
else if (pathstring)
filename = find_in_path (list->word->word, pathstring, FS_READABLE);
else if (source_uses_path)
filename = find_path_file (list->word->word);
if (filename == 0)
{
if (source_searches_cwd == 0)
if (search_cwd == 0)
{
x = printable_filename (list->word->word, 0);
builtin_error (_("%s: file not found"), x);
+15 -8
View File
@@ -68,6 +68,9 @@ Values are in 1024-byte increments, except for -t, which is in seconds;
-b, which is in bytes; and -e, -i, -k, -n, -q, -r, -u, -x, and -P,
which accept unscaled values.
When in posix mode, values supplied with -c and -f are in 512-byte
increments.
Exit Status:
Returns success unless an invalid option is supplied or an error occurs.
$END
@@ -456,8 +459,9 @@ ulimit_internal (int cmd, char *cmdarg, int mode, int multiple)
opt = get_limit (limind, &soft_limit, &hard_limit);
if (opt < 0)
{
builtin_error (_("%s: cannot get limit: %s"), limits[limind].description,
strerror (errno));
builtin_error ("%s: %s: %s", limits[limind].description,
_("cannot get limit"),
strerror (errno));
return (EXECUTION_FAILURE);
}
@@ -501,8 +505,9 @@ ulimit_internal (int cmd, char *cmdarg, int mode, int multiple)
if (set_limit (limind, real_limit, mode) < 0)
{
builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description,
strerror (errno));
builtin_error ("%s: %s: %s", limits[limind].description,
_("cannot modify limit"),
strerror (errno));
return (EXECUTION_FAILURE);
}
@@ -724,8 +729,9 @@ print_all_limits (int mode)
if (get_limit (i, &softlim, &hardlim) == 0)
printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
else if (errno != EINVAL)
builtin_error ("%s: cannot get limit: %s", limits[i].description,
strerror (errno));
builtin_error ("%s: %s: %s", limits[i].description,
_("cannot get limit"),
strerror (errno));
}
}
@@ -787,8 +793,9 @@ set_all_limits (int mode, RLIMTYPE newlim)
for (retval = i = 0; limits[i].option > 0; i++)
if (set_limit (i, newlim, mode) < 0)
{
builtin_error (_("%s: cannot modify limit: %s"), limits[i].description,
strerror (errno));
builtin_error ("%s: %s: %s", limits[i].description,
_("cannot modify limit"),
strerror (errno));
retval = 1;
}
return retval;
+61 -17
View File
@@ -92,7 +92,7 @@ int wait_intr_flag;
static int set_waitlist (WORD_LIST *);
static void unset_waitlist (void);
static int check_bgpids (WORD_LIST *, struct procstat *);
static int check_nonjobs (WORD_LIST *, struct procstat *);
/* Wait for the pid in LIST to stop or die. If no arguments are given, then
wait for all of the active background processes of the shell and return
@@ -211,12 +211,13 @@ wait_builtin (WORD_LIST *list)
#if defined (JOB_CONTROL)
if (nflag)
{
#if 0 /* TAG:bash-5.3 stevenpelley@gmail.com 01/22/2024 */
#if 1 /* TAG:bash-5.3 stevenpelley@gmail.com 01/22/2024 */
/* First let's see if there are any requested pids that have already
been removed from the jobs list and saved on bgpids. */
been removed from the jobs list and saved on bgpids or are terminated
procsubs. */
if (list)
{
status = check_bgpids (list, &pstat);
status = check_nonjobs (list, &pstat);
if (status != -1)
{
if (vname)
@@ -343,29 +344,49 @@ wait_builtin (WORD_LIST *list)
#if defined (JOB_CONTROL)
/* Take each valid pid or jobspec in LIST and mark the corresponding job as
J_WAITING, so wait -n knows which jobs to wait for. Return the number of
jobs we found. */
J_WAITING, so wait -n knows which jobs to wait for.
If we have process substitutions, allow wait -n to wait for procsubs by
pid by marking them with PROC_WAITING.
Return the number of jobs or procsubs we found. */
static int
set_waitlist (WORD_LIST *list)
{
sigset_t set, oset;
int job, njob;
intmax_t pid;
intmax_t ipid;
pid_t pid;
PROCESS *child;
WORD_LIST *l;
BLOCK_CHILD (set, oset);
njob = 0;
for (l = list; l; l = l->next)
{
job = NO_JOB;
job = (l && l->word && valid_number (l->word->word, &pid) && pid == (pid_t) pid)
? get_job_by_pid ((pid_t) pid, 0, 0)
: get_job_spec (l);
child = NULL;
pid = (l && l->word && valid_number (l->word->word, &ipid) && ipid == (pid_t)ipid) ? (pid_t)ipid : NO_PID;
job = (pid != NO_PID) ? get_job_by_pid (pid, 0, 0) : get_job_spec (l);
if (job == NO_JOB || jobs == 0 || INVALID_JOB (job))
{
sh_badjob (l->word->word);
#if defined (PROCESS_SUBSTITUTION)
child = (pid >= 0) ? procsub_search (pid, 0) : NULL;
#endif
if (child)
{
/* If we don't have a valid job, maybe we have a procsub */
njob++;
child->flags |= PROC_WAITING;
}
else if (l->word->word[0] == '%')
sh_badjob (l->word->word);
else if (job == BAD_JOBSPEC)
sh_invalidjob (l->word->word);
else
sh_badpid (l->word->word);
continue;
}
/* We don't check yet to see if one of the desired jobs has already
terminated, but we could. We wait until wait_for_any_job(). This
has the advantage of validating all the arguments. */
@@ -390,17 +411,22 @@ unset_waitlist (void)
for (i = 0; i < js.j_jobslots; i++)
if (jobs[i] && (jobs[i]->flags & J_WAITING))
jobs[i]->flags &= ~J_WAITING;
#if defined (PROCESS_SUBSTITUTION)
procsub_unsetflag (ANY_PID, PROC_WAITING, 0);
#endif
UNBLOCK_CHILD (oset);
}
#if 0 /* TAG:bash-5.3 */
/* For each pid in LIST, check the bgpids list and the procsub list, if we
have process substitutions. */
static int
check_bgpids (WORD_LIST *list, struct procstat *pstat)
check_nonjobs (WORD_LIST *list, struct procstat *pstat)
{
sigset_t set, oset;
pid_t pid;
intmax_t ipid;
WORD_LIST *l;
PROCESS *child;
int r, s;
r = -1;
@@ -408,11 +434,17 @@ check_bgpids (WORD_LIST *list, struct procstat *pstat)
BLOCK_CHILD (set, oset);
for (l = list; l; l = l->next)
{
if (l && valid_number (l->word->word, &ipid) && ipid == (pid_t) ipid)
if (l && valid_number (l->word->word, &ipid) && ipid == (pid_t) ipid && ipid >= 0)
pid = ipid;
else
else if (l && l->word->word[0] == '%')
continue; /* skip job ids for now */
else
{
r = -1;
continue;
}
/* check bgpids */
if ((s = retrieve_proc_status (pid, 0)) != -1)
{
pstat->pid = pid;
@@ -423,10 +455,22 @@ check_bgpids (WORD_LIST *list, struct procstat *pstat)
delete_proc_status (pid, 0);
break;
}
#if defined (PROCESS_SUBSTITUTION)
/* If this corresponds to a terminated procsub, return it. */
if ((child = procsub_search (pid, 0)) && child->running == PS_DONE)
{
pstat->pid = pid;
pstat->status = r = process_exit_status (child->status);
procsub_delete (pid, 0); /* moves to bgpids list */
if (posixly_correct)
delete_proc_status (pid, 0);
break;
}
#endif
}
UNBLOCK_CHILD (oset);
return r;
}
#endif
#endif
+6 -3
View File
@@ -47,7 +47,7 @@
/* Define DONT_REPORT_SIGTERM if you don't want to see `Terminated' message
when a job exits due to SIGTERM, since that's the default signal sent
by the kill builtin. */
by the kill builtin. Only effective for non-interactive shells. */
#define DONT_REPORT_SIGTERM
/* Define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS if you don't want builtins
@@ -139,9 +139,8 @@
/* Define as 1 if you want to enable code that implements multiple coprocs
executing simultaneously */
/* TAG: bash-5.3 */
#ifndef MULTIPLE_COPROCS
# define MULTIPLE_COPROCS 0
# define MULTIPLE_COPROCS 1
#endif
/* Define to 0 if you want the checkwinsize option off by default, 1 if you
@@ -206,3 +205,7 @@
#ifndef PATSUB_REPLACE_DEFAULT
#define PATSUB_REPLACE_DEFAULT 1
#endif
/* Define to 1 if you want posix mode to restrict shell function names to
shell NAMEs. */
/* #define POSIX_RESTRICT_FUNCNAME 0 */
+9
View File
@@ -178,6 +178,9 @@
/* Define to allow functions to be imported from the environment. */
#undef FUNCTION_IMPORT
/* Define to make the `bash_source_fullpath' option enabled by default. */
#undef BASH_SOURCE_FULLPATH_DEFAULT
/* Define AFS if you are using Transarc's AFS. */
#undef AFS
@@ -944,6 +947,12 @@
/* Define if you have the tcgetpgrp function. */
#undef HAVE_TCGETPGRP
/* Define if you have the tcgetwinsize function. */
#undef HAVE_TCGETWINSIZE
/* Define if you have the tcsetwinsize function. */
#undef HAVE_TCSETWINSIZE
/* Define if you have the times function. */
#undef HAVE_TIMES
Vendored
+195 -263
View File
@@ -1,7 +1,7 @@
#! /bin/sh
# From configure.ac for Bash 5.3, version 5.063.
# From configure.ac for Bash 5.3, version 5.074.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.72 for bash 5.3-alpha.
# Generated by GNU Autoconf 2.72 for bash 5.3-beta.
#
# Report bugs to <bug-bash@gnu.org>.
#
@@ -605,8 +605,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='bash'
PACKAGE_TARNAME='bash'
PACKAGE_VERSION='5.3-alpha'
PACKAGE_STRING='bash 5.3-alpha'
PACKAGE_VERSION='5.3-beta'
PACKAGE_STRING='bash 5.3-beta'
PACKAGE_BUGREPORT='bug-bash@gnu.org'
PACKAGE_URL=''
@@ -649,6 +649,7 @@ gl_use_threads_default=
gl_use_winpthreads_default=
enable_year2038=no
ac_subst_vars='LTLIBOBJS
STDCKDINT_H
LOCAL_DEFS
LOCAL_LDFLAGS
LOCAL_CFLAGS
@@ -748,6 +749,7 @@ INSTALL_DATA
INSTALL_SCRIPT
INSTALL_PROGRAM
TILDE_LIB
HIST_INCLUDEDIR
HIST_LIBDIR
HISTORY_DEP
HISTORY_LIB
@@ -761,7 +763,6 @@ RL_MAJOR
RL_VERSION
LIBS_FOR_BUILD
STYLE_CFLAGS
BASE_CFLAGS_FOR_BUILD
STATIC_LD
SIGNAMES_O
SIGNAMES_H
@@ -852,6 +853,7 @@ enable_alt_array_implementation
enable_arith_for_command
enable_array_variables
enable_bang_history
enable_bash_source_fullpath_default
enable_brace_expansion
enable_casemod_attributes
enable_casemod_expansions
@@ -1463,7 +1465,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
'configure' configures bash 5.3-alpha to adapt to many kinds of systems.
'configure' configures bash 5.3-beta to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1529,7 +1531,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of bash 5.3-alpha:";;
short | recursive ) echo "Configuration of bash 5.3-beta:";;
esac
cat <<\_ACEOF
@@ -1547,6 +1549,8 @@ Optional Features:
--enable-array-variables
include shell array variables
--enable-bang-history turn on csh-style history substitution
--enable-bash-source-fullpath-default
enable the bash_source_fullpath option by default
--enable-brace-expansion
include brace expansion
--enable-casemod-attributes
@@ -1735,7 +1739,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
bash configure 5.3-alpha
bash configure 5.3-beta
generated by GNU Autoconf 2.72
Copyright (C) 2023 Free Software Foundation, Inc.
@@ -2413,7 +2417,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by bash $as_me 5.3-alpha, which was
It was created by bash $as_me 5.3-beta, which was
generated by GNU Autoconf 2.72. Invocation command line was
$ $0$ac_configure_args_raw
@@ -3208,11 +3212,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_config_headers="$ac_config_headers config.h"
ac_config_headers="$ac_config_headers config.h buildconf.h"
BASHVERS=5.3
RELSTATUS=alpha
RELSTATUS=beta
case "$RELSTATUS" in
alp*|bet*|dev*|rc*|releng*|maint*) DEBUG='-DDEBUG' MALLOC_DEBUG='-DMALLOC_DEBUG' ;;
@@ -3455,6 +3459,7 @@ opt_function_import=yes
opt_dev_fd_stat_broken=no
opt_alt_array_impl=no
opt_translatable_strings=yes
opt_bash_source_fullpath_default=no
ARRAY_O=array.o
@@ -3480,6 +3485,7 @@ if test $opt_minimal_config = yes; then
opt_casemod_attrs=no opt_casemod_expansions=no opt_extglob_default=no
opt_translatable_strings=no
opt_globascii_default=yes
opt_bash_source_fullpath_default=no
fi
# Check whether --enable-alias was given.
@@ -3512,6 +3518,12 @@ then :
enableval=$enable_bang_history; opt_bang_history=$enableval
fi
# Check whether --enable-bash-source-fullpath-default was given.
if test ${enable_bash_source_fullpath_default+y}
then :
enableval=$enable_bash_source_fullpath_default; opt_bash_source_fullpath_default=$enableval
fi
# Check whether --enable-brace-expansion was given.
if test ${enable_brace_expansion+y}
then :
@@ -3877,6 +3889,13 @@ fi
if test $opt_translatable_strings = yes; then
printf "%s\n" "#define TRANSLATABLE_STRINGS 1" >>confdefs.h
fi
if test $opt_bash_source_fullpath_default = yes; then
printf "%s\n" "#define BASH_SOURCE_FULLPATH_DEFAULT 1" >>confdefs.h
else
printf "%s\n" "#define BASH_SOURCE_FULLPATH_DEFAULT 0" >>confdefs.h
fi
if test $opt_memscramble = yes; then
@@ -5330,30 +5349,30 @@ SIGNAMES_H=lsignames.h
CROSS_COMPILE=
if test "x$cross_compiling" = "xyes"; then
case "${host}" in
*-cygwin*)
cross_cache=${srcdir}/cross-build/cygwin32.cache
;;
*-msys*)
cross_cache=${srcdir}/cross-build/msys32.cache
;;
*-mingw*)
cross_cache=${srcdir}/cross-build/cygwin32.cache
;;
i[3456]86-*-beos*)
cross_cache=${srcdir}/cross-build/x86-beos.cache
;;
*-qnx*)
cross_cache=${srcdir}/cross-build/qnx.cache
;;
*) echo "configure: cross-compiling for $host is not supported" >&2
;;
esac
if test -n "${cross_cache}" && test -r "${cross_cache}"; then
echo "loading cross-build cache file ${cross_cache}"
. ${cross_cache}
fi
unset cross_cache
# case "${host}" in
# *-cygwin*)
# cross_cache=${srcdir}/cross-build/cygwin32.cache
# ;;
# *-msys*)
# cross_cache=${srcdir}/cross-build/msys32.cache
# ;;
# *-mingw*)
# cross_cache=${srcdir}/cross-build/cygwin32.cache
# ;;
# i[[3456]]86-*-beos*)
# cross_cache=${srcdir}/cross-build/x86-beos.cache
# ;;
# *-qnx*)
# cross_cache=${srcdir}/cross-build/qnx.cache
# ;;
# *) echo "configure: cross-compiling for $host is not supported" >&2
# ;;
# esac
# if test -n "${cross_cache}" && test -r "${cross_cache}"; then
# echo "loading cross-build cache file ${cross_cache}"
# . ${cross_cache}
# fi
# unset cross_cache
SIGNAMES_O='signames.o'
CROSS_COMPILE='-DCROSS_COMPILING'
@@ -5405,11 +5424,9 @@ if test "X$cross_compiling" = "Xno"; then
# CFLAGS set above to default value if not passed in environment
if test -n "$want_auto_cflags" ; then
CFLAGS_FOR_BUILD="${CFLAGS}"
BASE_CFLAGS_FOR_BUILD="${CFLAGS}"
else
# passed in environment
CFLAGS_FOR_BUILD=${CFLAGS-'$(CFLAGS)'}
BASE_CFLAGS_FOR_BUILD=${CFLAGS-'$(CFLAGS)'}
fi
LIBS_FOR_BUILD=${LIBS_FOR_BUILD-'$(LIBS)'}
else
@@ -5417,7 +5434,6 @@ else
CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-""}
LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-""}
CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD="-g"}
BASE_CFLAGS_FOR_BUILD=${BASE_CFLAGS_FOR_BUILD="-g"}
LIBS_FOR_BUILD=${LIBS_FOR_BUILD-""}
fi
@@ -5435,7 +5451,6 @@ fi
if test "$opt_readline" = yes && test "$opt_with_installed_readline" != "no"
then
# If the user specified --with-installed-readline=PREFIX and PREFIX
@@ -5599,53 +5614,6 @@ printf "%s\n" "$ac_cv_lib_curses_tgetent" >&6; }
if test "x$ac_cv_lib_curses_tgetent" = xyes
then :
bash_cv_termcap_lib=libcurses
else case e in #(
e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5
printf %s "checking for tgetent in -lncurses... " >&6; }
if test ${ac_cv_lib_ncurses_tgetent+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) ac_check_lib_save_LIBS=$LIBS
LIBS="-lncurses $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply.
The 'extern "C"' is for builds by C++ compilers;
although this is not generally supported in C code supporting it here
has little cost and some practical benefit (sr 110532). */
#ifdef __cplusplus
extern "C"
#endif
char tgetent (void);
int
main (void)
{
return tgetent ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_lib_ncurses_tgetent=yes
else case e in #(
e) ac_cv_lib_ncurses_tgetent=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tgetent" >&5
printf "%s\n" "$ac_cv_lib_ncurses_tgetent" >&6; }
if test "x$ac_cv_lib_ncurses_tgetent" = xyes
then :
bash_cv_termcap_lib=libncurses
else case e in #(
e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncursesw" >&5
printf %s "checking for tgetent in -lncursesw... " >&6; }
@@ -5693,6 +5661,53 @@ printf "%s\n" "$ac_cv_lib_ncursesw_tgetent" >&6; }
if test "x$ac_cv_lib_ncursesw_tgetent" = xyes
then :
bash_cv_termcap_lib=libncursesw
else case e in #(
e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5
printf %s "checking for tgetent in -lncurses... " >&6; }
if test ${ac_cv_lib_ncurses_tgetent+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) ac_check_lib_save_LIBS=$LIBS
LIBS="-lncurses $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply.
The 'extern "C"' is for builds by C++ compilers;
although this is not generally supported in C code supporting it here
has little cost and some practical benefit (sr 110532). */
#ifdef __cplusplus
extern "C"
#endif
char tgetent (void);
int
main (void)
{
return tgetent ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_lib_ncurses_tgetent=yes
else case e in #(
e) ac_cv_lib_ncurses_tgetent=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tgetent" >&5
printf "%s\n" "$ac_cv_lib_ncurses_tgetent" >&6; }
if test "x$ac_cv_lib_ncurses_tgetent" = xyes
then :
bash_cv_termcap_lib=libncurses
else case e in #(
e) bash_cv_termcap_lib=gnutermcap ;;
esac
@@ -5732,6 +5747,9 @@ TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libtinfo; then
TERMCAP_LIB=-ltinfo
TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libncursesw; then
TERMCAP_LIB=-lncursesw
TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libncurses; then
TERMCAP_LIB=-lncurses
TERMCAP_DEP=
@@ -5929,6 +5947,8 @@ if test $opt_readline = yes; then
else
RL_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
READLINE_DEP='$(READLINE_LIBRARY)'
# for dependencies
RL_INCLUDEDIR='$(RL_LIBDIR)'
# section for OS versions that ship an older/broken version of
# readline as a standard dynamic library and don't allow a
# static version specified as -llibname to override the
@@ -5941,6 +5961,7 @@ if test $opt_readline = yes; then
else
RL_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
READLINE_LIB= READLINE_DEP=
RL_INCLUDEDIR=
fi
if test $opt_history = yes || test $opt_bang_history = yes; then
if test $opt_history = yes; then
@@ -5966,6 +5987,8 @@ if test $opt_history = yes || test $opt_bang_history = yes; then
else
HIST_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
HISTORY_DEP='$(HISTORY_LIBRARY)'
# for dependencies
HIST_INCLUDEDIR='$(HIST_LIBDIR)'
# section for OS versions that ship an older version of
# readline as a standard dynamic library and don't allow a
# static version specified as -llibname to override the
@@ -5978,6 +6001,7 @@ if test $opt_history = yes || test $opt_bang_history = yes; then
else
HIST_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
HISTORY_LIB= HISTORY_DEP=
HIST_INCLUDEDIR=
fi
@@ -5991,6 +6015,7 @@ fi
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
@@ -9197,8 +9222,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
LIBS=$save_LIBS
test $gl_pthread_api = yes && break
done
echo "$as_me:9200: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9201: LIBPTHREAD=$LIBPTHREAD" >&5
echo "$as_me:9225: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9226: LIBPTHREAD=$LIBPTHREAD" >&5
gl_pthread_in_glibc=no
# On Linux with glibc >= 2.34, libc contains the fully functional
@@ -9224,7 +9249,7 @@ rm -rf conftest*
;;
esac
echo "$as_me:9227: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
echo "$as_me:9252: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
# Test for libpthread by looking for pthread_kill. (Not pthread_self,
# since it is defined as a macro on OSF/1.)
@@ -9402,7 +9427,7 @@ fi
fi
fi
echo "$as_me:9405: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
echo "$as_me:9430: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5
printf %s "checking whether POSIX threads API is available... " >&6; }
@@ -9649,8 +9674,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
LIBS=$save_LIBS
test $gl_pthread_api = yes && break
done
echo "$as_me:9652: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9653: LIBPTHREAD=$LIBPTHREAD" >&5
echo "$as_me:9677: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9678: LIBPTHREAD=$LIBPTHREAD" >&5
gl_pthread_in_glibc=no
# On Linux with glibc >= 2.34, libc contains the fully functional
@@ -9676,7 +9701,7 @@ rm -rf conftest*
;;
esac
echo "$as_me:9679: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
echo "$as_me:9704: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
# Test for libpthread by looking for pthread_kill. (Not pthread_self,
# since it is defined as a macro on OSF/1.)
@@ -9854,7 +9879,7 @@ fi
fi
fi
echo "$as_me:9857: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
echo "$as_me:9882: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5
printf %s "checking whether POSIX threads API is available... " >&6; }
@@ -15757,6 +15782,18 @@ if test "x$ac_cv_func_tcgetattr" = xyes
then :
printf "%s\n" "#define HAVE_TCGETATTR 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "tcgetwinsize" "ac_cv_func_tcgetwinsize"
if test "x$ac_cv_func_tcgetwinsize" = xyes
then :
printf "%s\n" "#define HAVE_TCGETWINSIZE 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "tcsetwinsize" "ac_cv_func_tcsetwinsize"
if test "x$ac_cv_func_tcsetwinsize" = xyes
then :
printf "%s\n" "#define HAVE_TCSETWINSIZE 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "times" "ac_cv_func_times"
if test "x$ac_cv_func_times" = xyes
@@ -16902,7 +16939,7 @@ INTL_DEP= INTL_INC= LIBINTL_H=
if test "x$USE_INCLUDED_LIBINTL" = "xyes"; then
INTL_DEP='${INTL_LIBDIR}/libintl.a'
INTL_INC='-I${INTL_LIBSRC} -I${INTL_BUILDDIR}'
LIBINTL_H='${INTL_BUILDDIR}/libintl.h'
LIBINTL_H='${INTL_LIBDIR}/libintl.h'
printf "%s\n" "#define HAVE_LOCALE_CHARSET 1" >>confdefs.h
@@ -18564,29 +18601,6 @@ printf "%s\n" "#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long" >>confdefs.h
ac_fn_c_check_type "$LINENO" "u_int" "ac_cv_type_u_int" "$ac_includes_default"
if test "x$ac_cv_type_u_int" = xyes
then :
else case e in #(
e)
printf "%s\n" "#define u_int unsigned int" >>confdefs.h
;;
esac
fi
ac_fn_c_check_type "$LINENO" "u_long" "ac_cv_type_u_long" "$ac_includes_default"
if test "x$ac_cv_type_u_long" = xyes
then :
else case e in #(
e)
printf "%s\n" "#define u_long unsigned long" >>confdefs.h
;;
esac
fi
if test "$ac_cv_sizeof_short" = 2; then
ac_fn_c_check_type "$LINENO" "bits16_t" "ac_cv_type_bits16_t" "$ac_includes_default"
@@ -19893,13 +19907,6 @@ fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct dirent.d_ino" >&5
printf %s "checking for struct dirent.d_ino... " >&6; }
if test ${bash_cv_dirent_has_d_ino+y}
then :
printf %s "(cached) " >&6
else case e in #(
e)
ac_fn_c_check_member "$LINENO" "struct dirent" "d_ino" "ac_cv_member_struct_dirent_d_ino" "
#include <stdio.h>
@@ -19928,31 +19935,11 @@ then :
printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_INO 1" >>confdefs.h
bash_cv_dirent_has_d_ino=yes
else case e in #(
e) bash_cv_dirent_has_d_ino=no ;;
esac
fi
;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $bash_cv_dirent_has_d_ino" >&5
printf "%s\n" "$bash_cv_dirent_has_d_ino" >&6; }
if test $bash_cv_dirent_has_d_ino = yes; then
printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_INO 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct dirent.d_fileno" >&5
printf %s "checking for struct dirent.d_fileno... " >&6; }
if test ${bash_cv_dirent_has_d_fileno+y}
then :
printf %s "(cached) " >&6
else case e in #(
e)
ac_fn_c_check_member "$LINENO" "struct dirent" "d_fileno" "ac_cv_member_struct_dirent_d_fileno" "
#include <stdio.h>
@@ -19981,31 +19968,11 @@ then :
printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_FILENO 1" >>confdefs.h
bash_cv_dirent_has_d_fileno=yes
else case e in #(
e) bash_cv_dirent_has_d_fileno=no ;;
esac
fi
;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $bash_cv_dirent_has_d_fileno" >&5
printf "%s\n" "$bash_cv_dirent_has_d_fileno" >&6; }
if test $bash_cv_dirent_has_d_fileno = yes; then
printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_FILENO 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct dirent.d_namlen" >&5
printf %s "checking for struct dirent.d_namlen... " >&6; }
if test ${bash_cv_dirent_has_d_namlen+y}
then :
printf %s "(cached) " >&6
else case e in #(
e)
ac_fn_c_check_member "$LINENO" "struct dirent" "d_namlen" "ac_cv_member_struct_dirent_d_namlen" "
#include <stdio.h>
@@ -20034,23 +20001,10 @@ then :
printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_NAMLEN 1" >>confdefs.h
bash_cv_dirent_has_d_namlen=yes
else case e in #(
e) bash_cv_dirent_has_d_namlen=no ;;
esac
fi
;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $bash_cv_dirent_has_d_namlen" >&5
printf "%s\n" "$bash_cv_dirent_has_d_namlen" >&6; }
if test $bash_cv_dirent_has_d_namlen = yes; then
printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_NAMLEN 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct winsize in sys/ioctl.h and termios.h" >&5
printf %s "checking for struct winsize in sys/ioctl.h and termios.h... " >&6; }
if test ${bash_cv_struct_winsize_header+y}
@@ -21449,15 +21403,6 @@ printf "%s\n" "#define HAVE_VSNPRINTF 0" >>confdefs.h
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for usable strtoimax" >&5
printf %s "checking for usable strtoimax... " >&6; }
if test ${bash_cv_func_strtoimax+y}
then :
printf %s "(cached) " >&6
else case e in #(
e)
HAVE_STRTOIMAX=0 HAVE_DECL_STRTOIMAX=0
ac_fn_c_check_func "$LINENO" "strtoimax" "ac_cv_func_strtoimax"
if test "x$ac_cv_func_strtoimax" = xyes
then :
@@ -21476,35 +21421,14 @@ fi
printf "%s\n" "#define HAVE_DECL_STRTOIMAX $ac_have_decl" >>confdefs.h
if test "$ac_cv_func_strtoimax" = "yes" ; then
HAVE_STRTOIMAX=1
fi
if test "$ac_cv_have_decl_strtoimax" = "yes" ; then
HAVE_DECL_STRTOIMAX=1
fi
if test "$HAVE_STRTOIMAX" = 0 || test "$HAVE_DECL_STRTOIMAX" = 0 ; then
bash_cv_func_strtoimax=no REPLACE_STRTOIMAX=1
else
bash_cv_func_strtoimax=yes
fi
;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $bash_cv_func_strtoimax" >&5
printf "%s\n" "$bash_cv_func_strtoimax" >&6; }
if test "$ac_cv_have_decl_strtoimax" = "yes" ; then
printf "%s\n" "#define HAVE_DECL_STRTOIMAX 1" >>confdefs.h
fi
if test $bash_cv_func_strtoimax = no; then
case " $LIBOBJS " in
if test "$ac_cv_func_strtoimax" != "yes" ; then
case " $LIBOBJS " in
*" strtoimax.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS strtoimax.$ac_objext"
;;
esac
fi
fi
ac_fn_check_decl "$LINENO" "clearerr_unlocked" "ac_cv_have_decl_clearerr_unlocked" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS"
if test "x$ac_cv_have_decl_clearerr_unlocked" = xyes
@@ -22701,53 +22625,6 @@ printf "%s\n" "$ac_cv_lib_curses_tgetent" >&6; }
if test "x$ac_cv_lib_curses_tgetent" = xyes
then :
bash_cv_termcap_lib=libcurses
else case e in #(
e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5
printf %s "checking for tgetent in -lncurses... " >&6; }
if test ${ac_cv_lib_ncurses_tgetent+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) ac_check_lib_save_LIBS=$LIBS
LIBS="-lncurses $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply.
The 'extern "C"' is for builds by C++ compilers;
although this is not generally supported in C code supporting it here
has little cost and some practical benefit (sr 110532). */
#ifdef __cplusplus
extern "C"
#endif
char tgetent (void);
int
main (void)
{
return tgetent ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_lib_ncurses_tgetent=yes
else case e in #(
e) ac_cv_lib_ncurses_tgetent=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tgetent" >&5
printf "%s\n" "$ac_cv_lib_ncurses_tgetent" >&6; }
if test "x$ac_cv_lib_ncurses_tgetent" = xyes
then :
bash_cv_termcap_lib=libncurses
else case e in #(
e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncursesw" >&5
printf %s "checking for tgetent in -lncursesw... " >&6; }
@@ -22795,6 +22672,53 @@ printf "%s\n" "$ac_cv_lib_ncursesw_tgetent" >&6; }
if test "x$ac_cv_lib_ncursesw_tgetent" = xyes
then :
bash_cv_termcap_lib=libncursesw
else case e in #(
e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5
printf %s "checking for tgetent in -lncurses... " >&6; }
if test ${ac_cv_lib_ncurses_tgetent+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) ac_check_lib_save_LIBS=$LIBS
LIBS="-lncurses $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply.
The 'extern "C"' is for builds by C++ compilers;
although this is not generally supported in C code supporting it here
has little cost and some practical benefit (sr 110532). */
#ifdef __cplusplus
extern "C"
#endif
char tgetent (void);
int
main (void)
{
return tgetent ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_lib_ncurses_tgetent=yes
else case e in #(
e) ac_cv_lib_ncurses_tgetent=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tgetent" >&5
printf "%s\n" "$ac_cv_lib_ncurses_tgetent" >&6; }
if test "x$ac_cv_lib_ncurses_tgetent" = xyes
then :
bash_cv_termcap_lib=libncurses
else case e in #(
e) bash_cv_termcap_lib=gnutermcap ;;
esac
@@ -22834,6 +22758,9 @@ TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libtinfo; then
TERMCAP_LIB=-ltinfo
TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libncursesw; then
TERMCAP_LIB=-lncursesw
TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libncurses; then
TERMCAP_LIB=-lncurses
TERMCAP_DEP=
@@ -23143,12 +23070,16 @@ ac_config_commands="$ac_config_commands stamp-h"
if test "$ac_cv_header_stdckdint_h" = yes; then
rm -f stdckdint.h
STDCKDINT_H=
elif cmp ${srcdir}/include/stdckdint.in.h stdckdint.h 2>/dev/null; then
:
STDCKDINT_H='${BUILD_DIR}/stdckdint.h'
else
cp ${srcdir}/include/stdckdint.in.h stdckdint.h
STDCKDINT_H='${BUILD_DIR}/stdckdint.h'
fi
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@@ -23658,7 +23589,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by bash $as_me 5.3-alpha, which was
This file was extended by bash $as_me 5.3-beta, which was
generated by GNU Autoconf 2.72. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -23726,7 +23657,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
bash config.status 5.3-alpha
bash config.status 5.3-beta
configured by $0, generated by GNU Autoconf 2.72,
with options \\"\$ac_cs_config\\"
@@ -23860,6 +23791,7 @@ for ac_config_target in $ac_config_targets
do
case $ac_config_target in
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
"buildconf.h") CONFIG_HEADERS="$CONFIG_HEADERS buildconf.h" ;;
"po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"builtins/Makefile") CONFIG_FILES="$CONFIG_FILES builtins/Makefile" ;;
+48 -35
View File
@@ -21,10 +21,10 @@ dnl Process this file with autoconf to produce a configure script.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_REVISION([for Bash 5.3, version 5.063])dnl
AC_REVISION([for Bash 5.3, version 5.074])dnl
define(bashvers, 5.3)
define(relstatus, alpha)
define(relstatus, beta)
AC_INIT([bash], bashvers-relstatus, [bug-bash@gnu.org])
@@ -34,7 +34,7 @@ AC_PREREQ(2.69)
AC_CONFIG_SRCDIR(shell.h)
dnl where to find install.sh, config.sub, and config.guess
AC_CONFIG_AUX_DIR(./support)
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_HEADERS(config.h buildconf.h)
dnl checks for version info
BASHVERS=bashvers
@@ -186,6 +186,7 @@ opt_function_import=yes
opt_dev_fd_stat_broken=no
opt_alt_array_impl=no
opt_translatable_strings=yes
opt_bash_source_fullpath_default=no
dnl modified by alternate array implementation option
ARRAY_O=array.o
@@ -211,6 +212,7 @@ if test $opt_minimal_config = yes; then
opt_casemod_attrs=no opt_casemod_expansions=no opt_extglob_default=no
opt_translatable_strings=no
opt_globascii_default=yes
opt_bash_source_fullpath_default=no
fi
AC_ARG_ENABLE(alias, AS_HELP_STRING([--enable-alias], [enable shell aliases]), opt_alias=$enableval)
@@ -218,6 +220,7 @@ AC_ARG_ENABLE(alt-array-implementation, AS_HELP_STRING([--enable-alt-array-imple
AC_ARG_ENABLE(arith-for-command, AS_HELP_STRING([--enable-arith-for-command], [enable arithmetic for command]), opt_arith_for_command=$enableval)
AC_ARG_ENABLE(array-variables, AS_HELP_STRING([--enable-array-variables], [include shell array variables]), opt_array_variables=$enableval)
AC_ARG_ENABLE(bang-history, AS_HELP_STRING([--enable-bang-history], [turn on csh-style history substitution]), opt_bang_history=$enableval)
AC_ARG_ENABLE(bash-source-fullpath-default, AS_HELP_STRING([--enable-bash-source-fullpath-default], [enable the bash_source_fullpath option by default]), opt_bash_source_fullpath_default=$enableval)
AC_ARG_ENABLE(brace-expansion, AS_HELP_STRING([--enable-brace-expansion], [include brace expansion]), opt_brace_expansion=$enableval)
AC_ARG_ENABLE(casemod-attributes, AS_HELP_STRING([--enable-casemod-attributes], [include case-modifying variable attributes]), opt_casemod_attrs=$enableval)
AC_ARG_ENABLE(casemod-expansions, AS_HELP_STRING([--enable-casemod-expansions], [include case-modifying word expansions]), opt_casemod_expansions=$enableval)
@@ -371,6 +374,11 @@ fi
if test $opt_translatable_strings = yes; then
AC_DEFINE(TRANSLATABLE_STRINGS)
fi
if test $opt_bash_source_fullpath_default = yes; then
AC_DEFINE(BASH_SOURCE_FULLPATH_DEFAULT, 1)
else
AC_DEFINE(BASH_SOURCE_FULLPATH_DEFAULT, 0)
fi
if test $opt_memscramble = yes; then
AC_DEFINE(MEMSCRAMBLE)
@@ -460,30 +468,30 @@ dnl Set SIGNAMES_H based on whether or not we're cross-compiling.
CROSS_COMPILE=
if test "x$cross_compiling" = "xyes"; then
case "${host}" in
*-cygwin*)
cross_cache=${srcdir}/cross-build/cygwin32.cache
;;
*-msys*)
cross_cache=${srcdir}/cross-build/msys32.cache
;;
*-mingw*)
cross_cache=${srcdir}/cross-build/cygwin32.cache
;;
i[[3456]]86-*-beos*)
cross_cache=${srcdir}/cross-build/x86-beos.cache
;;
*-qnx*)
cross_cache=${srcdir}/cross-build/qnx.cache
;;
*) echo "configure: cross-compiling for $host is not supported" >&2
;;
esac
if test -n "${cross_cache}" && test -r "${cross_cache}"; then
echo "loading cross-build cache file ${cross_cache}"
. ${cross_cache}
fi
unset cross_cache
# case "${host}" in
# *-cygwin*)
# cross_cache=${srcdir}/cross-build/cygwin32.cache
# ;;
# *-msys*)
# cross_cache=${srcdir}/cross-build/msys32.cache
# ;;
# *-mingw*)
# cross_cache=${srcdir}/cross-build/cygwin32.cache
# ;;
# i[[3456]]86-*-beos*)
# cross_cache=${srcdir}/cross-build/x86-beos.cache
# ;;
# *-qnx*)
# cross_cache=${srcdir}/cross-build/qnx.cache
# ;;
# *) echo "configure: cross-compiling for $host is not supported" >&2
# ;;
# esac
# if test -n "${cross_cache}" && test -r "${cross_cache}"; then
# echo "loading cross-build cache file ${cross_cache}"
# . ${cross_cache}
# fi
# unset cross_cache
SIGNAMES_O='signames.o'
CROSS_COMPILE='-DCROSS_COMPILING'
AC_SUBST(CROSS_COMPILE)
@@ -539,11 +547,9 @@ if test "X$cross_compiling" = "Xno"; then
# CFLAGS set above to default value if not passed in environment
if test -n "$want_auto_cflags" ; then
CFLAGS_FOR_BUILD="${CFLAGS}"
BASE_CFLAGS_FOR_BUILD="${CFLAGS}"
else
# passed in environment
CFLAGS_FOR_BUILD=${CFLAGS-'$(CFLAGS)'}
BASE_CFLAGS_FOR_BUILD=${CFLAGS-'$(CFLAGS)'}
fi
LIBS_FOR_BUILD=${LIBS_FOR_BUILD-'$(LIBS)'}
else
@@ -551,7 +557,6 @@ else
CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-""}
LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-""}
CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD="-g"}
BASE_CFLAGS_FOR_BUILD=${BASE_CFLAGS_FOR_BUILD="-g"}
LIBS_FOR_BUILD=${LIBS_FOR_BUILD-""}
fi
@@ -562,7 +567,6 @@ AC_SUBST(STATIC_LD)
AC_SUBST(CC_FOR_BUILD)
AC_SUBST(CFLAGS_FOR_BUILD)
AC_SUBST(BASE_CFLAGS_FOR_BUILD)
AC_SUBST(STYLE_CFLAGS)
AC_SUBST(CPPFLAGS_FOR_BUILD)
AC_SUBST(LDFLAGS_FOR_BUILD)
@@ -614,6 +618,8 @@ if test $opt_readline = yes; then
else
RL_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
READLINE_DEP='$(READLINE_LIBRARY)'
# for dependencies
RL_INCLUDEDIR='$(RL_LIBDIR)'
# section for OS versions that ship an older/broken version of
# readline as a standard dynamic library and don't allow a
# static version specified as -llibname to override the
@@ -626,6 +632,7 @@ if test $opt_readline = yes; then
else
RL_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
READLINE_LIB= READLINE_DEP=
RL_INCLUDEDIR=
fi
if test $opt_history = yes || test $opt_bang_history = yes; then
if test $opt_history = yes; then
@@ -649,6 +656,8 @@ if test $opt_history = yes || test $opt_bang_history = yes; then
else
HIST_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
HISTORY_DEP='$(HISTORY_LIBRARY)'
# for dependencies
HIST_INCLUDEDIR='$(HIST_LIBDIR)'
# section for OS versions that ship an older version of
# readline as a standard dynamic library and don't allow a
# static version specified as -llibname to override the
@@ -661,6 +670,7 @@ if test $opt_history = yes || test $opt_bang_history = yes; then
else
HIST_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
HISTORY_LIB= HISTORY_DEP=
HIST_INCLUDEDIR=
fi
AC_SUBST(READLINE_LIB)
AC_SUBST(READLINE_DEP)
@@ -670,6 +680,7 @@ AC_SUBST(RL_INCLUDE)
AC_SUBST(HISTORY_LIB)
AC_SUBST(HISTORY_DEP)
AC_SUBST(HIST_LIBDIR)
AC_SUBST(HIST_INCLUDEDIR)
AC_SUBST(TILDE_LIB)
dnl END READLINE and HISTORY LIBRARY SECTION
@@ -870,7 +881,8 @@ AC_CHECK_FUNCS(bcopy bzero clock_gettime confstr faccessat fnmatch \
getaddrinfo gethostbyname getservbyname getservent inet_aton \
imaxdiv memmove pathconf putenv raise random regcomp regexec \
setenv setlinebuf setlocale setvbuf siginterrupt strchr \
sysconf syslog tcgetattr times ttyname tzset unsetenv)
sysconf syslog tcgetattr tcgetwinsize tcsetwinsize \
times ttyname tzset unsetenv)
AC_CHECK_FUNCS(vasprintf asprintf)
AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit)
@@ -1014,9 +1026,6 @@ AC_CHECK_SIZEOF(size_t, 4)
AC_CHECK_SIZEOF(double, 8)
AC_CHECK_SIZEOF([long long], 8)
AC_CHECK_TYPE(u_int, [unsigned int])
AC_CHECK_TYPE(u_long, [unsigned long])
BASH_TYPE_BITS16_T
BASH_TYPE_U_BITS16_T
BASH_TYPE_BITS32_T
@@ -1361,10 +1370,14 @@ AC_CONFIG_COMMANDS([stamp-h], [echo timestamp > stamp-h])
if test "$ac_cv_header_stdckdint_h" = yes; then
rm -f stdckdint.h
STDCKDINT_H=
elif cmp ${srcdir}/include/stdckdint.in.h stdckdint.h 2>/dev/null; then
:
STDCKDINT_H='${BUILD_DIR}/stdckdint.h'
else
cp ${srcdir}/include/stdckdint.in.h stdckdint.h
STDCKDINT_H='${BUILD_DIR}/stdckdint.h'
fi
AC_SUBST(STDCKDINT_H)
AC_OUTPUT
+33 -16
View File
@@ -1,6 +1,6 @@
# This Makefile is for the Bash/documentation directory -*- text -*-.
#
# Copyright (C) 2003-2015 Free Software Foundation, Inc.
# Copyright (C) 2003-2024 Free Software Foundation, Inc.
# 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
@@ -65,10 +65,6 @@ SUPPORT_SRCDIR = $(topdir)/support
# bad style
RL_LIBDIR = $(topdir)/lib/readline
# unused
TEXINDEX = texindex
TEX = tex
MAKEINFO = makeinfo
TEXI2DVI = ${SUPPORT_SRCDIR}/texi2dvi
TEXI2HTML = ${SUPPORT_SRCDIR}/texi2html
@@ -161,12 +157,14 @@ all: info dvi text html pdf $(MAN2HTML)
nodvi: ps info text html
everything: all ps
PSFILES = bash.ps bashbug.ps article.ps builtins.ps rbash.ps
DVIFILES = bashref.dvi bashref.ps
CREATED_PS = bash.ps bashref.ps
PSFILES = ${CREATED_PS} article.ps
DVIFILES = bashref.dvi
INFOFILES = bashref.info bash.info
MAN0FILES = bash.0 bashbug.0 builtins.0 rbash.0
HTMLFILES = bashref.html bash.html
PDFFILES = bash.pdf bashref.pdf article.pdf rose94.pdf
CREATED_PDF = bash.pdf bashref.pdf builtins.pdf rbash.pdf
PDFFILES = ${CREATED_PDF} article.pdf rose94.pdf
ps: ${PSFILES}
dvi: ${DVIFILES}
@@ -215,6 +213,10 @@ bashref.ps: bashref.dvi
bashref.pdf: bashref.texi
bash.pdf: bash.1
builtins.pdf: builtins.1 bash.1
$(RM) $@
-${GROFF} -I${srcdir} -man -T pdf builtins.1 > $@
article.pdf: article.ps
rose94.pdf: rose94.ps
@@ -222,27 +224,32 @@ OTHER_DOCS = $(srcdir)/FAQ $(srcdir)/INTRO
OTHER_INSTALLED_DOCS = FAQ INTRO
$(MAN2HTML): ${topdir}/support/man2html.c
-( cd ${BUILD_DIR}/support ; ${MAKE} ${MFLAGS} man2html)
-( cd ${BUILD_DIR}/support ; ${MAKE} ${BASH_MAKEFLAGS} man2html)
clean:
.PHONY: clean maintainer-clean distclean mostlyclean maybe-clean
mostlyclean:
$(RM) *.aux *.bak *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps \
*.pgs *.bt *.bts *.rw *.rws *.fns *.kys *.tps *.vrs *.o
${RM} core *.core
mostlyclean: clean
$(RM) Makefile
clean: mostlyclean
distclean: clean maybe-clean
$(RM) Makefile
maintainer-clean: clean
${RM} ${PSFILES} ${DVIFILES} ${INFOFILES} ${MAN0FILES} ${HTMLFILES}
${RM} ${DVIFILES} ${INFOFILES} ${MAN0FILES} ${HTMLFILES}
${RM} ${CREATED_PS} ${CREATED_PDF}
${RM} ${CREATED_FAQ}
$(RM) Makefile
# I'd like to use realpath here, but it's not universal
maybe-clean:
-if test "X$(topdir)" != "X$(BUILD_DIR)"; then \
$(RM) ${PSFILES} ${DVIFILES} ${INFOFILES} ${MAN0FILES} ${HTMLFILES}; \
-TD=$$(cd $(topdir) && pwd -P) ; \
BD=$$(cd $(BUILD_DIR) && pwd -P) ; \
if test "X$$TD" != "X$$BD"; then \
$(RM) ${CREATED_PS} ${DVIFILES} ${INFOFILES} ${MAN0FILES} ${HTMLFILES} ${CREATED_PDF}; \
fi
installdirs:
@@ -286,12 +293,22 @@ install-html: html
$(INSTALL_DATA) $(srcdir)/bashref.html $(DESTDIR)$(htmldir) ; \
fi
install-dvi:
install-pdf:
install-ps:
uninstall-html:
-if test -n "$(htmldir)" ; then \
$(RM) $(DESTDIR)$(htmldir)/bash.html ; \
$(RM) $(DESTDIR)$(htmldir)/bashref.html ; \
fi
uninstall:
-$(RM) $(DESTDIR)$(man1dir)/bash${man1ext} $(DESTDIR)$(man1dir)/bashbug${man1ext}
-$(RM) $(DESTDIR)$(man1dir)/bash_builtins${man1ext}
$(RM) $(DESTDIR)$(infodir)/bash.info
# run install-info if it is present to update the info directory
if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
-if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
install-info --delete --dir-file=$(DESTDIR)$(infodir)/dir $(DESTDIR)$(infodir)/bash.info; \
else true; fi
-( cd $(DESTDIR)$(docdir) && $(RM) $(OTHER_INSTALLED_DOCS) )
+4008 -3465
View File
File diff suppressed because it is too large Load Diff
+3262 -2319
View File
File diff suppressed because it is too large Load Diff
+3581 -2463
View File
File diff suppressed because it is too large Load Diff
+3417 -2877
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+3382 -2372
View File
File diff suppressed because it is too large Load Diff
+3417 -2877
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+2463 -1752
View File
File diff suppressed because it is too large Load Diff
+1267 -1129
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+29 -26
View File
@@ -5,53 +5,56 @@ NNAAMMEE
RREESSTTRRIICCTTEEDD SSHHEELLLL
If bbaasshh is started with the name rrbbaasshh, or the --rr option is supplied at
invocation, the shell becomes restricted. A restricted shell is used
invocation, the shell becomes _r_e_s_t_r_i_c_t_e_d. A restricted shell is used
to set up an environment more controlled than the standard shell. It
behaves identically to bbaasshh with the exception that the following are
disallowed or not performed:
+o changing directories with ccdd
+o Changing directories with ccdd.
+o setting or unsetting the values of SSHHEELLLL, PPAATTHH, HHIISSTTFFIILLEE, EENNVV,
or BBAASSHH__EENNVV
+o Setting or unsetting the values of SSHHEELLLL, PPAATTHH, HHIISSTTFFIILLEE, EENNVV,
or BBAASSHH__EENNVV.
+o specifying command names containing //
+o Specifying command names containing //.
+o specifying a filename containing a // as an argument to the ..
builtin command
+o Specifying a filename containing a // as an argument to the ..
builtin command.
+o specifying a filename containing a slash as an argument to the
hhiissttoorryy builtin command
+o Using the --pp option to the .. builtin command to specify a
search path.
+o specifying a filename containing a slash as an argument to the
--pp option to the hhaasshh builtin command
+o Specifying a filename containing a slash as an argument to the
hhiissttoorryy builtin command.
+o importing function definitions from the shell environment at
startup
+o Specifying a filename containing a slash as an argument to the
--pp option to the hhaasshh builtin command.
+o parsing the value of SSHHEELLLLOOPPTTSS from the shell environment at
startup
+o Importing function definitions from the shell environment at
startup.
+o redirecting output using the >, >|, <>, >&, &>, and >> redirec-
tion operators
+o Parsing the value of SSHHEELLLLOOPPTTSS from the shell environment at
startup.
+o using the eexxeecc builtin command to replace the shell with another
command
+o Redirecting output using the >, >|, <>, >&, &>, and >> redirec-
tion operators.
+o adding or deleting builtin commands with the --ff and --dd options
to the eennaabbllee builtin command
+o Using the eexxeecc builtin command to replace the shell with another
command.
+o using the eennaabbllee builtin command to enable disabled shell
builtins
+o Adding or deleting builtin commands with the --ff and --dd options
to the eennaabbllee builtin command.
+o specifying the --pp option to the ccoommmmaanndd builtin command
+o Using the eennaabbllee builtin command to enable disabled shell
builtins.
+o turning off restricted mode with sseett ++rr or sshhoopptt --uu rree--
+o Specifying the --pp option to the ccoommmmaanndd builtin command.
+o Turning off restricted mode with sseett ++rr or sshhoopptt --uu rree--
ssttrriicctteedd__sshheellll.
These restrictions are enforced after any startup files are read.
When a command that is found to be a shell script is executed, rrbbaasshh
When a command that is found to be a shell script is executed, rrbbaasshh
turns off any restrictions in the shell spawned to execute the script.
SSEEEE AALLSSOO
BIN
View File
Binary file not shown.
+3 -3
View File
@@ -2,10 +2,10 @@
Copyright (C) 1988-2024 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Fri Apr 5 12:10:00 EDT 2024
@set LASTCHANGE Thu Dec 12 13:37:30 EST 2024
@set EDITION 5.3
@set VERSION 5.3
@set UPDATED 5 April 2024
@set UPDATED-MONTH April 2024
@set UPDATED 12 December 2024
@set UPDATED-MONTH December 2024
+6
View File
@@ -454,3 +454,9 @@ err_readonly (const char *s)
{
report_error (_("%s: readonly variable"), s);
}
void
err_invalidid (const char *s)
{
internal_error (_("`%s': not a valid identifier"), s);
}
+2
View File
@@ -73,6 +73,8 @@ extern void err_badarraysub (const char *);
extern void err_unboundvar (const char *);
extern void err_readonly (const char *);
extern void err_invalidid (const char *);
#ifdef DEBUG
# define INTERNAL_DEBUG(x) internal_debug x
#else
+7
View File
@@ -48,6 +48,10 @@
# include "bashhist.h"
#endif
#if defined (JOB_CONTROL)
# include "jobs.h"
#endif
static void send_pwd_to_eterm (void);
static sighandler alrm_catcher (int);
@@ -343,6 +347,9 @@ parse_command (void)
actually printed. */
if (interactive && bash_input.type != st_string && parser_expanding_alias() == 0)
{
#if defined (JOB_CONTROL)
notify_and_cleanup (-1);
#endif
#if defined (READLINE)
if (no_line_editing || (bash_input.type == st_stdin && parser_will_prompt ()))
#endif
+66
View File
@@ -0,0 +1,66 @@
# 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 3 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
# 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 this program. If not, see <http://www.gnu.org/licenses/>.
#
# setalrm - set a timer to fire in N seconds and send SIGALRM to the shell
#
# usage: setalrm [-c] N
#
# -c means to reset the trap on ALRM if the timer is canceled
#
# If N = 0, we cancel any pending alarm by killing the background timeout
# process. Any value greater than 0 sets a timeout for N seconds. Values
# of N less than zero are errors.
declare -i alrmpid=
setalrm()
{
local untrap=
local setalrm_usage="setalrm: usage: setalrm [-c] N"
while getopts c opt; do
case $opt in
c) untrap=1 ;;
*) echo "$setalrm_usage" >&2 ; return 2;;
esac
done
shift $(( $OPTIND - 1 ))
if [[ -z $1 ]]; then
echo "$setalrm_usage" >&2
return 2
fi
if (( $1 < 0 )); then
echo "setalrm: timeout must be greater than zero" >& 2
return 2
fi
if [[ $1 -eq 0 ]] && [[ -n "$alrmpid" ]]; then
kill -TERM $alrmpid ; es=$?
alrmpid=
if [ -n "$untrap" ]; then
trap - ALRM # caller saves if desired
fi
return $es
fi
# setting alarm
{ trap - ALRM ; sleep $1; kill -ALRM $$; } &
alrmpid=$!
return 0
}
+3 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 2020,2022,2023 Free Software Foundation, Inc.
Copyright (C) 2020,2022-2024 Free Software Foundation, Inc.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,6 +16,8 @@
*/
/* Contributed by Geir Hauge <geir.hauge@gmail.com> */
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
+2
View File
@@ -22,6 +22,8 @@
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <fcntl.h>
#include <errno.h>
+8
View File
@@ -30,6 +30,8 @@
#include "loadables.h"
#if defined (ARRAY_VARS)
#define CSV_ARRAY_DEFAULT "CSV"
#define NQUOTE 0
@@ -99,11 +101,13 @@ csvsplit (SHELL_VAR *csv, char *line, char *dstring)
return (rval = ind); /* number of fields */
}
#endif
int
csv_builtin (WORD_LIST *list)
{
int opt, rval;
#if defined (ARRAY_VARS)
char *array_name, *csvstring;
SHELL_VAR *v;
@@ -164,6 +168,10 @@ csv_builtin (WORD_LIST *list)
opt = csvsplit (v, csvstring, ",");
/* Maybe do something with OPT here, it's the number of fields */
#else
builtin_error ("arrays not available");
rval = EXECUTION_FAILURE;
#endif
return (rval);
}
+15
View File
@@ -178,7 +178,9 @@ cutbytes (SHELL_VAR *v, char *line, struct cutop *ops)
if (v)
{
ind = 0;
#if defined (ARRAY_VARS)
bind_array_element (v, ind, buf, 0);
#endif
ind++;
}
else
@@ -246,7 +248,9 @@ cutchars (SHELL_VAR *v, char *line, struct cutop *ops)
if (v)
{
ind = 0;
#if defined (ARRAY_VARS)
bind_array_element (v, ind, buf, 0);
#endif
ind++;
}
else
@@ -301,7 +305,9 @@ cutfields (SHELL_VAR *v, char *line, struct cutop *ops)
return ind;
if (v)
{
#if defined (ARRAY_VARS)
bind_array_element (v, ind, line, 0);
#endif
ind++;
}
else
@@ -330,12 +336,14 @@ cutfields (SHELL_VAR *v, char *line, struct cutop *ops)
{
if (bmap[b] == 0)
continue;
#if defined (ARRAY_VARS)
if (v)
{
bind_array_element (v, ind, fields[b], 0);
ind++;
}
else
#endif
{
if (i == 0)
putchar (ops->delim);
@@ -441,8 +449,13 @@ cut_internal (int which, WORD_LIST *list)
switch (opt)
{
case 'a':
#if defined (ARRAY_VARS)
array_name = list_optarg;
break;
#else
builtin_error ("arrays not available");
return (EX_USAGE);
#endif
case 'b':
cutflags |= BFLAG;
list_arg = list_optarg;
@@ -502,6 +515,7 @@ cut_internal (int which, WORD_LIST *list)
return (EXECUTION_FAILURE);
}
#if defined (ARRAY_VARS)
if (array_name)
{
v = builtin_find_indexed_array (array_name, 1);
@@ -511,6 +525,7 @@ cut_internal (int which, WORD_LIST *list)
return (EXECUTION_FAILURE);
}
}
#endif
op.flags = cutflags;
op.delim = delim;
+8
View File
@@ -30,6 +30,8 @@
#include "loadables.h"
#if defined (ARRAY_VARS)
#define DSV_ARRAY_DEFAULT "DSV"
#define NQUOTE 0
@@ -158,11 +160,13 @@ dsvsplit (SHELL_VAR *dsv, char *line, char *dstring, int flags)
return (rval = ind); /* number of fields */
}
#endif
int
dsv_builtin (WORD_LIST *list)
{
int opt, rval, flags;
#if defined (ARRAY_VARS)
char *array_name, *dsvstring, *delims;
SHELL_VAR *v;
@@ -238,6 +242,10 @@ dsv_builtin (WORD_LIST *list)
opt = dsvsplit (v, dsvstring, delims, flags);
/* Maybe do something with OPT here, it's the number of fields */
#else
builtin_error ("arrays not available");
rval = EXECUTION_FAILURE;
#endif
return (rval);
}
+5 -6
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1991-2023 Free Software Foundation, Inc.
/* Copyright (C) 1991-2024 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
@@ -21,8 +21,6 @@
#include <unistd.h>
#include <errno.h>
#include <error.h>
#include <gettext.h>
#include <locale.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@@ -1042,16 +1040,17 @@ getconf_all (WORD_LIST *list)
int r;
r = EXECUTION_SUCCESS;
path = list ? list->word->word : 0;
path = list ? list->word->word : "/";
for (c = vars; c->name != NULL; ++c)
{
#if 0
if (c->call == PATHCONF && path == 0)
continue; /* Don't print pathconf vars if no path supplied */
#if 0
if (c->call != PATHCONF && path)
continue; /* Only print pathconf vars if path supplied */
#endif
printf("%-35s", c->name);
/* The output format for getconf -a is required by POSIX interp 1808 */
printf("%s: ", c->name);
if (getconf_print (c, path, 1) == EXECUTION_FAILURE)
r = EXECUTION_FAILURE;
}
+8
View File
@@ -37,6 +37,8 @@
extern int errno;
#endif
#if defined (ARRAY_VARS)
#define KV_ARRAY_DEFAULT "KV"
/* Split LINE into a key and value, with the delimiter between the key and
@@ -113,10 +115,12 @@ kvfile (SHELL_VAR *v, int fd, char *delims, char *rs)
QUIT;
return nr;
}
#endif
int
kv_builtin (WORD_LIST *list)
{
#if defined (ARRAY_VARS)
int opt, rval, free_delims;
char *array_name, *delims, *rs;
SHELL_VAR *v;
@@ -192,6 +196,10 @@ kv_builtin (WORD_LIST *list)
if (free_delims)
free (delims); /* getifs returns allocated memory */
return (rval > 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
#else
builtin_error ("arrays not available");
return (EXECUTION_FAILURE);
#endif
}
/* Called when builtin is enabled and loaded from the shared object. If this
+2
View File
@@ -165,10 +165,12 @@ realpath_builtin(WORD_LIST *list)
builtin_error("%s: %s", p, strerror(errno));
continue;
}
#if defined (ARRAY_VARS)
if (aflag) {
bind_array_element (v, ind, r, 0);
ind++;
}
#endif
if (qflag == 0) {
if (vflag)
printf ("%s -> ", p);
+8
View File
@@ -46,6 +46,8 @@
extern int errno;
#endif
#if defined (ARRAY_VARS)
#define ST_NAME 0
#define ST_DEV 1
#define ST_INO 2
@@ -334,10 +336,12 @@ loadstat (char *vname, SHELL_VAR *var, char *fname, int flags, char *fmt, struct
}
return 0;
}
#endif
int
stat_builtin (WORD_LIST *list)
{
#if defined (ARRAY_VARS)
int opt, flags;
char *aname, *fname, *timefmt;
struct stat st;
@@ -410,6 +414,10 @@ stat_builtin (WORD_LIST *list)
}
return (EXECUTION_SUCCESS);
#else
builtin_error ("arrays not available");
return (EXECUTION_FAILURE);
#endif
}
/* An array of strings forming the `long' documentation for a builtin xxx,
+1 -1
View File
@@ -91,7 +91,7 @@ do
esac
# save to the history list
history -s "$EQN"
history -s -- "$EQN"
# run it through bc
calc "$EQN"
+137 -88
View File
@@ -261,6 +261,12 @@ int subshell_level = 0;
/* Currently-executing shell function. */
SHELL_VAR *this_shell_function;
/* Translated message printed when a command is not found. We declare it here
and initialize it in locale.c to work around a macOS bug that forces a
crash if bash calls setlocale(3) but does not call gettext(3) before
forking, then calls gettext() after forking. */
char *notfound_str = 0;
/* If non-zero, matches in case and [[ ... ]] are case-insensitive */
int match_ignore_case = 0;
@@ -301,6 +307,19 @@ do { \
? line_number_for_err_trap \
: executing_line_number ()
/* We adjust the line number when executing shell functions in an interactive
shell. */
#define ADJUST_LINE_NUMBER() \
do { \
if (variable_context && interactive_shell && sourcelevel == 0) \
{ \
/* line numbers in a function start at 1 */ \
line_number -= function_line_number - 1; \
if (line_number <= 0) \
line_number = 1; \
} \
} while (0)
/* A sort of function nesting level counter */
int funcnest = 0;
int funcnest_max = 0;
@@ -584,7 +603,7 @@ async_redirect_stdin (void)
close (fd);
}
else if (fd < 0)
internal_error (_("cannot redirect standard input from /dev/null: %s"), strerror (errno));
internal_error ("%s: %s", _("cannot redirect standard input from /dev/null"), strerror (errno));
}
#define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0)
@@ -802,7 +821,7 @@ execute_command_internal (COMMAND *command, int asynchronous, int pipe_in, int p
#if defined (PROCESS_SUBSTITUTION)
# if !defined (HAVE_DEV_FD)
reap_procsubs ();
delete_procsubs (); /* closes fds or unlinks fifos */
# endif
/* XXX - also if sourcelevel != 0? */
@@ -886,7 +905,7 @@ execute_command_internal (COMMAND *command, int asynchronous, int pipe_in, int p
#endif
was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
if (ignore_return && command->value.Simple)
if ((ignore_return || invert) && command->value.Simple)
command->value.Simple->flags |= CMD_IGNORE_RETURN;
if (command->flags & CMD_STDIN_REDIR)
command->value.Simple->flags |= CMD_STDIN_REDIR;
@@ -894,6 +913,18 @@ execute_command_internal (COMMAND *command, int asynchronous, int pipe_in, int p
begin_unwind_frame ("simple_lineno");
add_unwind_protect (uw_restore_lineno, (void *) (intptr_t) save_line_number);
/* Limit the scope of this attempted optimization for now: async
commands for which TRY_OPTIMIZING is set (see call to optimize_shell_function
for async functions in execute_subshell_builtin_or_function below)
in interactive and script shells. */
if ((command->flags & CMD_TRY_OPTIMIZING) &&
(subshell_environment & SUBSHELL_ASYNC) && startup_state < 2 &&
should_optimize_fork (command, 0))
{
command->flags |= CMD_NO_FORK;
command->value.Simple->flags |= CMD_NO_FORK;
}
SET_LINE_NUMBER (command->value.Simple->line);
exec_result =
execute_simple_command (command->value.Simple, pipe_in, pipe_out,
@@ -981,14 +1012,14 @@ execute_command_internal (COMMAND *command, int asynchronous, int pipe_in, int p
break;
case cm_for:
if (ignore_return)
if (ignore_return || invert)
command->value.For->flags |= CMD_IGNORE_RETURN;
exec_result = execute_for_command (command->value.For);
break;
#if defined (ARITH_FOR_COMMAND)
case cm_arith_for:
if (ignore_return)
if (ignore_return || invert)
command->value.ArithFor->flags |= CMD_IGNORE_RETURN;
exec_result = execute_arith_for_command (command->value.ArithFor);
break;
@@ -996,32 +1027,32 @@ execute_command_internal (COMMAND *command, int asynchronous, int pipe_in, int p
#if defined (SELECT_COMMAND)
case cm_select:
if (ignore_return)
if (ignore_return || invert)
command->value.Select->flags |= CMD_IGNORE_RETURN;
exec_result = execute_select_command (command->value.Select);
break;
#endif
case cm_case:
if (ignore_return)
if (ignore_return || invert)
command->value.Case->flags |= CMD_IGNORE_RETURN;
exec_result = execute_case_command (command->value.Case);
break;
case cm_while:
if (ignore_return)
if (ignore_return || invert)
command->value.While->flags |= CMD_IGNORE_RETURN;
exec_result = execute_while_command (command->value.While);
break;
case cm_until:
if (ignore_return)
if (ignore_return || invert)
command->value.While->flags |= CMD_IGNORE_RETURN;
exec_result = execute_until_command (command->value.While);
break;
case cm_if:
if (ignore_return)
if (ignore_return || invert)
command->value.If->flags |= CMD_IGNORE_RETURN;
exec_result = execute_if_command (command->value.If);
break;
@@ -1061,7 +1092,11 @@ execute_command_internal (COMMAND *command, int asynchronous, int pipe_in, int p
}
else
{
if (ignore_return && command->value.Group->command)
/* If we're already ignoring the return value of this group command,
or if the return value is being inverted, make sure to ignore
set -e for the duration of the command, even if the group
command enables it. */
if ((ignore_return || invert) && command->value.Group->command)
command->value.Group->command->flags |= CMD_IGNORE_RETURN;
exec_result =
execute_command_internal (command->value.Group->command,
@@ -1386,13 +1421,13 @@ print_formatted_time (FILE *fp, char *format,
static int
time_command (COMMAND *command, int asynchronous, int pipe_in, int pipe_out, struct fd_bitmap *fds_to_close)
{
int rv, posix_time, old_flags, nullcmd, code;
int rv, posix_time, nullcmd, code;
time_t rs, us, ss; /* seconds */
long rsf, usf, ssf; /* microseconds */
int cpu;
char *time_format;
volatile procenv_t save_top_level;
volatile int old_subshell;
volatile int old_subshell, old_flags;
#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
struct timeval real, user, sys;
@@ -1447,7 +1482,8 @@ time_command (COMMAND *command, int asynchronous, int pipe_in, int pipe_out, str
rv = execute_command_internal (command, asynchronous, pipe_in, pipe_out, fds_to_close);
COPY_PROCENV (save_top_level, top_level);
command->flags = old_flags;
if (code == NOT_JUMPED)
command->flags = old_flags;
/* If we're jumping in a different subshell environment than we started,
don't bother printing timing stats, just keep longjmping back to the
@@ -1554,7 +1590,7 @@ execute_in_subshell (COMMAND *command, int asynchronous, int pipe_in, int pipe_o
/* If a command is asynchronous in a subshell (like ( foo ) & or
the special case of an asynchronous GROUP command where the
subshell bit is turned on down in case cm_group: below),
subshell bit is turned on down in case cm_group: above),
turn off `asynchronous', so that two subshells aren't spawned.
XXX - asynchronous used to be set to 0 in this block, but that
means that setup_async_signals was never run. Now it's set to
@@ -1673,7 +1709,6 @@ execute_in_subshell (COMMAND *command, int asynchronous, int pipe_in, int pipe_o
#if defined (PROCESS_SUBSTITUTION)
# if defined (JOB_CONTROL)
procsub_clear ();
last_procsub_child = 0;
# endif
clear_fifo_list (); /* XXX- we haven't created any FIFOs */
#endif
@@ -1723,10 +1758,7 @@ execute_in_subshell (COMMAND *command, int asynchronous, int pipe_in, int pipe_o
#if 1
#if defined (PROCESS_SUBSTITUTION) && defined (JOB_CONTROL)
if (user_subshell && command->type == cm_subshell)
{
procsub_clear ();
last_procsub_child = 0;
}
procsub_clear ();
#endif
#endif
}
@@ -1746,6 +1778,10 @@ execute_in_subshell (COMMAND *command, int asynchronous, int pipe_in, int pipe_o
/* Make sure the subshell inherits any CMD_IGNORE_RETURN flag. */
if ((command->flags & CMD_IGNORE_RETURN) && tcom != command)
tcom->flags |= CMD_IGNORE_RETURN;
/* If the subshell's return value is being inverted, ignore set -e even
if the subshell enables it. */
if (invert)
tcom->flags |= CMD_IGNORE_RETURN;
/* If this is a simple command, tell execute_disk_command that it
might be able to get away without forking and simply exec.
@@ -1931,7 +1967,9 @@ cpl_reap (void)
if (p->coproc->c_flags & COPROC_DEAD)
{
coproc_list.ncoproc--; /* keep running count, fix up pointers later */
#if 0
INTERNAL_DEBUG (("cpl_reap: deleting %d", p->coproc->c_pid));
#endif
coproc_dispose (p->coproc);
cpe_dispose (p);
}
@@ -2185,7 +2223,11 @@ coproc_reap (void)
cp = &sh_coproc; /* XXX - will require changes for multiple coprocs */
if (cp && (cp->c_flags & COPROC_DEAD))
{
INTERNAL_DEBUG (("coproc_reap: deleting %d", cp->c_pid));
coproc_dispose (cp);
}
#endif
}
@@ -2356,7 +2398,7 @@ coproc_setvars (struct coproc *cp)
}
}
if (v && (readonly_p (v) || noassign_p (v)))
if (v && ASSIGN_DISALLOWED (v, 0))
{
if (readonly_p (v))
err_readonly (cp->c_name);
@@ -2454,7 +2496,7 @@ execute_coproc (COMMAND *command, int pipe_in, int pipe_out, struct fd_bitmap *f
/* Optional check -- could be relaxed */
if (valid_identifier (name) == 0)
{
internal_error (_("`%s': not a valid identifier"), name);
err_invalidid (name);
free (name);
return (invert ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
@@ -2569,7 +2611,7 @@ uw_lastpipe_cleanup (void *s)
static int
execute_pipeline (COMMAND *command, int asynchronous, int pipe_in, int pipe_out, struct fd_bitmap *fds_to_close)
{
int prev, fildes[2], new_bitmap_size, dummyfd, ignore_return, exec_result;
int prev, fildes[2], new_bitmap_size, dummyfd, ignore_return, invert, exec_result;
int lstdin, lastpipe_flag, lastpipe_jid, old_frozen, stdin_valid;
COMMAND *cmd;
struct fd_bitmap *fd_bitmap;
@@ -2581,6 +2623,7 @@ execute_pipeline (COMMAND *command, int asynchronous, int pipe_in, int pipe_out,
#endif /* JOB_CONTROL */
ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
invert = (command->flags & CMD_INVERT_RETURN) != 0;
stdin_valid = sh_validfd (0);
@@ -2648,7 +2691,7 @@ execute_pipeline (COMMAND *command, int asynchronous, int pipe_in, int pipe_out,
add_unwind_protect (uw_restore_signal_mask, &oset);
#endif /* JOB_CONTROL */
if (ignore_return && cmd->value.Connection->first)
if ((ignore_return || invert) && cmd->value.Connection->first)
cmd->value.Connection->first->flags |= CMD_IGNORE_RETURN;
execute_command_internal (cmd->value.Connection->first, asynchronous,
prev, fildes[1], fd_bitmap);
@@ -2668,7 +2711,7 @@ execute_pipeline (COMMAND *command, int asynchronous, int pipe_in, int pipe_out,
lastpid = last_made_pid;
/* Now execute the rightmost command in the pipeline. */
if (ignore_return && cmd)
if ((ignore_return || invert) && cmd)
cmd->flags |= CMD_IGNORE_RETURN;
lastpipe_flag = 0;
@@ -2691,7 +2734,7 @@ execute_pipeline (COMMAND *command, int asynchronous, int pipe_in, int pipe_out,
prev = NO_PIPE;
add_unwind_protect (uw_restore_stdin, (void *) (intptr_t) lstdin);
lastpipe_flag = 1;
old_frozen = freeze_jobs_list ();
old_frozen = freeze_jobs_list (1);
lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL); /* XXX */
add_unwind_protect (uw_lastpipe_cleanup, (void *) (intptr_t) old_frozen);
#if defined (JOB_CONTROL)
@@ -2764,6 +2807,7 @@ execute_connection (COMMAND *command, int asynchronous, int pipe_in, int pipe_ou
volatile int save_line_number;
ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
invert = (command->flags & CMD_INVERT_RETURN) != 0;
switch (command->value.Connection->connector)
{
@@ -2808,7 +2852,7 @@ execute_connection (COMMAND *command, int asynchronous, int pipe_in, int pipe_ou
/* Just call execute command on both sides. */
case ';':
case '\n': /* special case, happens in command substitutions */
if (ignore_return)
if (ignore_return || invert)
{
if (command->value.Connection->first)
command->value.Connection->first->flags |= CMD_IGNORE_RETURN;
@@ -2827,6 +2871,10 @@ execute_connection (COMMAND *command, int asynchronous, int pipe_in, int pipe_ou
#endif
QUIT;
#if defined (JOB_CONTROL)
if (command->value.Connection->connector == ';' && job_control && interactive && posixly_correct == 0)
notify_and_cleanup (-1);
#endif
optimize_connection_fork (command); /* XXX */
exec_result = execute_command_internal (command->value.Connection->second,
asynchronous, pipe_in, pipe_out,
@@ -2836,9 +2884,6 @@ execute_connection (COMMAND *command, int asynchronous, int pipe_in, int pipe_ou
case '|':
was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
invert = (command->flags & CMD_INVERT_RETURN) != 0;
ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
SET_LINE_NUMBER (line_number); /* XXX - save value? */
exec_result = execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close);
@@ -3026,7 +3071,7 @@ execute_for_command (FOR_COM *for_command)
else
v = bind_variable (identifier, list->word->word, 0);
if (v == 0 || readonly_p (v) || noassign_p (v))
if (v == 0 || ASSIGN_DISALLOWED (v, 0))
{
line_number = save_line_number;
if (v && readonly_p (v) && interactive_shell == 0 && posixly_correct)
@@ -3181,13 +3226,7 @@ execute_arith_for_command (ARITH_FOR_COM *arith_for_command)
line_number before executing each expression -- for $LINENO
and the DEBUG trap. */
line_number = arith_lineno = arith_for_command->line;
if (variable_context && interactive_shell && sourcelevel == 0)
{
/* line numbers in a function start at 1 */
line_number -= function_line_number - 1;
if (line_number <= 0)
line_number = 1;
}
ADJUST_LINE_NUMBER ();
/* Evaluate the initialization expression. */
expresult = eval_arith_for_expr (arith_for_command->init, &expok);
@@ -3199,6 +3238,21 @@ execute_arith_for_command (ARITH_FOR_COM *arith_for_command)
expresult = eval_arith_for_expr (arith_for_command->test, &expok);
line_number = save_lineno;
/* If the step or test expressions execute `break' or `continue' in a
nofork command substitution or by some other means, break the loop
here. */
if (breaking)
{
breaking--;
break;
}
if (continuing)
{
continuing--;
if (continuing)
break;
}
if (expok == 0)
break;
@@ -3520,7 +3574,7 @@ execute_select_command (SELECT_COM *select_command)
}
v = bind_variable (identifier, selection, 0);
if (v == 0 || readonly_p (v) || noassign_p (v))
if (v == 0 || ASSIGN_DISALLOWED (v, 0))
{
if (v && readonly_p (v) && interactive_shell == 0 && posixly_correct)
{
@@ -3841,13 +3895,7 @@ execute_arith_command (ARITH_COM *arith_command)
this_command_name = "(("; /* )) */
SET_LINE_NUMBER (arith_command->line);
/* If we're in a function, update the line number information. */
if (variable_context && interactive_shell && sourcelevel == 0)
{
/* line numbers in a function start at 1 */
line_number -= function_line_number - 1;
if (line_number <= 0)
line_number = 1;
}
ADJUST_LINE_NUMBER ();
command_string_index = 0;
print_arith_command (arith_command->exp);
@@ -4081,13 +4129,8 @@ execute_cond_command (COND_COM *cond_command)
SET_LINE_NUMBER (cond_command->line);
/* If we're in a function, update the line number information. */
if (variable_context && interactive_shell && sourcelevel == 0)
{
/* line numbers in a function start at 1 */
line_number -= function_line_number - 1;
if (line_number <= 0)
line_number = 1;
}
ADJUST_LINE_NUMBER ();
command_string_index = 0;
print_cond_command (cond_command);
@@ -4151,7 +4194,7 @@ bind_lastarg (char *arg)
static int
execute_null_command (REDIRECT *redirects, int pipe_in, int pipe_out, int async)
{
int r;
int r, code;
int forcefork, fork_flags;
REDIRECT *rd;
@@ -4186,6 +4229,10 @@ execute_null_command (REDIRECT *redirects, int pipe_in, int pipe_out, int async)
if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
subshell_environment |= SUBSHELL_PIPE;
code = setjmp_nosigs (top_level);
if (code)
exit (EXECUTION_FAILURE);
if (do_redirections (redirects, RX_ACTIVE) == 0)
exit (EXECUTION_SUCCESS);
else
@@ -4230,13 +4277,13 @@ fix_assignment_words (WORD_LIST *words)
{
WORD_LIST *w, *wcmd;
struct builtin *b;
int assoc, global, array, integer;
int assoc, global, array;
if (words == 0)
return;
b = 0;
assoc = global = array = integer = 0;
assoc = global = array = 0;
/* Skip over assignment statements preceding a command name */
wcmd = words;
@@ -4428,13 +4475,7 @@ execute_simple_command (SIMPLE_COM *simple_command, int pipe_in, int pipe_out, i
QUIT;
/* If we're in a function, update the line number information. */
if (variable_context && interactive_shell && sourcelevel == 0)
{
/* line numbers in a function start at 1 */
line_number -= function_line_number - 1;
if (line_number <= 0)
line_number = 1;
}
ADJUST_LINE_NUMBER ();
/* Remember what this command line looks like at invocation. */
command_string_index = 0;
@@ -4886,23 +4927,6 @@ execute_from_filesystem:
pipe_in, pipe_out, async, fds_to_close,
cmdflags);
#if 0
/* If we forked but still have to fork again to run the disk command, we
did so because we created FIFOs. We can't just execve the command in case
it dies of a signal without a chance to clean up the FIFOs, so we fork
again, then make sure we wait for the child from execute_disk_command(),
unlink the FIFOs we created, and exit ourselves. */
if (dofork && already_forked && (cmdflags & CMD_NO_FORK) == 0)
{
result = wait_for (last_made_pid, 0);
#if defined (PROCESS_SUBSTITUTION)
if (fifos_pending ())
unlink_fifo_list ();
#endif
sh_exit (result & 0xFF);
}
#endif
return_result:
bind_lastarg (lastarg);
FREE (command_line);
@@ -5274,7 +5298,7 @@ execute_function (SHELL_VAR *var, WORD_LIST *words, int flags, struct fd_bitmap
sfile = shell_fn ? shell_fn->source_file : "";
array_push ((ARRAY *)funcname_a, this_shell_function->name);
array_push ((ARRAY *)bash_source_a, sfile);
push_source ((ARRAY *)bash_source_a, sfile);
lineno = GET_LINE_NUMBER ();
t = itos (lineno);
array_push ((ARRAY *)bash_lineno_a, t);
@@ -5524,6 +5548,8 @@ execute_subshell_builtin_or_function (WORD_LIST *words, REDIRECT *redirects,
}
else
{
if (async)
optimize_shell_function (function_cell (var));
r = execute_function (var, words, flags, fds_to_close, async, 1);
fflush (stdout);
subshell_exit (r);
@@ -5694,6 +5720,14 @@ setup_async_signals (void)
NOTE: callers expect this to fork or exit(). */
/* See comment above where notfound_str is declared. */
void
init_notfound_str (void)
{
if (notfound_str == 0)
notfound_str = _("command not found");
}
/* Name of a shell function to call when a command name is not found. */
#ifndef NOTFOUND_HOOK
# define NOTFOUND_HOOK "command_not_found_handle"
@@ -5751,6 +5785,8 @@ execute_disk_command (WORD_LIST *words, REDIRECT *redirects, char *command_line,
maybe_make_export_env ();
put_command_name_into_env (command);
}
else if (command == 0 && notfound_str == 0) /* make sure */
init_notfound_str ();
/* We have to make the child before we check for the non-existence
of COMMAND, since we want the error messages to be redirected. */
@@ -5837,7 +5873,7 @@ execute_disk_command (WORD_LIST *words, REDIRECT *redirects, char *command_line,
{
/* Make sure filenames are displayed using printable characters */
pathname = printable_filename (pathname, 0);
internal_error (_("%s: command not found"), pathname);
internal_error ("%s: %s", pathname, notfound_str);
exit (EX_NOTFOUND); /* Posix.2 says the exit status is 127 */
}
@@ -6073,7 +6109,7 @@ shell_execve (char *command, char **args, char **env)
last_command_exit_value = (i == ENOENT) ? EX_NOTFOUND : EX_NOEXEC; /* XXX Posix.2 says that exit status is 126 */
if (file_isdir (command))
#if defined (EISDIR)
internal_error (_("%s: %s"), command, strerror (EISDIR));
internal_error ("%s: %s", command, strerror (EISDIR));
#else
internal_error (_("%s: is a directory"), command);
#endif
@@ -6104,14 +6140,14 @@ shell_execve (char *command, char **args, char **env)
interp = getinterp (sample, sample_len, (int *)NULL);
ilen = strlen (interp);
errno = i;
if (interp > 0 && interp[ilen - 1] == '\r')
if (ilen > 0 && interp[ilen - 1] == '\r')
{
interp = xrealloc (interp, ilen + 2);
interp[ilen - 1] = '^';
interp[ilen] = 'M';
interp[ilen + 1] = '\0';
}
sys_error (_("%s: %s: bad interpreter"), command, interp);
sys_error ("%s: %s: %s", command, interp, _("bad interpreter"));
FREE (interp);
return (EX_NOEXEC);
}
@@ -6157,7 +6193,7 @@ shell_execve (char *command, char **args, char **env)
#endif
if (check_binary_file (sample, sample_len))
{
internal_error (_("%s: cannot execute binary file: %s"), command, strerror (i));
internal_error ("%s: %s: %s", command, _("cannot execute binary file"), strerror (i));
errno = i;
return (EX_BINARY_FILE);
}
@@ -6220,8 +6256,21 @@ execute_intern_function (WORD_DESC *name, FUNCTION_DEF *funcdef)
{
SHELL_VAR *var;
char *t;
int pflags;
if (valid_function_word (name, posixly_correct) == 0)
/* This is where we enforce any restrictions on the function name via the
call to valid_function_word(). */
pflags = 0;
#if POSIX_RESTRICT_FUNCNAME
if (posixly_correct)
pflags |= 1; /* enforce posix function name restrictions */
#endif
if (posixly_correct)
pflags |= 4; /* no special builtins */
/* We still allow functions with the same name as reserved words, so they
can be called if quoted. */
if (valid_function_word (name, pflags) == 0)
{
if (posixly_correct)
{
@@ -6239,7 +6288,7 @@ execute_intern_function (WORD_DESC *name, FUNCTION_DEF *funcdef)
}
var = find_function (name->word);
if (var && (readonly_p (var) || noassign_p (var)))
if (var && ASSIGN_DISALLOWED (var, 0))
{
if (readonly_p (var))
internal_error (_("%s: readonly function"), var->name);
+2
View File
@@ -134,4 +134,6 @@ extern void bind_lastarg (char *);
extern void uw_dispose_fd_bitmap (void *);
extern void uw_close (void *);
extern void init_notfound_str (void);
#endif /* _EXECUTE_CMD_H_ */
+3 -4
View File
@@ -1,6 +1,6 @@
/* expr.c -- arithmetic expression evaluation. */
/* Copyright (C) 1990-2023 Free Software Foundation, Inc.
/* Copyright (C) 1990-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -26,8 +26,8 @@
order of decreasing precedence.
"id++", "id--" [post-increment and post-decrement]
"-", "+" [(unary operators)]
"++id", "--id" [pre-increment and pre-decrement]
"-", "+" [(unary operators)]
"!", "~"
"**" [(exponentiation)]
"*", "/", "%"
@@ -336,7 +336,7 @@ expr_bind_variable (const char *lhs, const char *rhs)
aflags = 0;
#endif
v = bind_int_variable (lhs, rhs, aflags);
if (v && (readonly_p (v) || noassign_p (v)))
if (v && ASSIGN_DISALLOWED (v, 0))
sh_longjmp (evalbuf, 1); /* variable assignment error */
stupidly_hack_special_variables (lhs);
}
@@ -467,7 +467,6 @@ subexpr (const char *expr)
val = EXP_LOWEST ();
/*TAG:bash-5.3 make it clear that these are arithmetic syntax errors */
if (curtok != 0)
evalerror (_("arithmetic syntax error in expression"));
+2 -1
View File
@@ -537,7 +537,7 @@ extern size_t utf8_mbstrlen (const char *);
/* declarations for functions defined in lib/sh/wcsnwidth.c */
#if defined (HANDLE_MULTIBYTE)
extern int wcsnwidth (const wchar_t *, size_t, int);
extern int wcsnwidth (const wchar_t *, size_t, size_t);
#endif
/* declarations for functions defined in lib/sh/winsize.c */
@@ -559,6 +559,7 @@ extern ssize_t zreadintr (int, char *, size_t);
extern ssize_t zreadc (int, char *);
extern ssize_t zreadcintr (int, char *);
extern ssize_t zreadn (int, char *, size_t);
extern int zungetc (int);
extern void zreset (void);
extern void zsyncfd (int);
+19 -12
View File
@@ -357,12 +357,12 @@ check_identifier (WORD_DESC *word, int check_word)
{
if (word->flags & (W_HASDOLLAR|W_QUOTED)) /* XXX - HASDOLLAR? */
{
internal_error (_("`%s': not a valid identifier"), word->word);
err_invalidid (word->word);
return (0);
}
else if (check_word && (all_digits (word->word) || valid_identifier (word->word) == 0))
{
internal_error (_("`%s': not a valid identifier"), word->word);
err_invalidid (word->word);
return (0);
}
else
@@ -431,10 +431,15 @@ valid_function_name (const char *name, int flags)
/* Return 1 if this is an identifier that can be used as a function name
when declaring a function. We don't allow `$' for historical reasons.
We allow quotes (for now), slashes, and pretty much everything else.
If FLAGS is non-zero (it's usually posixly_correct), we check the name
for additional posix restrictions using valid_function_name(). We pass
flags|2 to valid_function_name to suppress the check for an assignment
word, since we want to allow those here. */
If (FLAGS&4) is non-zero, we check that the name is not one of the POSIX
special builtins (this is the shell enforcing a POSIX application
requirement). We allow reserved words, even though it's unlikely anyone
would use them.
If (FLAGS&1) is non-zero (it's usually set by the caller from
posixly_correct), we check the name for additional posix restrictions
using valid_function_name().
We pass flags|2 to valid_function_name to suppress the check for an
assignment word, since we want to allow those here. */
int
valid_function_word (WORD_DESC *word, int flags)
{
@@ -443,18 +448,20 @@ valid_function_word (WORD_DESC *word, int flags)
name = word->word;
if ((word->flags & W_HASDOLLAR)) /* allow quotes for now */
{
internal_error (_("`%s': not a valid identifier"), name);
err_invalidid (name);
return (0);
}
/* POSIX interpretation 383 */
if (flags && find_special_builtin (name))
/* POSIX interpretation 383 -- this is an application requirement, but the
shell should enforce it rather than allow a script to define a function
that will never be called. */
if ((flags & 4) && find_special_builtin (name))
{
internal_error (_("`%s': is a special builtin"), name);
return (0);
}
if (flags && valid_function_name (name, flags|2) == 0)
if ((flags & 1) && valid_function_name (name, flags|2) == 0)
{
internal_error (_("`%s': not a valid identifier"), name);
err_invalidid (name);
return (0);
}
return 1;
@@ -834,7 +841,7 @@ absolute_program (const char *string)
return ((char *)mbschr (string, '/') != (char *)NULL);
#else
return ((char *)mbschr (string, '/') != (char *)NULL ||
(char *)mbschr (string, '\\') != (char *)NULL)
(char *)mbschr (string, '\\') != (char *)NULL);
#endif
}
+1 -1
View File
@@ -112,7 +112,7 @@ phash_insert (char *filename, char *full_path, int check_dot, int found)
pathdata(item)->flags = 0;
if (check_dot)
pathdata(item)->flags |= HASH_CHKDOT;
if (*full_path != '/')
if (RELPATH (full_path))
pathdata(item)->flags |= HASH_RELPATH;
item->times_found = found;
}
+36 -30
View File
@@ -1,5 +1,5 @@
/* Multibyte character data type.
Copyright (C) 2001, 2005-2007, 2009-2010, 2021 Free Software Foundation, Inc.
Copyright (C) 2001, 2005-2007, 2009-2010, 2021,2024 Free Software Foundation, Inc.
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
@@ -32,33 +32,39 @@
#include <wchar.h>
#include <wctype.h>
/* is_basic(c) tests whether the single-byte character c is in the
ISO C "basic character set". */
/* is_basic(c) tests whether the single-byte character c is
- in the ISO C "basic character set" or is one of '@', '$', and '`'
which ISO C 23 § 5.2.1.1.(1) guarantees to be single-byte and in
practice are safe to treat as basic in the execution character set,
or
- in the POSIX "portable character set", which
<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap06.html>
equally guarantees to be single-byte. */
#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
&& ('$' == 36) && ('%' == 37) && ('&' == 38) && ('\'' == 39) \
&& ('(' == 40) && (')' == 41) && ('*' == 42) && ('+' == 43) \
&& (',' == 44) && ('-' == 45) && ('.' == 46) && ('/' == 47) \
&& ('0' == 48) && ('1' == 49) && ('2' == 50) && ('3' == 51) \
&& ('4' == 52) && ('5' == 53) && ('6' == 54) && ('7' == 55) \
&& ('8' == 56) && ('9' == 57) && (':' == 58) && (';' == 59) \
&& ('<' == 60) && ('=' == 61) && ('>' == 62) && ('?' == 63) \
&& ('@' == 64) && ('A' == 65) && ('B' == 66) && ('C' == 67) \
&& ('D' == 68) && ('E' == 69) && ('F' == 70) && ('G' == 71) \
&& ('H' == 72) && ('I' == 73) && ('J' == 74) && ('K' == 75) \
&& ('L' == 76) && ('M' == 77) && ('N' == 78) && ('O' == 79) \
&& ('P' == 80) && ('Q' == 81) && ('R' == 82) && ('S' == 83) \
&& ('T' == 84) && ('U' == 85) && ('V' == 86) && ('W' == 87) \
&& ('X' == 88) && ('Y' == 89) && ('Z' == 90) && ('[' == 91) \
&& ('\\' == 92) && (']' == 93) && ('^' == 94) && ('_' == 95) \
&& ('`' == 96) && ('a' == 97) && ('b' == 98) && ('c' == 99) \
&& ('d' == 100) && ('e' == 101) && ('f' == 102) && ('g' == 103) \
&& ('h' == 104) && ('i' == 105) && ('j' == 106) && ('k' == 107) \
&& ('l' == 108) && ('m' == 109) && ('n' == 110) && ('o' == 111) \
&& ('p' == 112) && ('q' == 113) && ('r' == 114) && ('s' == 115) \
&& ('t' == 116) && ('u' == 117) && ('v' == 118) && ('w' == 119) \
&& ('x' == 120) && ('y' == 121) && ('z' == 122) && ('{' == 123) \
&& ('|' == 124) && ('}' == 125) && ('~' == 126)
/* The character set is ISO-646, not EBCDIC. */
# define IS_BASIC_ASCII 1
@@ -95,20 +101,20 @@ is_basic (char c)
{
case '\b': case '\r': case '\n':
case '\t': case '\v': case '\f':
case ' ': case '!': case '"': case '#': case '%':
case ' ': case '!': case '"': case '#': case '$': case '%':
case '&': case '\'': case '(': case ')': case '*':
case '+': case ',': case '-': case '.': case '/':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case ':': case ';': case '<': case '=': case '>':
case '?':
case '?': case '@':
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case '[': case '\\': case ']': case '^': case '_':
case '[': case '\\': case ']': case '^': case '_': case '`':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
+1 -1
View File
@@ -86,7 +86,7 @@ extern int locale_utf8locale; /* XXX */
#define UTF8_SINGLEBYTE(c) (1)
#define UTF8_MBFIRSTCHAR(c) (0)
#defined VALID_SINGLEBYTE_CHAR(c) (1)
#define VALID_SINGLEBYTE_CHAR(c) (1)
#endif /* !HANDLE_MULTIBYTE */
+386 -78
View File
@@ -216,6 +216,9 @@ volatile pid_t last_asynchronous_pid = NO_PID;
/* The pipeline currently being built. */
PROCESS *the_pipeline = (PROCESS *)NULL;
/* We are forking this pipeline (process) to perform a command substitution. */
PROCESS *comsub_pipeline = (PROCESS *)NULL;
/* If this is non-zero, do job control. */
int job_control = 1;
@@ -230,6 +233,11 @@ int already_making_children = 0;
int check_window_size = CHECKWINSIZE_DEFAULT;
PROCESS *last_procsub_child = (PROCESS *)NULL;
pid_t last_procsub_pid = NO_PID;
/* Set to non-zero if you want to force job notifications even in contexts
where the shell would defer them. */
int want_job_notifications = 0;
/* Functions local to this file. */
@@ -269,13 +277,14 @@ static WAIT raw_job_exit_status (int);
static int job_killed_by_signal (int);
static void notify_of_job_status (void);
static inline void maybe_print_job_notifications (int);
static void notify_of_job_status (int);
static void reset_job_indices (void);
static void cleanup_dead_jobs (void);
static int processes_in_job (int);
static void realloc_jobs_list (void);
static int compact_jobs_list (int);
static void add_process (char *, pid_t);
static PROCESS *add_process (char *, pid_t);
static void print_pipeline (PROCESS *, int, int, FILE *);
static void pretty_print_job (int, int, FILE *);
static void set_current_job (int);
@@ -337,10 +346,11 @@ static SigHandler *old_cont = (SigHandler *)SIG_DFL;
/* A place to temporarily save the current pipeline. */
static struct pipeline_saver *saved_pipeline;
/* Set this to non-zero whenever you don't want the jobs list to change at
/* Set this to 1 whenever you don't want the jobs list to change at
all: no jobs deleted and no status change notifications. This is used,
for example, when executing SIGCHLD traps, which may run arbitrary
commands. */
commands. Set to -1 if you allow status change notifications but no
jobs deleted. 0 means everything is allowed. */
static int jobs_list_frozen;
static char retcode_name_buffer[64];
@@ -562,7 +572,7 @@ stop_pipeline (int async, COMMAND *deferred)
cleanup_dead_jobs ();
if (js.j_jobslots == 0)
{
{
js.j_jobslots = JOB_SLOTS;
jobs = (JOB **)xmalloc (js.j_jobslots * sizeof (JOB *));
@@ -638,8 +648,9 @@ stop_pipeline (int async, COMMAND *deferred)
the_pipeline = (PROCESS *)NULL;
newjob->pgrp = pipeline_pgrp;
/* Invariant: if the shell is executing a command substitution,
pipeline_pgrp == shell_pgrp. Other parts of the shell assume this. */
/* Invariant: if the shell is executing a command substitution when
job control is enabled, pipeline_pgrp == shell_pgrp.
Other parts of the shell assume this. */
if (pipeline_pgrp != shell_pgrp)
pipeline_pgrp = 0;
@@ -964,6 +975,21 @@ bgp_prune (void)
}
#endif
/* Find any pid in the bgpids table and return it. It's pretty much random
because of how the hashing works, so we just return the first one. */
static struct pidstat *
bgp_findone (void)
{
ps_index_t psi;
if (bgpids.storage == 0 || bgpids.nalloc == 0 || bgpids.npid == 0)
return NULL;
for (psi = 0; psi < bgpids.nalloc; psi++)
if (bgpids.storage[psi].pid != NO_PID)
return (&bgpids.storage[psi]);
return NULL;
}
/* External interface to bgp_add/bgp_search/bgp_delete; takes care of blocking
and unblocking SIGCHLD if needed. If retrieve_proc_status or delete_proc_status
is called with BLOCK non-zero, the caller must block and unblock SIGCHLD. */
@@ -974,7 +1000,7 @@ save_proc_status (pid_t pid, int status)
sigset_t set, oset;
BLOCK_CHILD (set, oset);
bgp_add (pid, status);
bgp_add (pid, process_exit_status (status));
UNBLOCK_CHILD (oset);
}
@@ -1042,27 +1068,32 @@ procsub_add (PROCESS *p)
}
PROCESS *
procsub_search (pid_t pid)
procsub_search (pid_t pid, int block)
{
PROCESS *p;
sigset_t set, oset;
BLOCK_CHILD (set, oset);
if (block)
BLOCK_CHILD (set, oset);
for (p = procsubs.head; p; p = p->next)
if (p->pid == pid)
break;
UNBLOCK_CHILD (oset);
if (block)
UNBLOCK_CHILD (oset);
return p;
}
/* Take the PROCESS * corresponding to PID out of the procsubs list and
return it. */
PROCESS *
procsub_delete (pid_t pid)
procsub_delete (pid_t pid, int block)
{
PROCESS *p, *prev;
sigset_t set, oset;
BLOCK_CHILD (set, oset);
if (block)
BLOCK_CHILD (set, oset);
for (p = prev = procsubs.head; p; prev = p, p = p->next)
if (p->pid == pid)
{
@@ -1072,7 +1103,8 @@ procsub_delete (pid_t pid)
if (p == 0)
{
UNBLOCK_CHILD (oset);
if (block)
UNBLOCK_CHILD (oset);
return p;
}
@@ -1089,7 +1121,9 @@ procsub_delete (pid_t pid)
/* this can't be called anywhere in a signal handling path */
bgp_add (p->pid, process_exit_status (p->status));
UNBLOCK_CHILD (oset);
if (block)
UNBLOCK_CHILD (oset);
return (p);
}
@@ -1099,7 +1133,7 @@ procsub_waitpid (pid_t pid)
PROCESS *p;
int r;
p = procsub_search (pid);
p = procsub_search (pid, 1);
if (p == 0)
return -1;
if (p->running == PS_DONE)
@@ -1129,7 +1163,6 @@ procsub_clear (void)
sigset_t set, oset;
BLOCK_CHILD (set, oset);
for (ps = procsubs.head; ps; )
{
p = ps;
@@ -1137,7 +1170,9 @@ procsub_clear (void)
procsub_free (p);
}
procsubs.head = procsubs.end = 0;
procsubs.nproc = 0;
procsubs.nproc = 0;
last_procsub_child = NULL;
UNBLOCK_CHILD (oset);
}
@@ -1165,6 +1200,8 @@ procsub_prune (void)
if (p->running == PS_DONE)
{
bgp_add (p->pid, process_exit_status (p->status));
if (p == last_procsub_child)
last_procsub_child = NULL;
procsub_free (p);
}
else
@@ -1172,6 +1209,50 @@ procsub_prune (void)
p = ps;
}
}
void
procsub_reap (void)
{
int os;
QUEUE_SIGCHLD(os);
procsub_prune ();
UNQUEUE_SIGCHLD (os);
}
void
procsub_setflag (pid_t pid, int flag, int block)
{
sigset_t set, oset;
PROCESS *p;
if (block)
BLOCK_CHILD (set, oset);
for (p = procsubs.head; p; p = p->next)
if (p->pid == pid || pid == ANY_PID)
p->flags |= flag;
if (block)
UNBLOCK_CHILD (oset);
}
void
procsub_unsetflag (pid_t pid, int flag, int block)
{
sigset_t set, oset;
PROCESS *p;
if (block)
BLOCK_CHILD (set, oset);
for (p = procsubs.head; p; p = p->next)
if (p->pid == pid || pid == ANY_PID)
p->flags &= ~flag;
if (block)
UNBLOCK_CHILD (oset);
}
#endif
/* Reset the values of js.j_lastj and js.j_firstj after one or both have
@@ -1224,8 +1305,15 @@ cleanup_dead_jobs (void)
register int i;
int os;
/* Even if the jobs list is frozen or there aren't any background jobs,
clean up any terminated process substitutions. */
if (js.j_jobslots == 0 || jobs_list_frozen)
return;
{
#if defined (PROCESS_SUBSTITUTION)
procsub_reap ();
#endif
return;
}
QUEUE_SIGCHLD(os);
@@ -1246,8 +1334,8 @@ cleanup_dead_jobs (void)
}
#if defined (PROCESS_SUBSTITUTION)
/* Don't need to call procsub_reap() since SIGCHLD is already blocked. */
procsub_prune ();
last_procsub_child = (PROCESS *)NULL;
#endif
#if defined (COPROCESS_SUPPORT)
@@ -1468,6 +1556,29 @@ nohup_job (int job_index)
temp->flags |= J_NOHUP;
}
PROCESS *
alloc_process (char *name, pid_t pid)
{
PROCESS *t;
t = (PROCESS *)xmalloc (sizeof (PROCESS));
t->pid = pid;
WSTATUS (t->status) = 0;
t->running = PS_RUNNING; /* default */
t->flags = 0;
t->command = name;
t->next = (PROCESS *)0;
return (t);
}
void
dispose_process (PROCESS *t)
{
FREE (t->command);
free (t);
}
/* Get rid of the data structure associated with a process chain. */
int
discard_pipeline (PROCESS *chain)
@@ -1480,8 +1591,7 @@ discard_pipeline (PROCESS *chain)
do
{
next = this->next;
FREE (this->command);
free (this);
dispose_process (this);
n++;
this = next;
}
@@ -1492,8 +1602,9 @@ discard_pipeline (PROCESS *chain)
/* Add this process to the chain being built in the_pipeline.
NAME is the command string that will be exec'ed later.
PID is the process id of the child. */
static void
PID is the process id of the child. Returns the PROCESS *
we just created if the caller wants to use it or set flags. */
static PROCESS *
add_process (char *name, pid_t pid)
{
PROCESS *t, *p;
@@ -1511,12 +1622,8 @@ add_process (char *name, pid_t pid)
}
#endif
t = (PROCESS *)xmalloc (sizeof (PROCESS));
t = alloc_process (name, pid);
t->next = the_pipeline;
t->pid = pid;
WSTATUS (t->status) = 0;
t->running = PS_RUNNING;
t->command = name;
the_pipeline = t;
if (t->next == 0)
@@ -1528,6 +1635,8 @@ add_process (char *name, pid_t pid)
p = p->next;
p->next = t;
}
return t;
}
/* Create a (dummy) PROCESS with NAME, PID, and STATUS, and make it the last
@@ -1537,13 +1646,11 @@ append_process (char *name, pid_t pid, int status, int jid)
{
PROCESS *t, *p;
t = (PROCESS *)xmalloc (sizeof (PROCESS));
t->next = (PROCESS *)NULL;
t->pid = pid;
t = alloc_process (name, pid);
/* set process exit status using offset discovered by configure */
t->status = (status & 0xff) << WEXITSTATUS_OFFSET;
t->running = PS_DONE;
t->command = name;
js.c_reaped++; /* XXX */
@@ -1741,7 +1848,7 @@ find_pipeline (pid_t pid, int alive_only, int *jobp)
return (p);
#if defined (PROCESS_SUBSTITUTION)
if (procsubs.nproc > 0 && (p = procsub_search (pid)) && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p)))
if (procsubs.nproc > 0 && (p = procsub_search (pid, 0)) && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p)))
return (p);
#endif
@@ -1811,6 +1918,9 @@ get_job_by_pid (pid_t pid, int block, PROCESS **procp)
int job;
sigset_t set, oset;
if (pid < 0)
return (NO_JOB);
if (block)
BLOCK_CHILD (set, oset);
@@ -1905,19 +2015,26 @@ printable_job_status (int j, PROCESS *p, int format)
/* This is the way to print out information on a job if you
know the index. FORMAT is:
JLIST_NORMAL) [1]+ Running emacs
JLIST_STANDARD) [1]+ Running emacs
JLIST_LONG ) [1]+ 2378 Running emacs
-1 ) [1]+ 2378 emacs
JLIST_NORMAL) [1]+ Stopped ls | more
JLIST_STANDARD) [1]+ Stopped ls | more
JLIST_LONG ) [1]+ 2369 Stopped ls
2367 | more
JLIST_PID_ONLY)
Just list the pid of the process group leader (really
the process group).
JLIST_CHANGED_ONLY)
Use format JLIST_NORMAL, but list only jobs about which
the user has not been notified. */
Use format JLIST_STANDARD, but list only jobs about which
the user has not been notified.
JLIST_POSIX)
Use format JLIST_STANDARD, list all background jobs, running
and stopped, plus jobs about which the user has not been
notified (that would be notified)
JLIST_BGONLY)
Use format JLIST_STANDARD, but restrict output to background
jobs only. */
/* Print status for pipeline P. If JOB_INDEX is >= 0, it is the index into
the JOBS array corresponding to this pipeline. FORMAT is as described
@@ -1945,9 +2062,14 @@ print_pipeline (PROCESS *p, int job_index, int format, FILE *stream)
fprintf (stream, format ? " " : " |");
if (format != JLIST_STANDARD)
fprintf (stream, "%5ld", (long)p->pid);
{
fprintf (stream, "%5ld", (long)p->pid);
if (p == first)
fprintf (stream, " ");
}
fprintf (stream, " ");
if (p != first)
fprintf (stream, " ");
if (format > -1 && job_index >= 0)
{
@@ -2021,6 +2143,29 @@ print_pipeline (PROCESS *p, int job_index, int format, FILE *stream)
fflush (stream);
}
/* We want to print information about a job if it's running or terminated in
the background, if it's stopped, or if it was a foreground job terminated
due to a signal that we don't ignore (SIGINT and possibly SIGTERM and
SIGPIPE). If we change this, change the conditions in notify_of_job_status()
so they stay consistent.
This is for use by the jobs builtin. */
static int
should_notify (int job)
{
/* Background jobs, stopped jobs whether they were in the foreground or
background. */
if ((IS_FOREGROUND (job) == 0) || STOPPED (job))
return 1;
/* Foreground job killed by a signal we report on. */
if (DEADJOB (job) && IS_FOREGROUND (job) && job_killed_by_signal (job))
return 1;
return 0; /* catch-all */
}
/* Print information to STREAM about jobs[JOB_INDEX] according to FORMAT.
Must be called with SIGCHLD blocked or queued with queue_sigchld */
static void
@@ -2028,6 +2173,13 @@ pretty_print_job (int job_index, int format, FILE *stream)
{
register PROCESS *p;
/* If the jobs list is frozen, skip jobs we would remove and not report on */
if (jobs_list_frozen && should_notify (job_index) == 0)
return;
if (format == JLIST_BGONLY && IS_FOREGROUND (job_index))
return;
/* Format only pid information about the process group leader? */
if (format == JLIST_PID_ONLY)
{
@@ -2041,6 +2193,12 @@ pretty_print_job (int job_index, int format, FILE *stream)
return;
format = JLIST_STANDARD;
}
else if (format == JLIST_POSIX)
{
if (IS_FOREGROUND (job_index) && IS_NOTIFIED (job_index))
return;
format = JLIST_STANDARD;
}
if (format != JLIST_NONINTERACTIVE)
fprintf (stream, "[%d]%c ", job_index + 1,
@@ -2050,8 +2208,10 @@ pretty_print_job (int job_index, int format, FILE *stream)
if (format == JLIST_NONINTERACTIVE)
format = JLIST_LONG;
p = jobs[job_index]->pipe;
if (format == JLIST_STANDARD)
fprintf (stream, "%c", ' '); /* used to be in print_pipeline */
p = jobs[job_index]->pipe;
print_pipeline (p, job_index, format, stream);
/* We have printed information about this job. When the job's
@@ -2108,6 +2268,7 @@ make_child (char *command, int flags)
unsigned int forksleep;
sigset_t set, oset, oset_copy;
pid_t pid;
PROCESS *child;
SigHandler *oterm;
sigemptyset (&oset_copy);
@@ -2212,6 +2373,7 @@ make_child (char *command, int flags)
pipeline_pgrp = mypid;
/* Check for running command in backquotes. */
/* XXX - do this if (flags & FORK_NOJOB)? */
if (pipeline_pgrp == shell_pgrp)
ignore_tty_job_signals ();
else
@@ -2225,7 +2387,7 @@ make_child (char *command, int flags)
this would have for the first child) is an error. Section
B.4.3.3, p. 237 also covers this, in the context of job control
shells. */
if (setpgid (mypid, pipeline_pgrp) < 0)
if ((flags & FORK_NOJOB) == 0 && setpgid (mypid, pipeline_pgrp) < 0)
sys_error (_("child setpgid (%ld to %ld)"), (long)mypid, (long)pipeline_pgrp);
/* By convention (and assumption above), if
@@ -2289,7 +2451,8 @@ make_child (char *command, int flags)
the POSIX 1003.1 standard, where it discusses job control and
shells. It is done to avoid possible race conditions. (Ref.
1003.1 Rationale, section B.4.3.3, page 236). */
setpgid (pid, pipeline_pgrp);
if ((flags & FORK_NOJOB) == 0)
setpgid (pid, pipeline_pgrp);
}
else
{
@@ -2299,7 +2462,13 @@ make_child (char *command, int flags)
/* Place all processes into the jobs array regardless of the
state of job_control. */
add_process (command, pid);
child = add_process (command, pid);
/* Set up the flags based on what the caller provides. */
if (flags & FORK_PROCSUB)
child->flags |= PROC_PROCSUB;
if (flags & FORK_COMSUB)
child->flags |= PROC_COMSUB;
if (async_p)
last_asynchronous_pid = pid;
@@ -2571,7 +2740,11 @@ wait_for_single_pid (pid_t pid, int flags)
{
r = bgp_search (pid);
if (r >= 0)
return r;
{
if (posixly_correct)
bgp_delete (pid);
return r;
}
}
if (child == 0)
@@ -2605,7 +2778,7 @@ wait_for_single_pid (pid_t pid, int flags)
/* If running in posix mode, remove the job from the jobs table immediately */
if (posixly_correct)
{
cleanup_dead_jobs ();
cleanup_dead_jobs (); /* calls procsub_prune */
bgp_delete (pid);
}
@@ -2673,9 +2846,13 @@ wait_for_background_pids (struct procstat *ps)
}
#if defined (PROCESS_SUBSTITUTION)
# if defined (WAIT_WAITS_FOR_ALL_PROCSUBS)
procsub_waitall ();
# else
if (last_procsub_child && last_procsub_child->pid != NO_PID && last_procsub_child->pid == last_asynchronous_pid)
procsub_waitpid (last_procsub_child->pid);
reap_procsubs (); /* closes fd */
# endif
delete_procsubs (); /* closes fds or unlinks fifos */
#endif
/* POSIX.2 says the shell can discard the statuses of all completed jobs if
@@ -3096,7 +3273,8 @@ if (job == NO_JOB)
if (WIFSIGNALED (s) || WIFSTOPPED (s))
{
set_tty_state ();
if (running_trap == 0 /* || WIFSTOPPED (s) */)
set_tty_state ();
/* If the current job was stopped or killed by a signal, and
the user has requested it, get a possibly new window size */
@@ -3200,7 +3378,8 @@ if (job == NO_JOB)
the shell is not interactive, make sure we turn on the notify bit
so we don't get an unwanted message about the job's termination,
and so delete_job really clears the slot in the jobs table. */
notify_and_cleanup ();
if (posixly_correct == 0 || interactive_shell == 0 || interactive == 0)
notify_and_cleanup (job);
}
wait_for_return:
@@ -3262,20 +3441,25 @@ wait_for_job (int job, int flags, struct procstat *ps)
return r;
}
/* Wait for any background job started by this shell to finish. Very
similar to wait_for_background_pids(). Returns the exit status of
the next exiting job, -1 if there are no background jobs. The caller
is responsible for translating -1 into the right return value. RPID,
if non-null, gets the pid of the job's process leader. */
/* Wait for any background job started by this shell to finish, including
process substitutions.
Very similar to wait_for_background_pids(). Returns the exit status of
the next exiting job, -1 if there are no background jobs. If we are in
posix mode, we can take a pid from bgpids since we will delete it.
The caller is responsible for translating -1 into the right return value.
PS, if non-null, gets the pid and status of the job's process leader. */
int
wait_for_any_job (int flags, struct procstat *ps)
{
pid_t pid;
int i, r;
sigset_t set, oset;
struct pidstat *t;
PROCESS *p, *child;
/* Allow funsubs to run this, but don't remove jobs from the jobs table. */
if (jobs_list_frozen && executing_funsub == 0)
if (jobs_list_frozen > 0)
return -1;
/* First see if there are any unnotified dead jobs that we can report on */
@@ -3296,14 +3480,12 @@ return_job:
}
if (jobs_list_frozen == 0) /* must be running a funsub to get here */
{
notify_of_job_status (); /* XXX */
#if 1 /* TAG: bash-5.3 kre@munnari.oz.au 01/30/2024 */
notify_of_job_status (i); /* XXX */
/* kre@munnari.oz.au 01/30/2024 */
delete_job (i, posixly_correct ? DEL_NOBGPID : 0);
#else
delete_job (i, 0);
#endif
}
else
else /* if (jobs_list_frozen < 0) */ /* status changes only */
jobs[i]->flags |= J_NOTIFIED; /* clean up later */
#if defined (COPROCESS_SUPPORT)
coproc_reap ();
@@ -3312,6 +3494,61 @@ return_job:
return r;
}
}
#if defined (PROCESS_SUBSTITUTION)
/* We don't have any dead jobs, but let's see if we have a dead procsub. */
for (p = procsubs.head; p; p = p->next)
{
/* If we're waiting for specific pids, skip over ones we're not interested in. */
if ((flags & JWAIT_WAITING) && (p->flags & PROC_WAITING) == 0)
continue;
#if defined (WAIT_N_WAITS_FOR_LAST_PROCSUB)
/* If we want to restrict wait -n without pid arguments to only wait
for last_procsub_child->pid, uncomment this. */
if ((flags & JWAIT_WAITING) == 0 && p != last_procsub_child)
continue;
#endif
if (p->running == PS_DONE)
{
return_procsub:
if (p == last_procsub_child)
last_procsub_child = (PROCESS *)NULL;
r = process_exit_status (p->status);
pid = p->pid;
if (ps)
{
ps->pid = pid;
ps->status = r;
}
child = procsub_delete (pid, 0); /* XXX - procsub_reap? */
if (child == last_procsub_child)
last_procsub_child = NULL;
procsub_free (child);
if (posixly_correct)
bgp_delete (pid);
UNBLOCK_CHILD (oset);
return r;
}
}
#endif
/* There aren't any dead jobs in the jobs table, but let's see if there's
one in bgpids. We can do this in posix mode because we'll remove any
one we find from the table, preserving existing semantics. */
if (posixly_correct && (t = bgp_findone ()))
{
pid = t->pid;
r = t->status;
if (ps)
{
ps->pid = pid;
ps->status = r;
}
bgp_delete (pid);
UNBLOCK_CHILD (oset);
return r;
}
UNBLOCK_CHILD (oset);
/* At this point, we have no dead jobs in the jobs table. Wait until we
@@ -3332,7 +3569,27 @@ return_job:
goto return_job;
}
if (i == js.j_jobslots)
p = NULL;
#if defined (PROCESS_SUBSTITUTION)
/* Do we have any procsubs that are still candidates? */
for (p = procsubs.head; p; p = p->next)
{
if ((flags & JWAIT_WAITING) && (p->flags & PROC_WAITING) == 0)
continue;
#if 0
/* If we want to restrict wait -n without pid arguments to only wait
for last_procsub_child->pid, uncomment this. */
if ((flags & JWAIT_WAITING) == 0 && p != last_procsub_child && p->running == PS_DONE)
continue;
#endif
else if (p->running == PS_DONE)
goto return_procsub;
else if (p->running == PS_RUNNING) /* still got one */
break;
}
#endif
if (i == js.j_jobslots && p == NULL)
{
UNBLOCK_CHILD (oset);
return -1;
@@ -3358,6 +3615,15 @@ return_job:
if (jobs[i] && DEADJOB (i))
goto return_job;
}
#if defined (PROCESS_SUBSTITUTION)
for (p = procsubs.head; p; p = p->next)
{
if ((flags & JWAIT_WAITING) && (p->flags & PROC_WAITING) == 0)
continue;
else if (p->running == PS_DONE)
goto return_procsub;
}
#endif
UNBLOCK_CHILD (oset);
}
@@ -3367,15 +3633,18 @@ return_job:
/* Print info about dead jobs, and then delete them from the list
of known jobs. This does not actually delete jobs when the
shell is not interactive, because the dead jobs are not marked
as notified. */
as notified.
If JOB is >= 0, only print info about that job and then clean it up. */
void
notify_and_cleanup (void)
notify_and_cleanup (int job)
{
if (jobs_list_frozen)
if (jobs_list_frozen > 0)
return;
if (interactive || interactive_shell == 0 || sourcelevel)
notify_of_job_status ();
maybe_print_job_notifications (job);
if (jobs_list_frozen < 0)
return; /* status changes only */
cleanup_dead_jobs ();
}
@@ -3633,7 +3902,12 @@ start_job (int job, int foreground)
/* Save the tty settings before we start the job in the foreground. */
if (foreground)
{
get_tty_state ();
#if defined (READLINE)
/* Don't fetch the terminal attributes if we're doing this from a key
binding or programmable completion. */
if (RL_ISSTATE(RL_STATE_COMPLETING|RL_STATE_DISPATCHING|RL_STATE_TERMPREPPED) == 0)
#endif
get_tty_state ();
save_stty = shell_tty_info;
jobs[job]->flags &= ~J_ASYNC; /* no longer async */
/* Give the terminal to this job. */
@@ -3665,7 +3939,12 @@ start_job (int job, int foreground)
}
else
{
#if 0
/* XXX TAG:bash-5.4 */
set_current_job (job);
#else
reset_current ();
#endif
UNBLOCK_CHILD (oset);
return (0);
}
@@ -3896,7 +4175,8 @@ itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, bloc
is blocked. We only use this as a hint that we can remove FIFOs
or close file descriptors corresponding to terminated process
substitutions. */
if ((ind = find_procsub_child (pid)) >= 0)
/* XXX - should combine this list with procsub_add, etc. */
if ((ind = find_procsub_child (pid)) >= 0 && (WIFEXITED (status) || WIFSIGNALED (status)))
set_procsub_status (ind, pid, WSTATUS (status));
#endif
@@ -3907,7 +4187,12 @@ itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, bloc
if (child == 0)
{
if (WIFEXITED (status) || WIFSIGNALED (status))
js.c_reaped++;
{
js.c_reaped++;
js.c_totreaped++;
if (pid == wpid) /* but we're waiting for it?? */
internal_debug ("waitchld: pid == wpid but child == 0");
}
continue;
}
@@ -3988,7 +4273,7 @@ itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, bloc
that this process belongs to is no longer running, then notify the user
of that fact now. */
if (children_exited && asynchronous_notification && interactive && executing_builtin == 0)
notify_of_job_status ();
notify_of_job_status (-1);
return (children_exited);
}
@@ -4246,11 +4531,13 @@ run_sigchld_trap (int nchild)
}
/* Function to call when you want to notify people of changes
in job status. This prints out all jobs which are pending
notification to stderr, and marks those printed as already
notified, thus making them candidates for cleanup. */
in job status. This prints out all requested jobs which are
pending notification to stderr, and marks those printed as
notified, thus making them candidates for cleanup.
if WANTED is >=0, we print information only about that job;
otherwise we print all jobs whose status has changed. */
static void
notify_of_job_status (void)
notify_of_job_status (int wanted)
{
register int job, termsig;
char *dir;
@@ -4274,6 +4561,9 @@ notify_of_job_status (void)
/* XXX could use js.j_firstj here */
for (job = 0, dir = NULL; job < js.j_jobslots; job++)
{
if (wanted >= 0 && job != wanted)
continue;
if (jobs[job] && IS_NOTIFIED (job) == 0)
{
s = raw_job_exit_status (job);
@@ -4357,14 +4647,19 @@ notify_of_job_status (void)
if (termsig && WIFSIGNALED (s) && termsig != SIGINT && termsig != SIGPIPE)
#endif
{
#if 0
fprintf (stderr, "%s", j_strsignal (termsig));
if (WIFCORED (s))
fprintf (stderr, _(" (core dumped)"));
fprintf (stderr, "\n");
#else
print_pipeline (jobs[job]->pipe, job, JLIST_STANDARD, stderr);
#endif
}
/* foreground jobs that exit cleanly */
/* foreground jobs that exit cleanly or due to a signal we
don't report on */
jobs[job]->flags |= J_NOTIFIED;
}
else if (job_control)
@@ -4415,6 +4710,19 @@ internal_debug("notify_of_job_status: catch-all setting J_NOTIFIED on job %d (%d
queue_sigchld--;
}
/* Use this to determine when to conditionally print job notifications. We
print notifications if another part of the shell forces it, if we are
currently interactive, or if we are not an interactive shell. For
compatibility, we can also print notifications if we are sourcing a file
in an interactive shell.
In a separate inline function so the conditions are in one place. */
static inline void
maybe_print_job_notifications (int job)
{
if (want_job_notifications || interactive || interactive_shell == 0)
notify_of_job_status (job);
}
/* Initialize the job control mechanism, and set up the tty stuff. */
int
initialize_job_control (int force)
@@ -4970,12 +5278,12 @@ itrace("mark_dead_jobs_as_notified: child_max = %d ndead = %d ndeadproc = %d", j
/* Here to allow other parts of the shell (like the trap stuff) to
freeze and unfreeze the jobs list. */
int
freeze_jobs_list (void)
freeze_jobs_list (int n)
{
int o;
o = jobs_list_frozen;
jobs_list_frozen = 1;
jobs_list_frozen = n;
return o;
}
+31 -10
View File
@@ -34,9 +34,14 @@
#define JLIST_PID_ONLY 2
#define JLIST_CHANGED_ONLY 3
#define JLIST_NONINTERACTIVE 4
#define JLIST_POSIX 5
#define JLIST_BGONLY 6
/* I looked it up. For pretty_print_job (). The real answer is 24. */
#define LONGEST_SIGNAL_DESC 24
/* I looked it up. For pretty_print_job (). The real answer is 27
(macOS SIGPROF) but the makefile or configure can override it. */
#ifndef LONGEST_SIGNAL_DESC
# define LONGEST_SIGNAL_DESC 27
#endif
/* Defines for the wait_for_* functions and for the wait builtin to use */
#define JWAIT_PERROR (1 << 0)
@@ -60,6 +65,12 @@
#define PS_STOPPED 2
#define PS_RECYCLED 4
/* Values for the `flags' field of a struct process. */
#define PROC_WAITING 0x01
#define PROC_PROCSUB 0x02
#define PROC_COMSUB 0x04
#define PROC_LASTPIPE 0x08
/* Each child of the shell is remembered in a STRUCT PROCESS. A circular
chain of such structures is a pipeline. */
typedef struct process {
@@ -67,6 +78,7 @@ typedef struct process {
pid_t pid; /* Process ID. */
WAIT status; /* The status of this command as returned by wait. */
int running; /* Non-zero if this process is running. */
int flags; /* Placeholder for process-specific flag values. */
char *command; /* The particular program that is running. */
} PROCESS;
@@ -201,10 +213,12 @@ struct procchain {
#define ANY_PID (pid_t)-1
/* flags for make_child () */
#define FORK_SYNC 0 /* normal synchronous process */
#define FORK_ASYNC 1 /* background process */
#define FORK_NOJOB 2 /* don't put process in separate pgrp */
#define FORK_NOTERM 4 /* don't give terminal to any pgrp */
#define FORK_SYNC 0x0 /* normal synchronous process */
#define FORK_ASYNC 0x1 /* background process */
#define FORK_NOJOB 0x2 /* don't put process in separate pgrp */
#define FORK_NOTERM 0x4 /* don't give terminal to any pgrp */
#define FORK_COMSUB 0x8 /* command substitution */
#define FORK_PROCSUB 0x10 /* process substitution */
/* System calls. */
#if !defined (HAVE_UNISTD_H)
@@ -217,11 +231,13 @@ extern struct jobstats js;
extern pid_t original_pgrp, shell_pgrp, pipeline_pgrp;
extern volatile pid_t last_made_pid, last_asynchronous_pid;
extern int asynchronous_notification;
extern int want_job_notifications;
extern int already_making_children;
extern int running_in_background;
extern PROCESS *last_procsub_child;
extern pid_t last_procsub_pid;
extern JOB **jobs;
@@ -233,6 +249,8 @@ extern void save_pipeline (int);
extern PROCESS *restore_pipeline (int);
extern void start_pipeline (void);
extern int stop_pipeline (int, COMMAND *);
extern PROCESS *alloc_process (char *, pid_t);
extern void dispose_process (PROCESS *);
extern int discard_pipeline (PROCESS *);
extern void append_process (char *, pid_t, int, int);
@@ -241,12 +259,15 @@ extern int retrieve_proc_status (pid_t, int);
extern void delete_proc_status (pid_t, int);
extern PROCESS *procsub_add (PROCESS *);
extern PROCESS *procsub_search (pid_t);
extern PROCESS *procsub_delete (pid_t);
extern PROCESS *procsub_search (pid_t, int);
extern PROCESS *procsub_delete (pid_t, int);
extern int procsub_waitpid (pid_t);
extern void procsub_waitall (void);
extern void procsub_clear (void);
extern void procsub_prune (void);
extern void procsub_reap (void);
extern void procsub_setflag (pid_t, int, int);
extern void procsub_unsetflag (pid_t, int, int);
extern void delete_job (int, int);
extern void nohup_job (int);
@@ -291,7 +312,7 @@ extern int wait_for_any_job (int, struct procstat *);
extern void wait_sigint_cleanup (void);
extern void notify_and_cleanup (void);
extern void notify_and_cleanup (int);
extern void reap_dead_jobs (void);
extern int start_job (int, int);
extern int kill_pid (pid_t, int, int);
@@ -301,7 +322,7 @@ extern int give_terminal_to (pid_t, int);
extern void run_sigchld_trap (int);
extern int freeze_jobs_list (void);
extern int freeze_jobs_list (int);
extern int unfreeze_jobs_list (void);
extern void set_jobs_list_frozen (int);
extern int jobs_list_frozen_status (void);
+14 -8
View File
@@ -4,7 +4,7 @@
# #
####################################################################
#
# Copyright (C) 1996-2009 Free Software Foundation, Inc.
# Copyright (C) 1996-2024 Free Software Foundation, Inc.
# 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
@@ -39,6 +39,7 @@ MV = mv
SHELL = @MAKE_SHELL@
PROFILE_FLAGS = @PROFILE_FLAGS@
ADDON_CFLAGS =
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
@@ -67,8 +68,11 @@ LIBRARY_NAME = libglob.a
# The C code source files for this library.
CSOURCES = $(srcdir)/glob.c $(srcdir)/strmatch.c $(srcdir)/smatch.c \
$(srcdir)/gmisc.c \
$(srcdir)/xmbsrtowcs.c
LOOP_FILES = $(srcdir)/glob_loop.c $(srcdir)/gm_loop.c $(srcdir)/sm_loop.c
# The header files for this library.
HSOURCES = $(srcdir)/strmatch.h
@@ -101,7 +105,7 @@ what-tar:
done
documentation: force
-(cd doc; $(MAKE) $(MFLAGS))
-(cd doc; $(MAKE) $(BASH_MAKEFLAGS))
force:
# The rule for 'includes' is written funny so that the if statement
@@ -109,19 +113,21 @@ force:
# include files.
install:
clean:
.PHONY: clean maintainer-clean distclean mostlyclean
mostlyclean:
rm -f $(OBJECTS) $(LIBRARY_NAME)
-(cd doc && $(MAKE) $(MFLAGS) $@ )
-(cd doc && $(MAKE) $(BASH_MAKEFLAGS) $@ )
realclean distclean maintainer-clean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
-( cd doc && $(MAKE) $(BASH_MAKEFLAGS) $@ )
$(RM) -f Makefile
mostlyclean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
clean: mostlyclean
-( cd doc && $(MAKE) $(BASH_MAKEFLAGS) $@ )
${BUILD_DIR}/pathnames.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile
-( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} pathnames.h )
-( cd ${BUILD_DIR} && ${MAKE} ${BASH_MAKEFLAGS} pathnames.h )
######################################################################
# #
+5 -2
View File
@@ -72,7 +72,6 @@ ALLOCA_SOURCE = alloca.c
ALLOCA_OBJECT = alloca.o
MALLOC_SRC = @MALLOC_SRC@
MALLOC = @MALLOC@
ALLOCA = @ALLOCA@
MALLOC_OBJS = malloc.o $(ALLOCA) trace.o stats.o table.o watch.o
@@ -103,9 +102,13 @@ alloca.o: $(srcdir)/$(ALLOCA_SOURCE)
mv $(ALLOCA_OBJECT) alloca.o >/dev/null 2>&1 ; \
fi
mostlyclean clean:
.PHONY: clean maintainer-clean distclean mostlyclean
mostlyclean:
$(RM) *.o libmalloc.a
clean: mostlyclean
distclean realclean maintainer-clean: clean
$(RM) Makefile
+3 -2
View File
@@ -274,7 +274,7 @@ typedef union _malloc_guard {
/* Use this when we want to be sure that NB is in bucket NU. */
#define RIGHT_BUCKET(nb, nu) \
(((nb) > binsizes[(nu)-1]) && ((nb) <= binsizes[(nu)]))
(((nb) > (((nu) >= 1) ? binsizes[(nu)-1] : 0UL)) && ((nb) <= binsizes[(nu)]))
/* nextf[i] is free list of blocks of size 2**(i + 5) */
@@ -1140,6 +1140,7 @@ internal_realloc (PTR_T mem, size_t n, const char *file, int line, int flags)
if (n == 0)
{
internal_free (mem, file, line, MALLOC_INTERNAL);
/* XXX - return internal_malloc (0, file, line MALLOC_INTERNAL) ? */
return (NULL);
}
if ((p = (union mhead *) mem) == 0)
@@ -1202,7 +1203,7 @@ internal_realloc (PTR_T mem, size_t n, const char *file, int line, int flags)
nbytes = ALLOCATED_BYTES(n);
/* If ok, use the same block, just marking its size as changed. */
if (RIGHT_BUCKET(nbytes, nunits) || RIGHT_BUCKET(nbytes, nunits-1))
if (RIGHT_BUCKET(nbytes, nunits) || (nunits >= 1 && RIGHT_BUCKET(nbytes, nunits-1)))
{
/* Compensate for increment above. */
m -= 4;
+1 -1
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2023 Free Software Foundation, Inc.
/* Copyright (C) 2023-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+12 -8
View File
@@ -4,7 +4,7 @@
# #
#############################################################################
# Copyright (C) 1994-2012 Free Software Foundation, Inc.
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
# 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
@@ -54,6 +54,8 @@ CTAGS = ctags -tw
DEBUG = @DEBUG@
ADDON_CFLAGS =
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG}
STYLE_CFLAGS = @STYLE_CFLAGS@
@@ -137,7 +139,7 @@ libhistory.a: $(HISTOBJ) xmalloc.o xfree.o
documentation: force
test -d doc || mkdir doc
-( cd doc && $(MAKE) $(MFLAGS) )
-( cd doc && $(MAKE) $(BASH_MAKEFLAGS) )
# Since tilde.c is shared between readline and bash, make sure we compile
# it with the right flags when it's built as part of readline
@@ -159,15 +161,17 @@ TAGS: force
tags: force
$(CTAGS) $(CSOURCES) $(HSOURCES)
clean: force
$(RM) $(OBJECTS) *.a
-( cd doc && $(MAKE) $(MFLAGS) $@ )
.PHONY: clean maintainer-clean distclean mostlyclean
mostlyclean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
mostlyclean: force
$(RM) $(OBJECTS) *.a
-( cd doc && $(MAKE) $(BASH_MAKEFLAGS) $@ )
clean: mostlyclean
-( cd doc && $(MAKE) $(BASH_MAKEFLAGS) $@ )
distclean maintainer-clean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
-( cd doc && $(MAKE) $(BASH_MAKEFLAGS) $@ )
$(RM) Makefile
$(RM) TAGS tags
+27 -26
View File
@@ -1,6 +1,6 @@
/* bind.c -- key binding and startup file support for the readline library. */
/* Copyright (C) 1987-2023 Free Software Foundation, Inc.
/* Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -98,6 +98,15 @@ static int currently_reading_init_file;
/* used only in this file */
static int _rl_prefer_visible_bell = 1;
/* Currently confined to this file for key bindings. If enabled (> 0), we
force meta key bindings to use the meta prefix (ESC). If unset (-1) or
disabled (0), we use the current value of _rl_convert_meta_chars_to_ascii
as in previous readline versions. */
static int _rl_force_meta_prefix = 0;
/* Do we want to force binding "\M-C" to the meta prefix (ESC-C)? */
#define FORCE_META_PREFIX() (_rl_force_meta_prefix > 0 ? 1 : _rl_convert_meta_chars_to_ascii)
#define OP_EQ 1
#define OP_NE 2
#define OP_GT 3
@@ -137,7 +146,7 @@ rl_bind_key (int key, rl_command_func_t *function)
return (key);
/* Want to make this a multi-character key sequence with an ESC prefix */
if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
if (META_CHAR (key) && FORCE_META_PREFIX())
{
if (_rl_keymap[ESC].type == ISKMAP)
{
@@ -257,7 +266,7 @@ rl_unbind_function_in_map (rl_command_func_t *func, Keymap map)
map[i].function = (rl_command_func_t *)NULL;
rval = 1;
}
else if (map[i].type == ISKMAP) /* TAG:readline-8.1 */
else if (map[i].type == ISKMAP)
{
int r;
r = rl_unbind_function_in_map (func, FUNCTION_TO_KEYMAP (map, i));
@@ -418,19 +427,8 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
return -1;
}
/* We now rely on rl_translate_keyseq to do this conversion, so this
check is superfluous. */
#if 0
if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
{
ic = UNMETA (ic);
if (map[ESC].type == ISKMAP)
{
prevmap = map;
map = FUNCTION_TO_KEYMAP (map, ESC);
}
}
#endif
/* We rely on rl_translate_keyseq to do convert meta-chars to key
sequences with the meta prefix (ESC). */
if ((i + 1) < keys_len)
{
@@ -617,14 +615,13 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
c = (c == '?') ? RUBOUT : CTRL (_rl_to_upper (c));
has_control = 0;
}
if (has_meta)
{
c = META (c);
has_meta = 0;
}
/* If convert-meta is turned on, convert a meta char to a key sequence */
if (META_CHAR (c) && _rl_convert_meta_chars_to_ascii)
if (has_meta)
c = META (c);
/* If force-meta-prefix is turned on, convert a meta char to a key
sequence, but only if it uses the \M- syntax. */
if (META_CHAR (c) && has_meta && FORCE_META_PREFIX())
{
int x = UNMETA (c);
if (x)
@@ -638,6 +635,8 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
else
array[l++] = (c);
has_meta = 0;
/* Null characters may be processed for incomplete prefixes at the end of
sequence */
if (seq[i] == '\0')
@@ -698,7 +697,7 @@ rl_untranslate_keyseq (int seq)
c = UNMETA (c);
}
if (c == ESC)
if (c == ESC) /* look at _rl_force_meta_prefix here? */
{
kseq[i++] = '\\';
c = 'e';
@@ -805,7 +804,7 @@ _rl_function_of_keyseq_internal (const char *keyseq, size_t len, Keymap map, int
{
unsigned char ic = keyseq[i];
if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
if (META_CHAR (ic) && FORCE_META_PREFIX()) /* XXX - might not want this */
{
if (map[ESC].type == ISKMAP)
{
@@ -1865,6 +1864,7 @@ rl_parse_and_bind (char *string)
false. */
#define V_SPECIAL 0x1
#define V_DEPRECATED 0x02
static const struct {
const char * const name;
@@ -1888,6 +1888,7 @@ static const struct {
{ "enable-keypad", &_rl_enable_keypad, 0 },
{ "enable-meta-key", &_rl_enable_meta, 0 },
{ "expand-tilde", &rl_complete_with_tilde_expansion, 0 },
{ "force-meta-prefix", &_rl_force_meta_prefix, 0 },
{ "history-preserve-point", &_rl_history_preserve_point, 0 },
{ "horizontal-scroll-mode", &_rl_horizontal_scroll_mode, 0 },
{ "input-meta", &_rl_meta_flag, 0 },
@@ -2749,7 +2750,7 @@ rl_print_keybinding (const char *name, Keymap kmap, int print_readably)
char **invokers;
function = rl_named_function (name);
invokers = rl_invoking_keyseqs_in_map (function, kmap ? kmap : _rl_keymap);
invokers = function ? rl_invoking_keyseqs_in_map (function, kmap ? kmap : _rl_keymap) : (char **)NULL;
if (print_readably)
{
+1 -1
View File
@@ -73,7 +73,7 @@
static bool is_colored (enum indicator_no type);
static void restore_default_color (void);
#define RL_COLOR_PREFIX_EXTENSION ".readline-colored-completion-prefix"
#define RL_COLOR_PREFIX_EXTENSION "readline-colored-completion-prefix"
COLOR_EXT_TYPE *_rl_color_ext_list = 0;
+104 -19
View File
@@ -77,6 +77,10 @@ extern int errno;
# include "colors.h"
#endif
#ifndef MIN
#define MIN(x,y) (((x) < (y)) ? (x): (y))
#endif
typedef int QSFUNC (const void *, const void *);
#ifdef HAVE_LSTAT
@@ -149,6 +153,8 @@ static int complete_get_screenwidth (void);
static char *make_quoted_replacement (char *, int, char *);
static void _rl_export_completions (char **, char *, int, int);
/* **************************************************************** */
/* */
/* Completion matching, from readline's point of view. */
@@ -535,6 +541,18 @@ _rl_complete_sigcleanup (int sig, void *ptr)
/* */
/************************************/
static inline size_t
vector_len (char **vector)
{
size_t ret;
if (vector == 0 || vector[0] == 0)
return (size_t)0;
for (ret = 0; vector[ret]; ret++)
;
return ret;
}
/* Reset public readline state on a signal or other event. */
void
_rl_reset_completion_state (void)
@@ -863,7 +881,8 @@ fnprint (const char *to_print, int prefix_bytes, const char *real_pathname)
possible completions. Only cut off prefix_bytes if we're going to be
printing the ellipsis, which takes precedence over coloring the
completion prefix (see print_filename() below). */
if (_rl_completion_prefix_display_length > 0 && prefix_bytes >= print_len)
if (_rl_completion_prefix_display_length > 0 && prefix_bytes >= print_len &&
prefix_bytes > _rl_completion_prefix_display_length)
prefix_bytes = 0;
#if defined (COLOR_SUPPORT)
@@ -882,13 +901,16 @@ fnprint (const char *to_print, int prefix_bytes, const char *real_pathname)
printed_len = ELLIPSIS_LEN;
}
#if defined (COLOR_SUPPORT)
else if (prefix_bytes && _rl_colored_completion_prefix > 0)
else if (prefix_bytes && _rl_completion_prefix_display_length <= 0 &&
_rl_colored_completion_prefix > 0)
{
common_prefix_len = prefix_bytes;
prefix_bytes = 0;
/* XXX - print color indicator start here */
colored_prefix_start ();
}
else
common_prefix_len = prefix_bytes = 0; /* no ellipsis or color */
#endif
s = to_print + prefix_bytes;
@@ -1297,8 +1319,7 @@ remove_duplicate_matches (char **matches)
char **temp_array;
/* Sort the items. */
for (i = 0; matches[i]; i++)
;
i = vector_len (matches);
/* Sort the array without matches[0], since we need it to
stay in place no matter what. */
@@ -1355,9 +1376,9 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text)
int low; /* Count of max-matched characters. */
int lx;
char *dtext; /* dequoted TEXT, if needed */
size_t si1, si2;
size_t len1, len2;
#if defined (HANDLE_MULTIBYTE)
int v;
size_t v1, v2;
mbstate_t ps1, ps2;
WCHAR_T wc1, wc2;
@@ -1385,7 +1406,7 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text)
len1 = strlen (match_list[i]);
len2 = strlen (match_list[i + 1]);
for (si = 0; (c1 = match_list[i][si]) && (c2 = match_list[i + 1][si]); si++)
for (si1 = si2 = 0; (c1 = match_list[i][si1]) && (c2 = match_list[i + 1][si2]); si1++,si2++)
{
if (_rl_completion_case_fold)
{
@@ -1395,8 +1416,8 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text)
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
v1 = MBRTOWC (&wc1, match_list[i]+si, len1 - si, &ps1);
v2 = MBRTOWC (&wc2, match_list[i+1]+si, len2 - si, &ps2);
v1 = MBRTOWC (&wc1, match_list[i]+si1, len1 - si1, &ps1);
v2 = MBRTOWC (&wc2, match_list[i+1]+si2, len2 - si2, &ps2);
if (MB_INVALIDCH (v1) || MB_INVALIDCH (v2))
{
if (c1 != c2) /* do byte comparison */
@@ -1410,8 +1431,11 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text)
}
if (wc1 != wc2)
break;
else if (v1 > 1)
si += v1 - 1;
if (v1 > 1)
si1 += v1 - 1;
if (v2 > 1)
si2 += v2 - 1;
}
else
#endif
@@ -1419,6 +1443,7 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text)
break;
}
si = MIN (si1, si2); /* use shorter of matches of different length */
if (low > si)
low = si;
}
@@ -1581,7 +1606,7 @@ rl_display_match_list (char **matches, int len, int max)
/* check again in case of /usr/src/ */
temp = rl_filename_completion_desired ? strrchr (t, '/') : 0;
common_length = temp ? fnwidth (temp) : fnwidth (t);
sind = temp ? strlen (temp) : strlen (t);
sind = temp ? RL_STRLEN (temp) : RL_STRLEN (t);
if (common_length > max || sind > max)
common_length = sind = 0;
@@ -2038,7 +2063,9 @@ compare_match (char *text, const char *match)
`!' means to do standard completion, and list all possible completions if
there is more than one.
`@' means to do standard completion, and list all possible completions if
there is more than one and partial completion is not possible. */
there is more than one and partial completion is not possible.
`$' implements a protocol for exporting completions and information about
what is being completed to another process via rl_outstream. */
int
rl_complete_internal (int what_to_do)
{
@@ -2095,9 +2122,11 @@ rl_complete_internal (int what_to_do)
nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
if (what_to_do == '!' || what_to_do == '@')
tlen = strlen (text);
xfree (text);
if (matches == 0)
if (what_to_do != '$')
xfree (text);
if (matches == 0 && what_to_do != '$') /* we can export no completions */
{
rl_ding ();
FREE (saved_line_buffer);
@@ -2113,7 +2142,7 @@ rl_complete_internal (int what_to_do)
rl_filename_completion_function does this. */
i = rl_filename_completion_desired;
if (postprocess_matches (&matches, i) == 0)
if (postprocess_matches (&matches, i) == 0 && what_to_do != '$') /* we can export no completions */
{
rl_ding ();
FREE (saved_line_buffer);
@@ -2199,6 +2228,11 @@ rl_complete_internal (int what_to_do)
do_display = 1;
break;
case '$':
_rl_export_completions (matches, text, start, end);
xfree (text);
break;
default:
_rl_ttymsg ("bad value %d for what_to_do in rl_complete", what_to_do);
rl_ding ();
@@ -2764,8 +2798,8 @@ rl_old_menu_complete (int count, int invoking_key)
RL_UNSETSTATE(RL_STATE_COMPLETING);
for (match_list_size = 0; matches[match_list_size]; match_list_size++)
;
match_list_size = vector_len (matches);
/* matches[0] is lcd if match_list_size > 1, but the circular buffer
code below should take care of it. */
@@ -2899,8 +2933,7 @@ rl_menu_complete (int count, int ignore)
RL_UNSETSTATE(RL_STATE_COMPLETING);
for (match_list_size = 0; matches[match_list_size]; match_list_size++)
;
match_list_size = vector_len (matches);
if (match_list_size == 0)
{
@@ -2999,3 +3032,55 @@ rl_backward_menu_complete (int count, int key)
arguments for menu-complete, and vice versa. */
return (rl_menu_complete (-count, key));
}
/* This implements a protocol to export completions to another process or
calling application via rl_outstream.
MATCHES are the possible completions for TEXT, which is the text between
START and END in rl_line_buffer.
We print:
N - the number of matches
T - the word being completed
S:E - the start and end offsets of T in rl_line_buffer
then each match, one per line
If there are no matches, MATCHES is NULL, N will be 0, and there will be
no output after S:E.
Since MATCHES[0] can be empty if there is no common prefix of the elements
of MATCHES, applications should be prepared to deal with an empty line
preceding the matches.
*/
static void
_rl_export_completions (char **matches, char *text, int start, int end)
{
size_t len, i;
len = vector_len (matches);
if (RL_ISSTATE (RL_STATE_TERMPREPPED))
fprintf (rl_outstream, "\r\n");
fprintf (rl_outstream, "%zd\n", len);
fprintf (rl_outstream, "%s\n", text);
fprintf (rl_outstream, "%d:%d\n", start, end); /* : because it's not a radix character */
for (i = 0; i < len; i++)
fprintf (rl_outstream, "%s\n", matches[i]);
fflush (rl_outstream);
}
int
rl_export_completions (int count, int key)
{
rl_complete_internal ('$');
/* Clear the line buffer, currently requires a count argument. */
if (count > 1)
{
rl_delete_text (0, rl_end); /* undoable */
rl_point = rl_mark = 0;
}
return 0;
}
+30 -11
View File
@@ -1,6 +1,6 @@
/* display.c -- readline redisplay facility. */
/* Copyright (C) 1987-2023 Free Software Foundation, Inc.
/* Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -1111,7 +1111,7 @@ rl_redisplay (void)
#endif
{
#if 0
/* TAG: readline-8.3 20230227 */
/* TAG: readline-8.4 20230227 */
/* https://savannah.gnu.org/support/index.php?110830
asking for non-printing meta characters to be printed using an
escape sequence. */
@@ -1474,13 +1474,22 @@ rl_redisplay (void)
changed_screen_line = _rl_last_v_pos != cursor_linenum;
if (changed_screen_line)
{
int physpos;
/* The physpos calculation is to account for lines with differing
numbers of invisible characters. */
if (mb_cur_max == 1 || rl_byte_oriented)
physpos = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset);
/* Move to the line where the cursor will be. */
_rl_move_vert (cursor_linenum);
/* If we moved up to the line with the prompt using _rl_term_up,
the physical cursor position on the screen stays the same,
but the buffer position needs to be adjusted to account
for invisible characters. */
if ((mb_cur_max == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
_rl_last_c_pos += wrap_offset;
if ((mb_cur_max == 1 || rl_byte_oriented) && cursor_linenum == prompt_last_screen_line)
_rl_last_c_pos = physpos + WRAP_OFFSET (cursor_linenum, wrap_offset);;
}
/* Now we move the cursor to where it needs to be. First, make
@@ -1492,20 +1501,29 @@ rl_redisplay (void)
only need to reprint it if the cursor is before the last
invisible character in the prompt string. */
/* XXX - why not use local_prompt_len? */
/* XXX - This is right only if the prompt is a single line. */
nleft = prompt_visible_length + wrap_offset;
if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
_rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
if (cursor_linenum == prompt_last_screen_line && wrap_offset > 0 &&
_rl_last_c_pos > 0 && local_prompt &&
_rl_last_c_pos < PROMPT_ENDING_INDEX)
{
int pmt_offset;
_rl_cr ();
if (modmark)
_rl_output_some_chars ("*", 1);
_rl_output_some_chars (local_prompt, nleft);
/* If the number of characters in local_prompt is greater than
the screen width, the prompt wraps. We only want to print the
portion after the line wrap. */
pmt_offset = local_prompt_newlines[cursor_linenum];
if (cursor_linenum > 0 && pmt_offset > 0 && nleft > pmt_offset)
_rl_output_some_chars (local_prompt + pmt_offset, nleft - pmt_offset);
else
_rl_output_some_chars (local_prompt, nleft);
if (mb_cur_max > 1 && rl_byte_oriented == 0)
_rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark;
else
_rl_last_c_pos = nleft + modmark;
_rl_last_c_pos = nleft + modmark; /* buffer position */
}
/* Where on that line? And where does that line start
@@ -1524,6 +1542,7 @@ rl_redisplay (void)
the prompt, and there's no good way to tell it, we compensate for
those characters here and call _rl_backspace() directly if
necessary */
/* XXX - might need to check cursor_linenum == prompt_last_screen_line like above. */
if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
{
/* TX == new physical cursor position in multibyte locale. */
@@ -1732,7 +1751,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
{
char *ofd, *ols, *oe, *nfd, *nls, *ne;
char *ofdf, *nfdf, *olsf, *nlsf;
int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
int temp, lendiff, wsatend, od, nd, o_cpos;
int current_invis_chars;
int col_lendiff, col_temp;
int bytes_to_insert;
@@ -1863,7 +1882,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
_rl_output_some_chars below. */
if (newwidth > 0)
{
int count, i, j;
int i, j;
char *optr;
puts_face (new, new_face, newbytes);
+58 -21
View File
@@ -50,6 +50,8 @@ PSDPI = 300 # I don't have any 600-dpi printers
DVIPS = dvips -D ${PSDPI} $(QUIETPS) -o $@ # tricky
DVIPDF = dvipdfm -o $@ -p ${PAPERSIZE}
PSPDF = gs -sPAPERSIZE=${PAPERSIZE} -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -sOutputFile=$@
# experimental; uses external texi2dvi for now; this needs pdftex to be present
TEXI2PDF = texi2dvi --pdf
RLSRC = $(srcdir)/rlman.texi $(srcdir)/rluser.texi \
$(srcdir)/rltech.texi $(srcdir)/version.texi \
@@ -58,7 +60,7 @@ HISTSRC = $(srcdir)/history.texi $(srcdir)/hsuser.texi \
$(srcdir)/hstech.texi $(srcdir)/version.texi
# This should be a program that converts troff to an ascii-readable format
NROFF = groff -Tascii
NROFF = groff -Tascii -P -c
# This should be a program that converts troff to postscript
GROFF = groff
@@ -67,45 +69,75 @@ DVIOBJ = readline.dvi history.dvi rluserman.dvi
INFOOBJ = readline.info history.info rluserman.info
PSOBJ = readline.ps history.ps rluserman.ps
HTMLOBJ = readline.html history.html rluserman.html
PDFOBJ = readline.pdf history.pdf rluserman.pdf
TEXTOBJ = readline.0 history.0
PDFOBJ = readline.pdf history.pdf rluserman.pdf readline_3.pdf history_3.pdf
INTERMEDIATE_OBJ = rlman.dvi
CREATED_DOCS = $(DVIOBJ) $(INFOOBJ) $(PSOBJ) $(HTMLOBJ) $(PDFOBJ)
CREATED_DOCS = $(DVIOBJ) $(INFOOBJ) $(PSOBJ) $(HTMLOBJ) $(PDFOBJ) $(TEXTOBJ)
.SUFFIXES: .ps .txt .dvi .html .pdf
.SUFFIXES: .0 .3 .ps .txt .dvi .html .pdf
.ps.pdf:
.3.0:
$(RM) $@
-${PSPDF} $<
-${NROFF} -man $< > $@
.3.pdf:
$(RM) $@
-${GROFF} -man -T pdf $< > $@
.3.ps:
$(RM) $@
-${GROFF} -man $< > $@
#.ps.pdf:
# $(RM) $@
# -${PSPDF} $<
.dvi.pdf:
$(RM) $@
-${DVIPDF} $<
all: info dvi html ps
nodvi: info html
all: info html text pdf ps dvi
nodvi: info html text
pdf: $(PDFOBJ)
readline.dvi: $(RLSRC)
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rlman.texi
mv rlman.dvi readline.dvi
$(RM) $@
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) -o $@ $(srcdir)/rlman.texi
readline.info: $(RLSRC)
$(RM) $@
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texi
readline.pdf: $(RLSRC)
$(RM) $@
$(TEXI2PDF) -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texi
rluserman.dvi: $(RLSRC)
$(RM) $@
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rluserman.texi
rluserman.info: $(RLSRC)
$(RM) $@
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rluserman.texi
rluserman.pdf: $(RLSRC)
$(RM) $@
$(TEXI2PDF) -I $(TEXINPUTDIR) -o $@ $(srcdir)/rluserman.texi
history.dvi: ${HISTSRC}
$(RM) $@
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/history.texi
history.info: ${HISTSRC}
$(RM) $@
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/history.texi
history.pdf: $(HISTSRC)
$(RM) $@
$(TEXI2PDF) -I $(TEXINPUTDIR) -o $@ $(srcdir)/history.texi
readline.ps: readline.dvi
$(RM) $@
$(DVIPS) readline.dvi
@@ -119,9 +151,8 @@ history.ps: history.dvi
$(DVIPS) history.dvi
readline.html: ${RLSRC}
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rlman.texi
sed -e 's:rlman.html:readline.html:' rlman.html > readline.html
$(RM) rlman.html
$(RM) $@
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texi
rluserman.html: ${RLSRC}
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rluserman.texi
@@ -129,14 +160,23 @@ rluserman.html: ${RLSRC}
history.html: ${HISTSRC}
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/history.texi
history.0: $(srcdir)/history.3
readline.0: $(srcdir)/readline.3
history_3.pdf: $(srcdir)/history.3
$(RM) $@
-${GROFF} -man -T pdf $< > $@
readline_3.pdf: $(srcdir)/readline.3
$(RM) $@
-${GROFF} -man -T pdf $< > $@
info: $(INFOOBJ)
dvi: $(DVIOBJ)
ps: $(PSOBJ)
html: $(HTMLOBJ)
readline.pdf: readline.dvi
history.pdf: history.dvi
rluserman.pdf: rluserman.dvi
text: $(TEXTOBJ)
pdf: $(PDFOBJ)
clean:
$(RM) *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
@@ -148,10 +188,7 @@ distclean: clean
mostlyclean: clean
maintainer-clean: clean
$(RM) $(CREATED_DOCS)
$(RM) $(INTERMEDIATE_OBJ)
$(RM) Makefile
maintainer-clean: distclean
install:
@echo "This documentation should not be installed."
+1 -1
View File
@@ -12,7 +12,7 @@ This document describes the GNU History library
a programming tool that provides a consistent user interface for
recalling lines of previously typed input.
Copyright @copyright{} 1988--2023 Free Software Foundation, Inc.
Copyright @copyright{} 1988--2024 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document

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