mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-07 10:42:28 +02:00
commit bash-20100204 snapshot
This commit is contained in:
@@ -357,7 +357,8 @@ compat40 set
|
||||
- the < and > operators to the [[ command do not consider the current
|
||||
locale when comparing strings
|
||||
- interrupting a command list such as "a ; b ; c" causes the execution
|
||||
of the entire list to be aborted
|
||||
of the entire list to be aborted (in versions before bash-4.0,
|
||||
interrupting one command in a list caused the next to be executed)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -0,0 +1,367 @@
|
||||
Compatibility with previous versions
|
||||
====================================
|
||||
|
||||
This document details the incompatibilities between this version of bash,
|
||||
bash-4.1, and the previous widely-available versions, bash-2.x (which is
|
||||
still the `standard' version for a few Linux distributions) and bash-3.x.
|
||||
These were discovered by users of bash-2.x and 3.x, so this list is not
|
||||
comprehensive. Some of these incompatibilities occur between the current
|
||||
version and versions 2.0 and above.
|
||||
|
||||
1. Bash uses a new quoting syntax, $"...", to do locale-specific
|
||||
string translation. Users who have relied on the (undocumented)
|
||||
behavior of bash-1.14 will have to change their scripts. For
|
||||
instance, if you are doing something like this to get the value of
|
||||
a variable whose name is the value of a second variable:
|
||||
|
||||
eval var2=$"$var1"
|
||||
|
||||
you will have to change to a different syntax.
|
||||
|
||||
This capability is directly supported by bash-2.0:
|
||||
|
||||
var2=${!var1}
|
||||
|
||||
This alternate syntax will work portably between bash-1.14 and bash-2.0:
|
||||
|
||||
eval var2=\$${var1}
|
||||
|
||||
2. One of the bugs fixed in the YACC grammar tightens up the rules
|
||||
concerning group commands ( {...} ). The `list' that composes the
|
||||
body of the group command must be terminated by a newline or
|
||||
semicolon. That's because the braces are reserved words, and are
|
||||
recognized as such only when a reserved word is legal. This means
|
||||
that while bash-1.14 accepted shell function definitions like this:
|
||||
|
||||
foo() { : }
|
||||
|
||||
bash-2.0 requires this:
|
||||
|
||||
foo() { :; }
|
||||
|
||||
This is also an issue for commands like this:
|
||||
|
||||
mkdir dir || { echo 'could not mkdir' ; exit 1; }
|
||||
|
||||
The syntax required by bash-2.0 is also accepted by bash-1.14.
|
||||
|
||||
3. The options to `bind' have changed to make them more consistent with
|
||||
the rest of the bash builtins. If you are using `bind -d' to list
|
||||
the readline key bindings in a form that can be re-read, use `bind -p'
|
||||
instead. If you were using `bind -v' to list the key bindings, use
|
||||
`bind -P' instead.
|
||||
|
||||
4. The `long' invocation options must now be prefixed by `--' instead
|
||||
of `-'. (The old form is still accepted, for the time being.)
|
||||
|
||||
5. There was a bug in the version of readline distributed with bash-1.14
|
||||
that caused it to write badly-formatted key bindings when using
|
||||
`bind -d'. The only key sequences that were affected are C-\ (which
|
||||
should appear as \C-\\ in a key binding) and C-" (which should appear
|
||||
as \C-\"). If these key sequences appear in your inputrc, as, for
|
||||
example,
|
||||
|
||||
"\C-\": self-insert
|
||||
|
||||
they will need to be changed to something like the following:
|
||||
|
||||
"\C-\\": self-insert
|
||||
|
||||
6. A number of people complained about having to use ESC to terminate an
|
||||
incremental search, and asked for an alternate mechanism. Bash-2.03
|
||||
uses the value of the settable readline variable `isearch-terminators'
|
||||
to decide which characters should terminate an incremental search. If
|
||||
that variable has not been set, ESC and Control-J will terminate a
|
||||
search.
|
||||
|
||||
7. Some variables have been removed: MAIL_WARNING, notify, history_control,
|
||||
command_oriented_history, glob_dot_filenames, allow_null_glob_expansion,
|
||||
nolinks, hostname_completion_file, noclobber, no_exit_on_failed_exec, and
|
||||
cdable_vars. Most of them are now implemented with the new `shopt'
|
||||
builtin; others were already implemented by `set'. Here is a list of
|
||||
correspondences:
|
||||
|
||||
MAIL_WARNING shopt mailwarn
|
||||
notify set -o notify
|
||||
history_control HISTCONTROL
|
||||
command_oriented_history shopt cmdhist
|
||||
glob_dot_filenames shopt dotglob
|
||||
allow_null_glob_expansion shopt nullglob
|
||||
nolinks set -o physical
|
||||
hostname_completion_file HOSTFILE
|
||||
noclobber set -o noclobber
|
||||
no_exit_on_failed_exec shopt execfail
|
||||
cdable_vars shopt cdable_vars
|
||||
|
||||
8. `ulimit' now sets both hard and soft limits and reports the soft limit
|
||||
by default (when neither -H nor -S is specified). This is compatible
|
||||
with versions of sh and ksh that implement `ulimit'. The bash-1.14
|
||||
behavior of, for example,
|
||||
|
||||
ulimit -c 0
|
||||
|
||||
can be obtained with
|
||||
|
||||
ulimit -S -c 0
|
||||
|
||||
It may be useful to define an alias:
|
||||
|
||||
alias ulimit="ulimit -S"
|
||||
|
||||
9. Bash-2.01 uses a new quoting syntax, $'...' to do ANSI-C string
|
||||
translation. Backslash-escaped characters in ... are expanded and
|
||||
replaced as specified by the ANSI C standard.
|
||||
|
||||
10. The sourcing of startup files has changed somewhat. This is explained
|
||||
more completely in the INVOCATION section of the manual page.
|
||||
|
||||
A non-interactive shell not named `sh' and not in posix mode reads
|
||||
and executes commands from the file named by $BASH_ENV. A
|
||||
non-interactive shell started by `su' and not in posix mode will read
|
||||
startup files. No other non-interactive shells read any startup files.
|
||||
|
||||
An interactive shell started in posix mode reads and executes commands
|
||||
from the file named by $ENV.
|
||||
|
||||
11. The <> redirection operator was changed to conform to the POSIX.2 spec.
|
||||
In the absence of any file descriptor specification preceding the `<>',
|
||||
file descriptor 0 is used. In bash-1.14, this was the behavior only
|
||||
when in POSIX mode. The bash-1.14 behavior may be obtained with
|
||||
|
||||
<>filename 1>&0
|
||||
|
||||
12. The `alias' builtin now checks for invalid options and takes a `-p'
|
||||
option to display output in POSIX mode. If you have old aliases beginning
|
||||
with `-' or `+', you will have to add the `--' to the alias command
|
||||
that declares them:
|
||||
|
||||
alias -x='chmod a-x' --> alias -- -x='chmod a-x'
|
||||
|
||||
13. The behavior of range specificiers within bracket matching expressions
|
||||
in the pattern matcher (e.g., [A-Z]) depends on the current locale,
|
||||
specifically the value of the LC_COLLATE environment variable. Setting
|
||||
this variable to C or POSIX will result in the traditional ASCII behavior
|
||||
for range comparisons. If the locale is set to something else, e.g.,
|
||||
en_US (specified by the LANG or LC_ALL variables), collation order is
|
||||
locale-dependent. For example, the en_US locale sorts the upper and
|
||||
lower case letters like this:
|
||||
|
||||
AaBb...Zz
|
||||
|
||||
so a range specification like [A-Z] will match every letter except `z'.
|
||||
Other locales collate like
|
||||
|
||||
aAbBcC...zZ
|
||||
|
||||
which means that [A-Z] matches every letter except `a'.
|
||||
|
||||
The portable way to specify upper case letters is [:upper:] instead of
|
||||
A-Z; lower case may be specified as [:lower:] instead of a-z.
|
||||
|
||||
Look at the manual pages for setlocale(3), strcoll(3), and, if it is
|
||||
present, locale(1).
|
||||
|
||||
You can find your current locale information by running locale(1):
|
||||
|
||||
caleb.ins.cwru.edu(2)$ locale
|
||||
LANG=en_US
|
||||
LC_CTYPE="en_US"
|
||||
LC_NUMERIC="en_US"
|
||||
LC_TIME="en_US"
|
||||
LC_COLLATE="en_US"
|
||||
LC_MONETARY="en_US"
|
||||
LC_MESSAGES="en_US"
|
||||
LC_ALL=en_US
|
||||
|
||||
My advice is to put
|
||||
|
||||
export LC_COLLATE=C
|
||||
|
||||
into /etc/profile and inspect any shell scripts run from cron for
|
||||
constructs like [A-Z]. This will prevent things like
|
||||
|
||||
rm [A-Z]*
|
||||
|
||||
from removing every file in the current directory except those beginning
|
||||
with `z' and still allow individual users to change the collation order.
|
||||
Users may put the above command into their own profiles as well, of course.
|
||||
|
||||
14. Bash versions up to 1.14.7 included an undocumented `-l' operator to
|
||||
the `test/[' builtin. It was a unary operator that expanded to the
|
||||
length of its string argument. This let you do things like
|
||||
|
||||
test -l $variable -lt 20
|
||||
|
||||
for example.
|
||||
|
||||
This was included for backwards compatibility with old versions of the
|
||||
Bourne shell, which did not provide an easy way to obtain the length of
|
||||
the value of a shell variable.
|
||||
|
||||
This operator is not part of the POSIX standard, because one can (and
|
||||
should) use ${#variable} to get the length of a variable's value.
|
||||
Bash-2.x does not support it.
|
||||
|
||||
15. Bash no longer auto-exports the HOME, PATH, SHELL, TERM, HOSTNAME,
|
||||
HOSTTYPE, MACHTYPE, or OSTYPE variables. If they appear in the initial
|
||||
environment, the export attribute will be set, but if bash provides a
|
||||
default value, they will remain local to the current shell.
|
||||
|
||||
16. Bash no longer initializes the FUNCNAME, GROUPS, or DIRSTACK variables
|
||||
to have special behavior if they appear in the initial environment.
|
||||
|
||||
17. Bash no longer removes the export attribute from the SSH_CLIENT or
|
||||
SSH2_CLIENT variables, and no longer attempts to discover whether or
|
||||
not it has been invoked by sshd in order to run the startup files.
|
||||
|
||||
18. Bash no longer requires that the body of a function be a group command;
|
||||
any compound command is accepted.
|
||||
|
||||
19. As of bash-3.0, the pattern substitution operators no longer perform
|
||||
quote removal on the pattern before attempting the match. This is the
|
||||
way the pattern removal functions behave, and is more consistent.
|
||||
|
||||
20. After bash-3.0 was released, I reimplemented tilde expansion, incorporating
|
||||
it into the mainline word expansion code. This fixes the bug that caused
|
||||
the results of tilde expansion to be re-expanded. There is one
|
||||
incompatibility: a ${paramOPword} expansion within double quotes will not
|
||||
perform tilde expansion on WORD. This is consistent with the other
|
||||
expansions, and what POSIX specifies.
|
||||
|
||||
21. A number of variables have the integer attribute by default, so the +=
|
||||
assignment operator returns expected results: RANDOM, LINENO, MAILCHECK,
|
||||
HISTCMD, OPTIND.
|
||||
|
||||
22. Bash-3.x is much stricter about $LINENO correctly reflecting the line
|
||||
number in a script; assignments to LINENO have little effect.
|
||||
|
||||
23. By default, readline binds the terminal special characters to their
|
||||
readline equivalents. As of bash-3.1/readline-5.1, this is optional and
|
||||
controlled by the bind-tty-special-chars readline variable.
|
||||
|
||||
24. The \W prompt string expansion abbreviates $HOME as `~'. The previous
|
||||
behavior is available with ${PWD##/*/}.
|
||||
|
||||
25. The arithmetic exponentiation operator is right-associative as of bash-3.1.
|
||||
|
||||
26. The rules concerning valid alias names are stricter, as per POSIX.2.
|
||||
|
||||
27. The Readline key binding functions now obey the convert-meta setting active
|
||||
when the binding takes place, as the dispatch code does when characters
|
||||
are read and processed.
|
||||
|
||||
28. The historical behavior of `trap' reverting signal disposition to the
|
||||
original handling in the absence of a valid first argument is implemented
|
||||
only if the first argument is a valid signal number.
|
||||
|
||||
29. In versions of bash after 3.1, the ${parameter//pattern/replacement}
|
||||
expansion does not interpret `%' or `#' specially. Those anchors don't
|
||||
have any real meaning when replacing every match.
|
||||
|
||||
30. Beginning with bash-3.1, the combination of posix mode and enabling the
|
||||
`xpg_echo' option causes echo to ignore all options, not looking for `-n'
|
||||
|
||||
31. Beginning with bash-3.2, bash follows the Bourne-shell-style (and POSIX-
|
||||
style) rules for parsing the contents of old-style backquoted command
|
||||
substitutions. Previous versions of bash attempted to recursively parse
|
||||
embedded quoted strings and shell constructs; bash-3.2 uses strict POSIX
|
||||
rules to find the closing backquote and simply passes the contents of the
|
||||
command substitution to a subshell for parsing and execution.
|
||||
|
||||
32. Beginning with bash-3.2, bash uses access(2) when executing primaries for
|
||||
the test builtin and the [[ compound command, rather than looking at the
|
||||
file permission bits obtained with stat(2). This obeys restrictions of
|
||||
the file system (e.g., read-only or noexec mounts) not available via stat.
|
||||
|
||||
33. Bash-3.2 adopts the convention used by other string and pattern matching
|
||||
operators for the `[[' compound command, and matches any quoted portion
|
||||
of the right-hand-side argument to the =~ operator as a string rather
|
||||
than a regular expression.
|
||||
|
||||
34. Bash-4.0 allows the behavior in the previous item to be modified using
|
||||
the notion of a shell `compatibility level'. If the compat31 shopt
|
||||
option is set, quoting the pattern has no special effect.
|
||||
|
||||
35. Bash-3.2 (patched) and Bash-4.0 fix a bug that leaves the shell in an
|
||||
inconsistent internal state following an assignment error. One of the
|
||||
changes means that compound commands or { ... } grouping commands are
|
||||
aborted under some circumstances in which they previously were not.
|
||||
This is what Posix specifies.
|
||||
|
||||
36. Bash-4.0 now allows process substitution constructs to pass unchanged
|
||||
through brace expansion, so any expansion of the contents will have to be
|
||||
separately specified, and each process subsitution will have to be
|
||||
separately entered.
|
||||
|
||||
37. Bash-4.0 now allows SIGCHLD to interrupt the wait builtin, as Posix
|
||||
specifies, so the SIGCHLD trap is no longer always invoked once per
|
||||
exiting child if you are using `wait' to wait for all children.
|
||||
|
||||
38. Since bash-4.0 now follows Posix rules for finding the closing delimiter
|
||||
of a $() command substitution, it will not behave as previous versions
|
||||
did, but will catch more syntax and parsing errors before spawning a
|
||||
subshell to evaluate the command substitution.
|
||||
|
||||
39. The programmable completion code uses the same set of delimiting characters
|
||||
as readline when breaking the command line into words, rather than the
|
||||
set of shell metacharacters, so programmable completion and readline
|
||||
should be more consistent.
|
||||
|
||||
40. When the read builtin times out, it attempts to assign any input read to
|
||||
specified variables, which also causes variables to be set to the empty
|
||||
string if there is not enough input. Previous versions discarded the
|
||||
characters read.
|
||||
|
||||
41. Beginning with bash-4.0, when one of the commands in a pipeline is killed
|
||||
by a SIGINT while executing a command list, the shell acts as if it
|
||||
received the interrupt. This can be disabled by setting the compat31 or
|
||||
compat32 shell options.
|
||||
|
||||
42. Bash-4.0 changes the handling of the set -e option so that the shell exits
|
||||
if a pipeline fails (and not just if the last command in the failing
|
||||
pipeline is a simple command). This is not as Posix specifies. There is
|
||||
work underway to update this portion of the standard; the bash-4.0
|
||||
behavior attempts to capture the consensus at the time of release.
|
||||
|
||||
43. Bash-4.0 fixes a Posix mode bug that caused the . (source) builtin to
|
||||
search the current directory for its filename argument, even if "." is
|
||||
not in $PATH. Posix says that the shell shouldn't look in $PWD in this
|
||||
case.
|
||||
|
||||
44. Bash-4.1 uses the current locale when comparing strings using the < and
|
||||
> operators to the `[[' command. This can be reverted to the previous
|
||||
behavior by setting one of the `compatNN' shopt options.
|
||||
|
||||
Shell Compatibility Level
|
||||
=========================
|
||||
|
||||
Bash-4.0 introduced the concept of a `shell compatibility level', specified
|
||||
as a set of options to the shopt builtin (compat31, compat32, compat40 at
|
||||
this writing). There is only one current compatibility level -- each
|
||||
option is mutually exclusive. This list does not mention behavior that is
|
||||
standard for a particular version (e.g., setting compat32 means that quoting
|
||||
the rhs of the regexp matching operator quotes special regexp characters in
|
||||
the word, which is default behavior in bash-3.2 and above).
|
||||
|
||||
compat31 set
|
||||
- the < and > operators to the [[ command do not consider the current
|
||||
locale when comparing strings
|
||||
- quoting the rhs of the regexp matching operator (=~) has no
|
||||
special effect
|
||||
|
||||
compat32 set
|
||||
- the < and > operators to the [[ command do not consider the current
|
||||
locale when comparing strings
|
||||
|
||||
compat40 set
|
||||
- the < and > operators to the [[ command do not consider the current
|
||||
locale when comparing strings
|
||||
- interrupting a command list such as "a ; b ; c" causes the execution
|
||||
of the entire list to be aborted
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. This file is offered as-is,
|
||||
without any warranty.
|
||||
@@ -9466,3 +9466,15 @@ bashline.c
|
||||
hint might contain an already-dequoted globbing character, but
|
||||
glob_matches will be NULL. Fixes bug reported by
|
||||
coyote@wariat.org.pl
|
||||
|
||||
2/5
|
||||
---
|
||||
builtins/exec.def
|
||||
- set extern variable "exec_argv0" to the argument to -a
|
||||
|
||||
shell.c
|
||||
- if exec_argv0 is set, set dollar_vars[0] to it and set it to NULL,
|
||||
assuming it was set by `exec -a'. `exec -a foo' now sets $0 to
|
||||
foo in an executable shell script without a leading `#!' (fixes
|
||||
longstanding bug)
|
||||
|
||||
|
||||
@@ -9457,3 +9457,22 @@ arrayfunc.c
|
||||
invisible. Pointed out by Mart Frauenlab <mart.frauenlob@chello.at>
|
||||
- change array_value_internal to return NULL for variable which has
|
||||
not been set
|
||||
|
||||
1/30
|
||||
----
|
||||
bashline.c
|
||||
- in command_word_completion_function, don't call glob_pattern_p
|
||||
on hint -- use the already-computed `globpat'. At this point,
|
||||
hint might contain an already-dequoted globbing character, but
|
||||
glob_matches will be NULL. Fixes bug reported by
|
||||
coyote@wariat.org.pl
|
||||
|
||||
2/5
|
||||
---
|
||||
builtins/exec.def
|
||||
- set extern variable "exec_argv0" to the argument to -a
|
||||
|
||||
shell.c
|
||||
- if exec_argv0 is set, set dollar_vars[0] to it and set it to NULL,
|
||||
assuming it was set by `exec -a'. `exec -a foo' now sets $0 to
|
||||
foo in an executable shell script without a leading `#!'
|
||||
|
||||
@@ -517,6 +517,8 @@ po/tr.gmo f
|
||||
po/tr.po f
|
||||
po/vi.gmo f
|
||||
po/vi.po f
|
||||
po/zh_CN.gmo f
|
||||
po/zh_CN.po f
|
||||
po/zh_TW.gmo f
|
||||
po/zh_TW.po f
|
||||
po/insert-header.sin f
|
||||
|
||||
+1
-1
@@ -367,7 +367,7 @@ make_builtin_argv (list, ip)
|
||||
return argv;
|
||||
}
|
||||
|
||||
/* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
|
||||
/* Remember LIST in $1 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
|
||||
non-zero, then discard whatever the existing arguments are, else
|
||||
only discard the ones that are to be replaced. */
|
||||
void
|
||||
|
||||
@@ -0,0 +1,890 @@
|
||||
/* common.c - utility functions for all builtins */
|
||||
|
||||
/* Copyright (C) 1987-2009 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/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <chartypes.h>
|
||||
#include "../bashtypes.h"
|
||||
#include "posixstat.h"
|
||||
#include <signal.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#if defined (PREFER_STDARG)
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#define NEED_FPURGE_DECL
|
||||
|
||||
#include "../shell.h"
|
||||
#include "maxpath.h"
|
||||
#include "../flags.h"
|
||||
#include "../jobs.h"
|
||||
#include "../builtins.h"
|
||||
#include "../input.h"
|
||||
#include "../execute_cmd.h"
|
||||
#include "../trap.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "common.h"
|
||||
#include "builtext.h"
|
||||
#include <tilde/tilde.h>
|
||||
|
||||
#if defined (HISTORY)
|
||||
# include "../bashhist.h"
|
||||
#endif
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern int indirection_level, subshell_environment;
|
||||
extern int line_number;
|
||||
extern int last_command_exit_value;
|
||||
extern int running_trap;
|
||||
extern int posixly_correct;
|
||||
extern char *this_command_name, *shell_name;
|
||||
extern const char * const bash_getcwd_errstr;
|
||||
|
||||
/* Used by some builtins and the mainline code. */
|
||||
sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL;
|
||||
sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Error reporting, usage, and option processing */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* This is a lot like report_error (), but it is for shell builtins
|
||||
instead of shell control structures, and it won't ever exit the
|
||||
shell. */
|
||||
|
||||
static void
|
||||
builtin_error_prolog ()
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = get_name_for_error ();
|
||||
fprintf (stderr, "%s: ", name);
|
||||
|
||||
if (interactive_shell == 0)
|
||||
fprintf (stderr, _("line %d: "), executing_line_number ());
|
||||
|
||||
if (this_command_name && *this_command_name)
|
||||
fprintf (stderr, "%s: ", this_command_name);
|
||||
}
|
||||
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
builtin_error (const char *format, ...)
|
||||
#else
|
||||
builtin_error (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
builtin_error_prolog ();
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
builtin_warning (const char *format, ...)
|
||||
#else
|
||||
builtin_warning (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
builtin_error_prolog ();
|
||||
fprintf (stderr, _("warning: "));
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
/* Print a usage summary for the currently-executing builtin command. */
|
||||
void
|
||||
builtin_usage ()
|
||||
{
|
||||
if (this_command_name && *this_command_name)
|
||||
fprintf (stderr, _("%s: usage: "), this_command_name);
|
||||
fprintf (stderr, "%s\n", current_builtin->short_doc);
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
/* Return if LIST is NULL else barf and jump to top_level. Used by some
|
||||
builtins that do not accept arguments. */
|
||||
void
|
||||
no_args (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
if (list)
|
||||
{
|
||||
builtin_error (_("too many arguments"));
|
||||
top_level_cleanup ();
|
||||
jump_to_top_level (DISCARD);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that no options were given to the currently-executing builtin,
|
||||
and return 0 if there were options. */
|
||||
int
|
||||
no_options (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
reset_internal_getopt ();
|
||||
if (internal_getopt (list, "") != -1)
|
||||
{
|
||||
builtin_usage ();
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
sh_needarg (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: option requires an argument"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_neednumarg (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: numeric argument required"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_notfound (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: not found"), s);
|
||||
}
|
||||
|
||||
/* Function called when one of the builtin commands detects an invalid
|
||||
option. */
|
||||
void
|
||||
sh_invalidopt (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: invalid option"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidoptname (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: invalid option name"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidid (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("`%s': not a valid identifier"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidnum (s)
|
||||
char *s;
|
||||
{
|
||||
char *msg;
|
||||
|
||||
if (*s == '0' && isdigit (s[1]))
|
||||
msg = _("invalid octal number");
|
||||
else if (*s == '0' && s[1] == 'x')
|
||||
msg = _("invalid hex number");
|
||||
else
|
||||
msg = _("invalid number");
|
||||
builtin_error ("%s: %s", s, msg);
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidsig (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: invalid signal specification"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_badpid (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("`%s': not a pid or valid job spec"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_readonly (s)
|
||||
const char *s;
|
||||
{
|
||||
builtin_error (_("%s: readonly variable"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_erange (s, desc)
|
||||
char *s, *desc;
|
||||
{
|
||||
if (s)
|
||||
builtin_error (_("%s: %s out of range"), s, desc ? desc : _("argument"));
|
||||
else
|
||||
builtin_error (_("%s out of range"), desc ? desc : _("argument"));
|
||||
}
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
void
|
||||
sh_badjob (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: no such job"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_nojobs (s)
|
||||
char *s;
|
||||
{
|
||||
if (s)
|
||||
builtin_error (_("%s: no job control"), s);
|
||||
else
|
||||
builtin_error (_("no job control"));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
void
|
||||
sh_restricted (s)
|
||||
char *s;
|
||||
{
|
||||
if (s)
|
||||
builtin_error (_("%s: restricted"), s);
|
||||
else
|
||||
builtin_error (_("restricted"));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sh_notbuiltin (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: not a shell builtin"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_wrerror ()
|
||||
{
|
||||
#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));
|
||||
}
|
||||
|
||||
void
|
||||
sh_ttyerror (set)
|
||||
int set;
|
||||
{
|
||||
if (set)
|
||||
builtin_error (_("error setting terminal attributes: %s"), strerror (errno));
|
||||
else
|
||||
builtin_error (_("error getting terminal attributes: %s"), strerror (errno));
|
||||
}
|
||||
|
||||
int
|
||||
sh_chkwrite (s)
|
||||
int s;
|
||||
{
|
||||
fflush (stdout);
|
||||
if (ferror (stdout))
|
||||
{
|
||||
sh_wrerror ();
|
||||
fpurge (stdout);
|
||||
clearerr (stdout);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Shell positional parameter manipulation */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Convert a WORD_LIST into a C-style argv. Return the number of elements
|
||||
in the list in *IP, if IP is non-null. A convenience function for
|
||||
loadable builtins; also used by `test'. */
|
||||
char **
|
||||
make_builtin_argv (list, ip)
|
||||
WORD_LIST *list;
|
||||
int *ip;
|
||||
{
|
||||
char **argv;
|
||||
|
||||
argv = strvec_from_word_list (list, 0, 1, ip);
|
||||
argv[0] = this_command_name;
|
||||
return argv;
|
||||
}
|
||||
|
||||
/* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
|
||||
non-zero, then discard whatever the existing arguments are, else
|
||||
only discard the ones that are to be replaced. */
|
||||
void
|
||||
remember_args (list, destructive)
|
||||
WORD_LIST *list;
|
||||
int destructive;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 1; i < 10; i++)
|
||||
{
|
||||
if ((destructive || list) && dollar_vars[i])
|
||||
{
|
||||
free (dollar_vars[i]);
|
||||
dollar_vars[i] = (char *)NULL;
|
||||
}
|
||||
|
||||
if (list)
|
||||
{
|
||||
dollar_vars[i] = savestring (list->word->word);
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* If arguments remain, assign them to REST_OF_ARGS.
|
||||
Note that copy_word_list (NULL) returns NULL, and
|
||||
that dispose_words (NULL) does nothing. */
|
||||
if (destructive || list)
|
||||
{
|
||||
dispose_words (rest_of_args);
|
||||
rest_of_args = copy_word_list (list);
|
||||
}
|
||||
|
||||
if (destructive)
|
||||
set_dollar_vars_changed ();
|
||||
}
|
||||
|
||||
static int changed_dollar_vars;
|
||||
|
||||
/* Have the dollar variables been reset to new values since we last
|
||||
checked? */
|
||||
int
|
||||
dollar_vars_changed ()
|
||||
{
|
||||
return (changed_dollar_vars);
|
||||
}
|
||||
|
||||
void
|
||||
set_dollar_vars_unchanged ()
|
||||
{
|
||||
changed_dollar_vars = 0;
|
||||
}
|
||||
|
||||
void
|
||||
set_dollar_vars_changed ()
|
||||
{
|
||||
if (variable_context)
|
||||
changed_dollar_vars |= ARGS_FUNC;
|
||||
else if (this_shell_builtin == set_builtin)
|
||||
changed_dollar_vars |= ARGS_SETBLTIN;
|
||||
else
|
||||
changed_dollar_vars |= ARGS_INVOC;
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Validating numeric input and arguments */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Read a numeric arg for this_command_name, the name of the shell builtin
|
||||
that wants it. LIST is the word list that the arg is to come from.
|
||||
Accept only the numeric argument; report an error if other arguments
|
||||
follow. If FATAL is 1, call throw_to_top_level, which exits the
|
||||
shell; if it's 2, call jump_to_top_level (DISCARD), which aborts the
|
||||
current command; if FATAL is 0, return an indication of an invalid
|
||||
number by setting *NUMOK == 0 and return -1. */
|
||||
int
|
||||
get_numeric_arg (list, fatal, count)
|
||||
WORD_LIST *list;
|
||||
int fatal;
|
||||
intmax_t *count;
|
||||
{
|
||||
char *arg;
|
||||
|
||||
if (count)
|
||||
*count = 1;
|
||||
|
||||
if (list && list->word && ISOPTION (list->word->word, '-'))
|
||||
list = list->next;
|
||||
|
||||
if (list)
|
||||
{
|
||||
arg = list->word->word;
|
||||
if (arg == 0 || (legal_number (arg, count) == 0))
|
||||
{
|
||||
sh_neednumarg (list->word->word ? list->word->word : "`'");
|
||||
if (fatal == 0)
|
||||
return 0;
|
||||
else if (fatal == 1) /* fatal == 1; abort */
|
||||
throw_to_top_level ();
|
||||
else /* fatal == 2; discard current command */
|
||||
{
|
||||
top_level_cleanup ();
|
||||
jump_to_top_level (DISCARD);
|
||||
}
|
||||
}
|
||||
no_args (list->next);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Get an eight-bit status value from LIST */
|
||||
int
|
||||
get_exitstat (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int status;
|
||||
intmax_t sval;
|
||||
char *arg;
|
||||
|
||||
if (list && list->word && ISOPTION (list->word->word, '-'))
|
||||
list = list->next;
|
||||
|
||||
if (list == 0)
|
||||
return (last_command_exit_value);
|
||||
|
||||
arg = list->word->word;
|
||||
if (arg == 0 || legal_number (arg, &sval) == 0)
|
||||
{
|
||||
sh_neednumarg (list->word->word ? list->word->word : "`'");
|
||||
return 255;
|
||||
}
|
||||
no_args (list->next);
|
||||
|
||||
status = sval & 255;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Return the octal number parsed from STRING, or -1 to indicate
|
||||
that the string contained a bad number. */
|
||||
int
|
||||
read_octal (string)
|
||||
char *string;
|
||||
{
|
||||
int result, digits;
|
||||
|
||||
result = digits = 0;
|
||||
while (*string && ISOCTAL (*string))
|
||||
{
|
||||
digits++;
|
||||
result = (result * 8) + (*string++ - '0');
|
||||
if (result > 0777)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (digits == 0 || *string)
|
||||
result = -1;
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Manipulating the current working directory */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Return a consed string which is the current working directory.
|
||||
FOR_WHOM is the name of the caller for error printing. */
|
||||
char *the_current_working_directory = (char *)NULL;
|
||||
|
||||
char *
|
||||
get_working_directory (for_whom)
|
||||
char *for_whom;
|
||||
{
|
||||
if (no_symbolic_links)
|
||||
{
|
||||
FREE (the_current_working_directory);
|
||||
the_current_working_directory = (char *)NULL;
|
||||
}
|
||||
|
||||
if (the_current_working_directory == 0)
|
||||
{
|
||||
#if defined (GETCWD_BROKEN)
|
||||
the_current_working_directory = getcwd (0, PATH_MAX);
|
||||
#else
|
||||
the_current_working_directory = getcwd (0, 0);
|
||||
#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));
|
||||
return (char *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (savestring (the_current_working_directory));
|
||||
}
|
||||
|
||||
/* Make NAME our internal idea of the current working directory. */
|
||||
void
|
||||
set_working_directory (name)
|
||||
char *name;
|
||||
{
|
||||
FREE (the_current_working_directory);
|
||||
the_current_working_directory = savestring (name);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Job control support functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
int
|
||||
get_job_by_name (name, flags)
|
||||
const char *name;
|
||||
int flags;
|
||||
{
|
||||
register int i, wl, cl, match, job;
|
||||
register PROCESS *p;
|
||||
register JOB *j;
|
||||
|
||||
job = NO_JOB;
|
||||
wl = strlen (name);
|
||||
for (i = js.j_jobslots - 1; i >= 0; i--)
|
||||
{
|
||||
j = get_job_by_jid (i);
|
||||
if (j == 0 || ((flags & JM_STOPPED) && J_JOBSTATE(j) != JSTOPPED))
|
||||
continue;
|
||||
|
||||
p = j->pipe;
|
||||
do
|
||||
{
|
||||
if (flags & JM_EXACT)
|
||||
{
|
||||
cl = strlen (p->command);
|
||||
match = STREQN (p->command, name, cl);
|
||||
}
|
||||
else if (flags & JM_SUBSTRING)
|
||||
match = strcasestr (p->command, name) != (char *)0;
|
||||
else
|
||||
match = STREQN (p->command, name, wl);
|
||||
|
||||
if (match == 0)
|
||||
{
|
||||
p = p->next;
|
||||
continue;
|
||||
}
|
||||
else if (flags & JM_FIRSTMATCH)
|
||||
return i; /* return first match */
|
||||
else if (job != NO_JOB)
|
||||
{
|
||||
if (this_shell_builtin)
|
||||
builtin_error (_("%s: ambiguous job spec"), name);
|
||||
else
|
||||
report_error (_("%s: ambiguous job spec"), name);
|
||||
return (DUP_JOB);
|
||||
}
|
||||
else
|
||||
job = i;
|
||||
}
|
||||
while (p != j->pipe);
|
||||
}
|
||||
|
||||
return (job);
|
||||
}
|
||||
|
||||
/* Return the job spec found in LIST. */
|
||||
int
|
||||
get_job_spec (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
register char *word;
|
||||
int job, jflags;
|
||||
|
||||
if (list == 0)
|
||||
return (js.j_current);
|
||||
|
||||
word = list->word->word;
|
||||
|
||||
if (*word == '\0')
|
||||
return (NO_JOB);
|
||||
|
||||
if (*word == '%')
|
||||
word++;
|
||||
|
||||
if (DIGIT (*word) && all_digits (word))
|
||||
{
|
||||
job = atoi (word);
|
||||
return (job > js.j_jobslots ? NO_JOB : job - 1);
|
||||
}
|
||||
|
||||
jflags = 0;
|
||||
switch (*word)
|
||||
{
|
||||
case 0:
|
||||
case '%':
|
||||
case '+':
|
||||
return (js.j_current);
|
||||
|
||||
case '-':
|
||||
return (js.j_previous);
|
||||
|
||||
case '?': /* Substring search requested. */
|
||||
jflags |= JM_SUBSTRING;
|
||||
word++;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
return get_job_by_name (word, jflags);
|
||||
}
|
||||
}
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
/*
|
||||
* NOTE: `kill' calls this function with forcecols == 0
|
||||
*/
|
||||
int
|
||||
display_signal_list (list, forcecols)
|
||||
WORD_LIST *list;
|
||||
int forcecols;
|
||||
{
|
||||
register int i, column;
|
||||
char *name;
|
||||
int result, signum, dflags;
|
||||
intmax_t lsignum;
|
||||
|
||||
result = EXECUTION_SUCCESS;
|
||||
if (!list)
|
||||
{
|
||||
for (i = 1, column = 0; i < NSIG; i++)
|
||||
{
|
||||
name = signal_name (i);
|
||||
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
|
||||
continue;
|
||||
|
||||
if (posixly_correct && !forcecols)
|
||||
{
|
||||
/* This is for the kill builtin. POSIX.2 says the signal names
|
||||
are displayed without the `SIG' prefix. */
|
||||
if (STREQN (name, "SIG", 3))
|
||||
name += 3;
|
||||
printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("%2d) %s", i, name);
|
||||
|
||||
if (++column < 5)
|
||||
printf ("\t");
|
||||
else
|
||||
{
|
||||
printf ("\n");
|
||||
column = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((posixly_correct && !forcecols) || column != 0)
|
||||
printf ("\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
/* List individual signal names or numbers. */
|
||||
while (list)
|
||||
{
|
||||
if (legal_number (list->word->word, &lsignum))
|
||||
{
|
||||
/* This is specified by Posix.2 so that exit statuses can be
|
||||
mapped into signal numbers. */
|
||||
if (lsignum > 128)
|
||||
lsignum -= 128;
|
||||
if (lsignum < 0 || lsignum >= NSIG)
|
||||
{
|
||||
sh_invalidsig (list->word->word);
|
||||
result = EXECUTION_FAILURE;
|
||||
list = list->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
signum = lsignum;
|
||||
name = signal_name (signum);
|
||||
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
|
||||
{
|
||||
list = list->next;
|
||||
continue;
|
||||
}
|
||||
#if defined (JOB_CONTROL)
|
||||
/* POSIX.2 says that `kill -l signum' prints the signal name without
|
||||
the `SIG' prefix. */
|
||||
printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
|
||||
#else
|
||||
printf ("%s\n", name);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
dflags = DSIG_NOCASE;
|
||||
if (posixly_correct == 0 || this_shell_builtin != kill_builtin)
|
||||
dflags |= DSIG_SIGPREFIX;
|
||||
signum = decode_signal (list->word->word, dflags);
|
||||
if (signum == NO_SIG)
|
||||
{
|
||||
sh_invalidsig (list->word->word);
|
||||
result = EXECUTION_FAILURE;
|
||||
list = list->next;
|
||||
continue;
|
||||
}
|
||||
printf ("%d\n", signum);
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Finding builtin commands and their functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Perform a binary search and return the address of the builtin function
|
||||
whose name is NAME. If the function couldn't be found, or the builtin
|
||||
is disabled or has no function associated with it, return NULL.
|
||||
Return the address of the builtin.
|
||||
DISABLED_OKAY means find it even if the builtin is disabled. */
|
||||
struct builtin *
|
||||
builtin_address_internal (name, disabled_okay)
|
||||
char *name;
|
||||
int disabled_okay;
|
||||
{
|
||||
int hi, lo, mid, j;
|
||||
|
||||
hi = num_shell_builtins - 1;
|
||||
lo = 0;
|
||||
|
||||
while (lo <= hi)
|
||||
{
|
||||
mid = (lo + hi) / 2;
|
||||
|
||||
j = shell_builtins[mid].name[0] - name[0];
|
||||
|
||||
if (j == 0)
|
||||
j = strcmp (shell_builtins[mid].name, name);
|
||||
|
||||
if (j == 0)
|
||||
{
|
||||
/* It must have a function pointer. It must be enabled, or we
|
||||
must have explicitly allowed disabled functions to be found,
|
||||
and it must not have been deleted. */
|
||||
if (shell_builtins[mid].function &&
|
||||
((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
|
||||
((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
|
||||
return (&shell_builtins[mid]);
|
||||
else
|
||||
return ((struct builtin *)NULL);
|
||||
}
|
||||
if (j > 0)
|
||||
hi = mid - 1;
|
||||
else
|
||||
lo = mid + 1;
|
||||
}
|
||||
return ((struct builtin *)NULL);
|
||||
}
|
||||
|
||||
/* Return the pointer to the function implementing builtin command NAME. */
|
||||
sh_builtin_func_t *
|
||||
find_shell_builtin (name)
|
||||
char *name;
|
||||
{
|
||||
current_builtin = builtin_address_internal (name, 0);
|
||||
return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
|
||||
}
|
||||
|
||||
/* Return the address of builtin with NAME, whether it is enabled or not. */
|
||||
sh_builtin_func_t *
|
||||
builtin_address (name)
|
||||
char *name;
|
||||
{
|
||||
current_builtin = builtin_address_internal (name, 1);
|
||||
return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
|
||||
}
|
||||
|
||||
/* Return the function implementing the builtin NAME, but only if it is a
|
||||
POSIX.2 special builtin. */
|
||||
sh_builtin_func_t *
|
||||
find_special_builtin (name)
|
||||
char *name;
|
||||
{
|
||||
current_builtin = builtin_address_internal (name, 0);
|
||||
return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
|
||||
current_builtin->function :
|
||||
(sh_builtin_func_t *)NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
shell_builtin_compare (sbp1, sbp2)
|
||||
struct builtin *sbp1, *sbp2;
|
||||
{
|
||||
int result;
|
||||
|
||||
if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
|
||||
result = strcmp (sbp1->name, sbp2->name);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Sort the table of shell builtins so that the binary search will work
|
||||
in find_shell_builtin. */
|
||||
void
|
||||
initialize_shell_builtins ()
|
||||
{
|
||||
qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
|
||||
(QSFUNC *)shell_builtin_compare);
|
||||
}
|
||||
+3
-1
@@ -76,6 +76,7 @@ extern int errno;
|
||||
|
||||
extern int subshell_environment;
|
||||
extern REDIRECT *redirection_undo_list;
|
||||
extern char *exec_argv0;
|
||||
|
||||
int no_exit_on_failed_exec;
|
||||
|
||||
@@ -102,7 +103,7 @@ exec_builtin (list)
|
||||
char *argv0, *command, **args, **env, *newname, *com2;
|
||||
|
||||
cleanenv = login = 0;
|
||||
argv0 = (char *)NULL;
|
||||
exec_argv0 = argv0 = (char *)NULL;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "cla:")) != -1)
|
||||
@@ -164,6 +165,7 @@ exec_builtin (list)
|
||||
{
|
||||
free (args[0]);
|
||||
args[0] = login ? mkdashname (argv0) : savestring (argv0);
|
||||
exec_argv0 = savestring (args[0]);
|
||||
}
|
||||
else if (login)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
This file is exec.def, from which is created exec.c.
|
||||
It implements the builtin "exec" in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 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/>.
|
||||
|
||||
$PRODUCES exec.c
|
||||
|
||||
$BUILTIN exec
|
||||
$FUNCTION exec_builtin
|
||||
$SHORT_DOC exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
|
||||
Replace the shell with the given command.
|
||||
|
||||
Execute COMMAND, replacing this shell with the specified program.
|
||||
ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified,
|
||||
any redirections take effect in the current shell.
|
||||
|
||||
Options:
|
||||
-a name pass NAME as the zeroth argument to COMMAND
|
||||
-c execute COMMAND with an empty environment
|
||||
-l place a dash in the zeroth argument to COMMAND
|
||||
|
||||
If the command cannot be executed, a non-interactive shell exits, unless
|
||||
the shell option `execfail' is set.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless COMMAND is not found or a redirection error occurs.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "../bashtypes.h"
|
||||
#include "posixstat.h"
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../execute_cmd.h"
|
||||
#include "../findcmd.h"
|
||||
#if defined (JOB_CONTROL)
|
||||
# include "../jobs.h"
|
||||
#endif
|
||||
#include "../flags.h"
|
||||
#include "../trap.h"
|
||||
#if defined (HISTORY)
|
||||
# include "../bashhist.h"
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern int subshell_environment;
|
||||
extern REDIRECT *redirection_undo_list;
|
||||
extern char *exec_argv0;
|
||||
|
||||
int no_exit_on_failed_exec;
|
||||
|
||||
/* If the user wants this to look like a login shell, then
|
||||
prepend a `-' onto NAME and return the new name. */
|
||||
static char *
|
||||
mkdashname (name)
|
||||
char *name;
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = (char *)xmalloc (2 + strlen (name));
|
||||
ret[0] = '-';
|
||||
strcpy (ret + 1, name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
exec_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int exit_value = EXECUTION_FAILURE;
|
||||
int cleanenv, login, opt;
|
||||
char *argv0, *command, **args, **env, *newname, *com2;
|
||||
|
||||
cleanenv = login = 0;
|
||||
exec_argv0 = argv0 = (char *)NULL;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "cla:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'c':
|
||||
cleanenv = 1;
|
||||
break;
|
||||
case 'l':
|
||||
login = 1;
|
||||
break;
|
||||
case 'a':
|
||||
argv0 = list_optarg;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
/* First, let the redirections remain. */
|
||||
dispose_redirects (redirection_undo_list);
|
||||
redirection_undo_list = (REDIRECT *)NULL;
|
||||
|
||||
if (list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
if (restricted)
|
||||
{
|
||||
sh_restricted ((char *)NULL);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif /* RESTRICTED_SHELL */
|
||||
|
||||
args = strvec_from_word_list (list, 1, 0, (int *)NULL);
|
||||
|
||||
/* A command with a slash anywhere in its name is not looked up in $PATH. */
|
||||
command = absolute_program (args[0]) ? args[0] : search_for_command (args[0]);
|
||||
|
||||
if (command == 0)
|
||||
{
|
||||
sh_notfound (args[0]);
|
||||
exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
|
||||
goto failed_exec;
|
||||
}
|
||||
|
||||
com2 = full_pathname (command);
|
||||
if (com2)
|
||||
{
|
||||
if (command != args[0])
|
||||
free (command);
|
||||
command = com2;
|
||||
}
|
||||
|
||||
if (argv0)
|
||||
{
|
||||
free (args[0]);
|
||||
exec_argv0 = args[0] = login ? mkdashname (argv0) : savestring (argv0);
|
||||
}
|
||||
else if (login)
|
||||
{
|
||||
newname = mkdashname (args[0]);
|
||||
free (args[0]);
|
||||
args[0] = newname;
|
||||
}
|
||||
|
||||
/* Decrement SHLVL by 1 so a new shell started here has the same value,
|
||||
preserving the appearance. After we do that, we need to change the
|
||||
exported environment to include the new value. */
|
||||
if (cleanenv == 0)
|
||||
adjust_shell_level (-1);
|
||||
|
||||
if (cleanenv)
|
||||
env = (char **)NULL;
|
||||
else
|
||||
{
|
||||
maybe_make_export_env ();
|
||||
env = export_env;
|
||||
}
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (interactive_shell && subshell_environment == 0)
|
||||
maybe_save_shell_history ();
|
||||
#endif /* HISTORY */
|
||||
|
||||
restore_original_signals ();
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
if (subshell_environment == 0)
|
||||
end_job_control ();
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
shell_execve (command, args, env);
|
||||
|
||||
/* 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 (executable_file (command) == 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot execute: %s"), command, strerror (errno));
|
||||
exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
|
||||
}
|
||||
else
|
||||
file_error (command);
|
||||
|
||||
failed_exec:
|
||||
FREE (command);
|
||||
|
||||
if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
|
||||
exit_shell (exit_value);
|
||||
|
||||
if (args)
|
||||
strvec_dispose (args);
|
||||
|
||||
initialize_traps ();
|
||||
initialize_signals (1);
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
if (interactive_shell || job_control)
|
||||
restart_job_control ();
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
return (exit_value);
|
||||
}
|
||||
@@ -1380,7 +1380,7 @@ write_documentation (stream, documentation, indentation, flags)
|
||||
{
|
||||
register int i, j;
|
||||
register char *line;
|
||||
int string_array, texinfo, base_indent, last_cpp, filename_p;
|
||||
int string_array, texinfo, base_indent, filename_p;
|
||||
|
||||
if (stream == 0)
|
||||
return;
|
||||
@@ -1407,7 +1407,7 @@ write_documentation (stream, documentation, indentation, flags)
|
||||
|
||||
base_indent = (string_array && single_longdoc_strings && filename_p == 0) ? BASE_INDENT : 0;
|
||||
|
||||
for (i = last_cpp = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
|
||||
for (i = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
|
||||
{
|
||||
/* Allow #ifdef's to be written out verbatim, but don't put them into
|
||||
separate help files. */
|
||||
@@ -1415,11 +1415,8 @@ write_documentation (stream, documentation, indentation, flags)
|
||||
{
|
||||
if (string_array && filename_p == 0 && single_longdoc_strings == 0)
|
||||
fprintf (stream, "%s\n", line);
|
||||
last_cpp = 1;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
last_cpp = 0;
|
||||
|
||||
/* prefix with N_( for gettext */
|
||||
if (string_array && single_longdoc_strings == 0)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
This is the Bash FAQ, version 4.11, for Bash version 4.1.
|
||||
This is the Bash FAQ, version 4.12, for Bash version 4.1.
|
||||
|
||||
This document contains a set of frequently-asked questions concerning
|
||||
Bash, the GNU Bourne-Again Shell. Bash is a freely-available command
|
||||
@@ -1778,7 +1778,8 @@ compat40 set
|
||||
- the < and > operators to the [[ command do not consider the current
|
||||
locale when comparing strings
|
||||
- interrupting a command list such as "a ; b ; c" causes the execution
|
||||
of the entire list to be aborted
|
||||
of the entire list to be aborted (in versions before bash-4.0,
|
||||
interrupting one command in a list caused the next to be executed)
|
||||
|
||||
Section F: Things to watch out for on certain Unix versions
|
||||
|
||||
|
||||
+5
-7
@@ -67,8 +67,10 @@ Shell and Utilities portion of the IEEE POSIX specification
|
||||
.B Bash
|
||||
can be configured to be POSIX-conformant by default.
|
||||
.SH OPTIONS
|
||||
In addition to the single-character shell options documented in the
|
||||
description of the \fBset\fR builtin command, \fBbash\fR
|
||||
All of the single-character shell options documented in the
|
||||
description of the \fBset\fR builtin command can be used as options
|
||||
when the shell is invoked.
|
||||
In addition, \fBbash\fR
|
||||
interprets the following options when it is invoked:
|
||||
.PP
|
||||
.PD 0
|
||||
@@ -161,10 +163,6 @@ Turns on extended debugging mode (see the description of the
|
||||
.B extdebug
|
||||
option to the
|
||||
.B shopt
|
||||
builtin below)
|
||||
and shell function tracing (see the description of the
|
||||
\fB\-o functrace\fP option to the
|
||||
.B set
|
||||
builtin below).
|
||||
.TP
|
||||
.B \-\-dump\-po\-strings
|
||||
@@ -6057,7 +6055,7 @@ exit status of 124. If a shell function returns 124, and changes
|
||||
the compspec associated with the command on which completion is being
|
||||
attempted (supplied as the first argument when the function is executed),
|
||||
programmable completion restarts from the beginning, with an
|
||||
attempt to find a compspec for that command. This allows a set of
|
||||
attempt to find a new compspec for that command. This allows a set of
|
||||
completions to be built dynamically as completion is attempted, rather than
|
||||
being loaded all at once.
|
||||
.PP
|
||||
|
||||
+102
-61
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet@po.cwru.edu
|
||||
.\"
|
||||
.\" Last Change: Tue Dec 29 15:36:16 EST 2009
|
||||
.\" Last Change: Fri Jan 15 10:50:42 EST 2010
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2009 December 29" "GNU Bash-4.1"
|
||||
.TH BASH 1 "2010 January 15" "GNU Bash-4.1"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -67,8 +67,10 @@ Shell and Utilities portion of the IEEE POSIX specification
|
||||
.B Bash
|
||||
can be configured to be POSIX-conformant by default.
|
||||
.SH OPTIONS
|
||||
In addition to the single-character shell options documented in the
|
||||
description of the \fBset\fR builtin command, \fBbash\fR
|
||||
All of the single-character shell options documented in the
|
||||
description of the \fBset\fR builtin command can be used as options
|
||||
when the shell is invoked.
|
||||
In addition, \fBbash\fR
|
||||
interprets the following options when it is invoked:
|
||||
.PP
|
||||
.PD 0
|
||||
@@ -161,10 +163,6 @@ Turns on extended debugging mode (see the description of the
|
||||
.B extdebug
|
||||
option to the
|
||||
.B shopt
|
||||
builtin below)
|
||||
and shell function tracing (see the description of the
|
||||
\fB\-o functrace\fP option to the
|
||||
.B set
|
||||
builtin below).
|
||||
.TP
|
||||
.B \-\-dump\-po\-strings
|
||||
@@ -1358,7 +1356,7 @@ that do not require \fBbash\fP to be re-initialized.
|
||||
.TP
|
||||
.B BASH_ALIASES
|
||||
An associative array variable whose members correspond to the internal
|
||||
list of aliases as maintained by the \fBalias\fP builtin
|
||||
list of aliases as maintained by the \fBalias\fP builtin.
|
||||
Elements added to this array appear in the alias list; unsetting array
|
||||
elements cause aliases to be removed from the alias list.
|
||||
.TP
|
||||
@@ -1544,6 +1542,11 @@ This variable is available only in shell functions invoked by the
|
||||
programmable completion facilities (see \fBProgrammable Completion\fP
|
||||
below).
|
||||
.TP
|
||||
.B COPROC
|
||||
An array variable (see \fBArrays\fP below) created to hold the file descriptors
|
||||
for output from and input to an unnamed coprocess (see \fBCoprocesses\fP
|
||||
above).
|
||||
.TP
|
||||
.B DIRSTACK
|
||||
An array variable (see
|
||||
.B Arrays
|
||||
@@ -1638,6 +1641,10 @@ type on which
|
||||
is executing, in the standard GNU \fIcpu-company-system\fP format.
|
||||
The default is system-dependent.
|
||||
.TP
|
||||
.B MAPFILE
|
||||
An array variable (see \fBArrays\fP below) created to hold the text
|
||||
read by the \fBmapfile\fP builtin when no variable name is supplied.
|
||||
.TP
|
||||
.B OLDPWD
|
||||
The previous working directory as set by the
|
||||
.B cd
|
||||
@@ -1694,6 +1701,28 @@ If
|
||||
is unset, it loses its special properties, even if it is
|
||||
subsequently reset.
|
||||
.TP
|
||||
.B READLINE_LINE
|
||||
The contents of the
|
||||
.B readline
|
||||
line buffer, for use with
|
||||
.if t \f(CWbind -x\fP
|
||||
.if n "bind -x"
|
||||
(see
|
||||
.SM
|
||||
.B "SHELL BUILTIN COMMANDS"
|
||||
below).
|
||||
.TP
|
||||
.B READLINE_POINT
|
||||
The position of the insertion point in the
|
||||
.B readline
|
||||
line buffer, for use with
|
||||
.if t \f(CWbind -x\fP
|
||||
.if n "bind -x"
|
||||
(see
|
||||
.SM
|
||||
.B "SHELL BUILTIN COMMANDS"
|
||||
below).
|
||||
.TP
|
||||
.B REPLY
|
||||
Set to the line of input read by the
|
||||
.B read
|
||||
@@ -1766,18 +1795,6 @@ expansion before being interpreted as a file name.
|
||||
.B PATH
|
||||
is not used to search for the resultant file name.
|
||||
.TP
|
||||
.B CDPATH
|
||||
The search path for the
|
||||
.B cd
|
||||
command.
|
||||
This is a colon-separated list of directories in which the shell looks
|
||||
for destination directories specified by the
|
||||
.B cd
|
||||
command.
|
||||
A sample value is
|
||||
.if t \f(CW".:~:/usr"\fP.
|
||||
.if n ".:~:/usr".
|
||||
.TP
|
||||
.B BASH_XTRACEFD
|
||||
If set to an integer corresponding to a valid file descriptor, \fBbash\fP
|
||||
will write the trace output generated when
|
||||
@@ -1800,9 +1817,23 @@ to 2 (the standard error file
|
||||
descriptor) and then unsetting it will result in the standard error
|
||||
being closed.
|
||||
.TP
|
||||
.B CDPATH
|
||||
The search path for the
|
||||
.B cd
|
||||
command.
|
||||
This is a colon-separated list of directories in which the shell looks
|
||||
for destination directories specified by the
|
||||
.B cd
|
||||
command.
|
||||
A sample value is
|
||||
.if t \f(CW".:~:/usr"\fP.
|
||||
.if n ".:~:/usr".
|
||||
.TP
|
||||
.B COLUMNS
|
||||
Used by the \fBselect\fP builtin command to determine the terminal width
|
||||
when printing selection lists. Automatically set upon receipt of a SIGWINCH.
|
||||
when printing selection lists. Automatically set upon receipt of a
|
||||
.SM
|
||||
.BR SIGWINCH .
|
||||
.TP
|
||||
.B COMPREPLY
|
||||
An array variable from which \fBbash\fP reads the possible completions
|
||||
@@ -1817,6 +1848,12 @@ with value
|
||||
it assumes that the shell is running in an emacs shell buffer and disables
|
||||
line editing.
|
||||
.TP
|
||||
.B ENV
|
||||
Similar to
|
||||
.SM
|
||||
.BR BASH_ENV ;
|
||||
used when the shell is invoked in POSIX mode.
|
||||
.TP
|
||||
.B FCEDIT
|
||||
The default editor for the
|
||||
.B fc
|
||||
@@ -2842,7 +2879,7 @@ to uppercase; the \fB,\fP operator converts matching uppercase letters
|
||||
to lowercase.
|
||||
The \fB^^\fP and \fB,,\fP expansions convert each matched character in the
|
||||
expanded value; the \fB^\fP and \fB,\fP expansions match and convert only
|
||||
the first character in the expanded value..
|
||||
the first character in the expanded value.
|
||||
If \fIpattern\fP is omitted, it is treated like a \fB?\fP, which matches
|
||||
every character.
|
||||
If
|
||||
@@ -3948,20 +3985,24 @@ True if \fIfile\fP exists and is writable.
|
||||
.B \-x \fIfile\fP
|
||||
True if \fIfile\fP exists and is executable.
|
||||
.TP
|
||||
.B \-O \fIfile\fP
|
||||
True if \fIfile\fP exists and is owned by the effective user id.
|
||||
.TP
|
||||
.B \-G \fIfile\fP
|
||||
True if \fIfile\fP exists and is owned by the effective group id.
|
||||
.TP
|
||||
.B \-L \fIfile\fP
|
||||
True if \fIfile\fP exists and is a symbolic link.
|
||||
.TP
|
||||
.B \-N \fIfile\fP
|
||||
True if \fIfile\fP exists and has been modified since it was last read.
|
||||
.TP
|
||||
.B \-O \fIfile\fP
|
||||
True if \fIfile\fP exists and is owned by the effective user id.
|
||||
.TP
|
||||
.B \-S \fIfile\fP
|
||||
True if \fIfile\fP exists and is a socket.
|
||||
.TP
|
||||
.B \-N \fIfile\fP
|
||||
True if \fIfile\fP exists and has been modified since it was last read.
|
||||
\fIfile1\fP \fB\-ef\fP \fIfile2\fP
|
||||
True if \fIfile1\fP and \fIfile2\fP refer to the same device and
|
||||
inode numbers.
|
||||
.TP
|
||||
\fIfile1\fP \-\fBnt\fP \fIfile2\fP
|
||||
True if \fIfile1\fP is newer (according to modification date) than \fIfile2\fP,
|
||||
@@ -3971,10 +4012,6 @@ or if \fIfile1\fP exists and \fPfile2\fP does not.
|
||||
True if \fIfile1\fP is older than \fIfile2\fP, or if \fIfile2\fP exists
|
||||
and \fIfile1\fP does not.
|
||||
.TP
|
||||
\fIfile1\fP \fB\-ef\fP \fIfile2\fP
|
||||
True if \fIfile1\fP and \fIfile2\fP refer to the same device and
|
||||
inode numbers.
|
||||
.TP
|
||||
.B \-o \fIoptname\fP
|
||||
True if shell option
|
||||
.I optname
|
||||
@@ -6655,7 +6692,7 @@ is not a shell builtin command.
|
||||
.TP
|
||||
\fBcaller\fP [\fIexpr\fP]
|
||||
Returns the context of any active subroutine call (a shell function or
|
||||
a script executed with the \fB.\fP or \fBsource\fP builtins.
|
||||
a script executed with the \fB.\fP or \fBsource\fP builtins).
|
||||
Without \fIexpr\fP, \fBcaller\fP displays the line number and source
|
||||
filename of the current subroutine call.
|
||||
If a non-negative integer is supplied as \fIexpr\fP, \fBcaller\fP
|
||||
@@ -6926,18 +6963,6 @@ User names. May also be specified as \fB\-u\fP.
|
||||
Names of all shell variables. May also be specified as \fB\-v\fP.
|
||||
.RE
|
||||
.TP 8
|
||||
\fB\-G\fP \fIglobpat\fP
|
||||
The pathname expansion pattern \fIglobpat\fP is expanded to generate
|
||||
the possible completions.
|
||||
.TP 8
|
||||
\fB\-W\fP \fIwordlist\fP
|
||||
The \fIwordlist\fP is split using the characters in the
|
||||
.SM
|
||||
.B IFS
|
||||
special variable as delimiters, and each resultant word is expanded.
|
||||
The possible completions are the members of the resultant list which
|
||||
match the word being completed.
|
||||
.TP 8
|
||||
\fB\-C\fP \fIcommand\fP
|
||||
\fIcommand\fP is executed in a subshell environment, and its output is
|
||||
used as the possible completions.
|
||||
@@ -6951,13 +6976,9 @@ of the
|
||||
.B COMPREPLY
|
||||
array variable.
|
||||
.TP 8
|
||||
\fB\-X\fP \fIfilterpat\fP
|
||||
\fIfilterpat\fP is a pattern as used for pathname expansion.
|
||||
It is applied to the list of possible completions generated by the
|
||||
preceding options and arguments, and each completion matching
|
||||
\fIfilterpat\fP is removed from the list.
|
||||
A leading \fB!\fP in \fIfilterpat\fP negates the pattern; in this
|
||||
case, any completion not matching \fIfilterpat\fP is removed.
|
||||
\fB\-G\fP \fIglobpat\fP
|
||||
The pathname expansion pattern \fIglobpat\fP is expanded to generate
|
||||
the possible completions.
|
||||
.TP 8
|
||||
\fB\-P\fP \fIprefix\fP
|
||||
\fIprefix\fP is added at the beginning of each possible completion
|
||||
@@ -6966,6 +6987,22 @@ after all other options have been applied.
|
||||
\fB\-S\fP \fIsuffix\fP
|
||||
\fIsuffix\fP is appended to each possible completion
|
||||
after all other options have been applied.
|
||||
.TP 8
|
||||
\fB\-W\fP \fIwordlist\fP
|
||||
The \fIwordlist\fP is split using the characters in the
|
||||
.SM
|
||||
.B IFS
|
||||
special variable as delimiters, and each resultant word is expanded.
|
||||
The possible completions are the members of the resultant list which
|
||||
match the word being completed.
|
||||
.TP 8
|
||||
\fB\-X\fP \fIfilterpat\fP
|
||||
\fIfilterpat\fP is a pattern as used for pathname expansion.
|
||||
It is applied to the list of possible completions generated by the
|
||||
preceding options and arguments, and each completion matching
|
||||
\fIfilterpat\fP is removed from the list.
|
||||
A leading \fB!\fP in \fIfilterpat\fP negates the pattern; in this
|
||||
case, any completion not matching \fIfilterpat\fP is removed.
|
||||
.PD
|
||||
.PP
|
||||
The return value is true unless an invalid option is supplied, an option
|
||||
@@ -6978,7 +7015,7 @@ an error occurs adding a completion specification.
|
||||
\fBcompopt\fP [\fB\-o\fP \fIoption\fP] [\fB\-DE\fP] [\fB+o\fP \fIoption\fP] [\fIname\fP]
|
||||
Modify completion options for each \fIname\fP according to the
|
||||
\fIoption\fPs, or for the
|
||||
currently-executing100 completion if no \fIname\fPs are supplied.
|
||||
currently-executing completion if no \fIname\fPs are supplied.
|
||||
If no \fIoption\fPs are given, display the completion options for each
|
||||
\fIname\fP or the current completion.
|
||||
The possible values of \fIoption\fP are those valid for the \fBcomplete\fP
|
||||
@@ -7119,7 +7156,7 @@ an attempt is made to turn off array status for an array variable,
|
||||
or an attempt is made to display a non-existent function with \fB\-f\fP.
|
||||
.RE
|
||||
.TP
|
||||
.B dirs [+\fIn\fP] [\-\fIn\fP] [\fB\-cplv\fP]
|
||||
.B dirs [+\fIn\fP] [\-\fIn\fP] [\fB\-clpv\fP]
|
||||
Without options, displays the list of currently remembered directories.
|
||||
The default display is on a single line with directory names separated
|
||||
by spaces.
|
||||
@@ -7768,14 +7805,14 @@ meanings:
|
||||
List process IDs
|
||||
in addition to the normal information.
|
||||
.TP
|
||||
.B \-p
|
||||
List only the process ID of the job's process group
|
||||
leader.
|
||||
.TP
|
||||
.B \-n
|
||||
Display information only about jobs that have changed status since
|
||||
the user was last notified of their status.
|
||||
.TP
|
||||
.B \-p
|
||||
List only the process ID of the job's process group
|
||||
leader.
|
||||
.TP
|
||||
.B \-r
|
||||
Restrict output to running jobs.
|
||||
.TP
|
||||
@@ -8827,7 +8864,7 @@ subshells invoked with \fB(\fP \fIcommand\fP \fB)\fP inherit the
|
||||
.B 6.
|
||||
Error tracing is enabled: command substitution, shell functions, and
|
||||
subshells invoked with \fB(\fP \fIcommand\fP \fB)\fP inherit the
|
||||
\fBERROR\fP trap.
|
||||
\fBERR\fP trap.
|
||||
.RE
|
||||
.TP 8
|
||||
.B extglob
|
||||
@@ -9157,7 +9194,10 @@ Each
|
||||
.I sigspec
|
||||
is either
|
||||
a signal name defined in <\fIsignal.h\fP>, or a signal number.
|
||||
Signal names are case insensitive and the SIG prefix is optional.
|
||||
Signal names are case insensitive and the
|
||||
.SM
|
||||
.B SIG
|
||||
prefix is optional.
|
||||
.if t .sp 0.5
|
||||
.if n .sp 1
|
||||
If a
|
||||
@@ -9387,7 +9427,8 @@ The maximum amount of cpu time in seconds
|
||||
The maximum number of processes available to a single user
|
||||
.TP
|
||||
.B \-v
|
||||
The maximum amount of virtual memory available to the shell
|
||||
The maximum amount of virtual memory available to the shell and, on
|
||||
some systems, to its children
|
||||
.TP
|
||||
.B \-x
|
||||
The maximum number of file locks
|
||||
|
||||
+4
-5
@@ -5316,8 +5316,9 @@ bash [long-opt] [-abefhkmnptuvxdBCDHP] [-o @var{option}] [-O @var{shopt_option}]
|
||||
bash [long-opt] -s [-abefhkmnptuvxdBCDHP] [-o @var{option}] [-O @var{shopt_option}] [@var{argument} @dots{}]
|
||||
@end example
|
||||
|
||||
In addition to the single-character shell command-line options
|
||||
(@pxref{The Set Builtin}), there are several multi-character
|
||||
All of the single-character options used with the @code{set} builtin
|
||||
(@pxref{The Set Builtin}) can be used as options when the shell is invoked.
|
||||
In addition, there are several multi-character
|
||||
options that you can use. These options must appear on the command
|
||||
line before the single-character options to be recognized.
|
||||
|
||||
@@ -5326,9 +5327,7 @@ line before the single-character options to be recognized.
|
||||
Arrange for the debugger profile to be executed before the shell
|
||||
starts. Turns on extended debugging mode (see @ref{The Shopt Builtin}
|
||||
for a description of the @code{extdebug} option to the @code{shopt}
|
||||
builtin) and shell function tracing
|
||||
(see @ref{The Set Builtin} for a description of the @code{-o functrace}
|
||||
option).
|
||||
builtin).
|
||||
|
||||
@item --dump-po-strings
|
||||
A list of all double-quoted strings preceded by @samp{$}
|
||||
|
||||
+7963
File diff suppressed because it is too large
Load Diff
+2
-5
@@ -2166,7 +2166,6 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
||||
int asynchronous, pipe_in, pipe_out;
|
||||
struct fd_bitmap *fds_to_close;
|
||||
{
|
||||
REDIRECT *rp;
|
||||
COMMAND *tc, *second;
|
||||
int ignore_return, exec_result, was_error_trap, invert;
|
||||
volatile int save_line_number;
|
||||
@@ -2181,8 +2180,6 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
||||
if (tc == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
rp = tc->redirects;
|
||||
|
||||
if (ignore_return)
|
||||
tc->flags |= CMD_IGNORE_RETURN;
|
||||
tc->flags |= CMD_AMPERSAND;
|
||||
@@ -2719,8 +2716,10 @@ select_query (list, list_len, prompt, print_menu)
|
||||
WORD_LIST *l;
|
||||
char *repl_string, *t;
|
||||
|
||||
#if 0
|
||||
t = get_string_value ("LINES");
|
||||
LINES = (t && *t) ? atoi (t) : 24;
|
||||
#endif
|
||||
t = get_string_value ("COLUMNS");
|
||||
COLS = (t && *t) ? atoi (t) : 80;
|
||||
|
||||
@@ -4343,7 +4342,6 @@ execute_builtin_or_function (words, builtin, var, redirects,
|
||||
{
|
||||
int result;
|
||||
REDIRECT *saved_undo_list;
|
||||
sh_builtin_func_t *saved_this_shell_builtin;
|
||||
|
||||
if (do_redirections (redirects, RX_ACTIVE|RX_UNDOABLE) != 0)
|
||||
{
|
||||
@@ -4353,7 +4351,6 @@ execute_builtin_or_function (words, builtin, var, redirects,
|
||||
return (EX_REDIRFAIL); /* was EXECUTION_FAILURE */
|
||||
}
|
||||
|
||||
saved_this_shell_builtin = this_shell_builtin;
|
||||
saved_undo_list = redirection_undo_list;
|
||||
|
||||
/* Calling the "exec" builtin changes redirections forever. */
|
||||
|
||||
+5008
File diff suppressed because it is too large
Load Diff
@@ -2351,7 +2351,6 @@ wait_for (pid)
|
||||
WAIT s;
|
||||
register PROCESS *child;
|
||||
sigset_t set, oset;
|
||||
register PROCESS *p;
|
||||
|
||||
/* In the case that this code is interrupted, and we longjmp () out of it,
|
||||
we are relying on the code in throw_to_top_level () to restore the
|
||||
|
||||
@@ -77,6 +77,10 @@
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
#if !defined (HAVE_KILLPG)
|
||||
extern int killpg __P((pid_t, int));
|
||||
#endif
|
||||
|
||||
#define DEFAULT_CHILD_MAX 32
|
||||
#if !defined (DEBUG)
|
||||
#define MAX_JOBS_IN_ARRAY 4096 /* production */
|
||||
|
||||
@@ -1733,7 +1733,7 @@ exit status of 124. If a shell function returns 124, and changes
|
||||
the compspec associated with the command on which completion is being
|
||||
attempted (supplied as the first argument when the function is executed),
|
||||
programmable completion restarts from the beginning, with an
|
||||
attempt to find a compspec for that command. This allows a set of
|
||||
attempt to find a new compspec for that command. This allows a set of
|
||||
completions to be built dynamically as completion is attempted, rather than
|
||||
being loaded all at once.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1957,6 +1957,7 @@ read_a_line (remove_quoted_newline)
|
||||
}
|
||||
else if (c == '\\' && remove_quoted_newline)
|
||||
{
|
||||
QUIT;
|
||||
peekc = yy_getc ();
|
||||
if (peekc == '\n')
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
# Set of available languages.
|
||||
en@quot en@boldquot af bg ca cs de eo es et fi fr ga hu id ja lt nl pl pt_BR ro ru sk sv tr vi zh_TW
|
||||
en@quot en@boldquot af bg ca cs de eo es et fi fr ga hu id ja lt nl pl pt_BR ro ru sk sv tr vi zh_CN zh_TW
|
||||
|
||||
+3814
File diff suppressed because it is too large
Load Diff
+2
-3
@@ -155,7 +155,7 @@ static void
|
||||
make_command_string_internal (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
char s[3], *op;
|
||||
char s[3];
|
||||
|
||||
if (command == 0)
|
||||
cprintf ("");
|
||||
@@ -1052,10 +1052,9 @@ static void
|
||||
print_redirection (redirect)
|
||||
REDIRECT *redirect;
|
||||
{
|
||||
int kill_leading, redirector, redir_fd;
|
||||
int redirector, redir_fd;
|
||||
WORD_DESC *redirectee, *redir_word;
|
||||
|
||||
kill_leading = 0;
|
||||
redirectee = redirect->redirectee.filename;
|
||||
redir_fd = redirect->redirectee.dest;
|
||||
|
||||
|
||||
@@ -1121,6 +1121,9 @@ print_redirection (redirect)
|
||||
else if (redirector != 0)
|
||||
cprintf ("%d", redirector);
|
||||
#if 0
|
||||
/* Don't need to check whether or not to requote, since original quotes
|
||||
are still intact. The only thing that has happened is that $'...'
|
||||
has been replaced with 'expanded ...'. */
|
||||
if (ansic_shouldquote (redirect->redirectee.filename->word))
|
||||
{
|
||||
char *x;
|
||||
|
||||
@@ -226,7 +226,6 @@ int posixly_correct = 1; /* Non-zero means posix.2 superset. */
|
||||
int posixly_correct = 0; /* Non-zero means posix.2 superset. */
|
||||
#endif
|
||||
|
||||
|
||||
/* Some long-winded argument names. These are obviously new. */
|
||||
#define Int 1
|
||||
#define Charp 2
|
||||
@@ -271,6 +270,8 @@ int subshell_argc;
|
||||
char **subshell_argv;
|
||||
char **subshell_envp;
|
||||
|
||||
char *exec_argv0;
|
||||
|
||||
#if defined (BUFFERED_INPUT)
|
||||
/* The file descriptor from which the shell is reading input. */
|
||||
int default_buffered_input = -1;
|
||||
@@ -1415,7 +1416,12 @@ open_shell_script (script_name)
|
||||
}
|
||||
|
||||
free (dollar_vars[0]);
|
||||
dollar_vars[0] = savestring (script_name);
|
||||
dollar_vars[0] = exec_argv0 ? savestring (exec_argv0) : savestring (script_name);
|
||||
if (exec_argv0)
|
||||
{
|
||||
free (exec_argv0);
|
||||
exec_argv0 = (char *)NULL;
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
|
||||
@@ -1719,8 +1725,9 @@ shell_initialize ()
|
||||
initialize_flags ();
|
||||
|
||||
/* Initialize the shell options. Don't import the shell options
|
||||
from the environment variable $SHELLOPTS if we are running in
|
||||
privileged or restricted mode or if the shell is running setuid. */
|
||||
from the environment variables $SHELLOPTS or $BASHOPTS if we are
|
||||
running in privileged or restricted mode or if the shell is running
|
||||
setuid. */
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
initialize_shell_options (privileged_mode||restricted||running_setuid);
|
||||
initialize_bashopts (privileged_mode||restricted||running_setuid);
|
||||
|
||||
@@ -1270,7 +1270,7 @@ extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
|
||||
if ((flags & SX_COMMAND) && string[i] == '$' && string[i+1] == LPAREN)
|
||||
{
|
||||
si = i + 2;
|
||||
t = extract_command_subst (string, &si, flags);
|
||||
t = extract_command_subst (string, &si, flags|SX_NOALLOC);
|
||||
i = si + 1;
|
||||
continue;
|
||||
}
|
||||
@@ -2661,8 +2661,8 @@ do_assignment_internal (word, expand)
|
||||
const WORD_DESC *word;
|
||||
int expand;
|
||||
{
|
||||
int offset, tlen, appendop, assign_list, aflags, retval;
|
||||
char *name, *value;
|
||||
int offset, appendop, assign_list, aflags, retval;
|
||||
char *name, *value, *temp;
|
||||
SHELL_VAR *entry;
|
||||
#if defined (ARRAY_VARS)
|
||||
char *t;
|
||||
@@ -2681,8 +2681,6 @@ do_assignment_internal (word, expand)
|
||||
|
||||
if (name[offset] == '=')
|
||||
{
|
||||
char *temp;
|
||||
|
||||
if (name[offset - 1] == '+')
|
||||
{
|
||||
appendop = 1;
|
||||
@@ -2691,7 +2689,6 @@ do_assignment_internal (word, expand)
|
||||
|
||||
name[offset] = 0; /* might need this set later */
|
||||
temp = name + offset + 1;
|
||||
tlen = STRLEN (temp);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (expand && (word->flags & W_COMPASSIGN))
|
||||
|
||||
@@ -5276,7 +5276,7 @@ array_length_reference (s)
|
||||
else if (array_p (var))
|
||||
return (array ? array_num_elements (array) : 0);
|
||||
else
|
||||
return (value_cell (var) ? 1 : 0);
|
||||
return (var_isset (var) ? 1 : 0);
|
||||
}
|
||||
|
||||
if (assoc_p (var))
|
||||
|
||||
+1
-2
@@ -158,7 +158,6 @@ static int export_env_size;
|
||||
|
||||
#if defined (READLINE)
|
||||
static int winsize_assignment; /* currently assigning to LINES or COLUMNS */
|
||||
static int winsize_assigned; /* assigned to LINES or COLUMNS */
|
||||
#endif
|
||||
|
||||
/* Some forward declarations. */
|
||||
@@ -4342,7 +4341,7 @@ sv_winsize (name)
|
||||
{
|
||||
if (legal_number (value_cell (v), &xd) == 0)
|
||||
return;
|
||||
winsize_assignment = winsize_assigned = 1;
|
||||
winsize_assignment = 1;
|
||||
d = xd; /* truncate */
|
||||
if (name[0] == 'L') /* LINES */
|
||||
rl_set_screen_size (d, -1);
|
||||
|
||||
@@ -1309,7 +1309,6 @@ get_random (var)
|
||||
|
||||
rv = get_random_number ();
|
||||
last_random_value = rv;
|
||||
fprintf(stderr, "get_random: rv = %d\n", rv);
|
||||
p = itos (rv);
|
||||
|
||||
FREE (value_cell (var));
|
||||
|
||||
Reference in New Issue
Block a user