mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-07 04:10:49 +02:00
Bash-5.3-beta release
This commit is contained in:
+78
-1
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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}c’ ↦ ‘bac 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
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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 ‘name’s. That is, they may not
|
||||
contain characters other than letters, digits, and underscores, and
|
||||
may not start with a digit. Declaring a function with an 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
|
||||
|
||||
@@ -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’
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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,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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+3262
-2319
File diff suppressed because it is too large
Load Diff
+3581
-2463
File diff suppressed because it is too large
Load Diff
+3417
-2877
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
+3382
-2372
File diff suppressed because it is too large
Load Diff
+3417
-2877
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+2463
-1752
File diff suppressed because it is too large
Load Diff
+1267
-1129
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+29
-26
@@ -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
|
||||
|
||||
Binary file not shown.
+3
-3
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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"));
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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 )
|
||||
|
||||
######################################################################
|
||||
# #
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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."
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user