mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-26 23:33:08 +02:00
commit bash-20190920 snapshot
This commit is contained in:
@@ -6560,3 +6560,77 @@ m4/intl.m4
|
||||
- gt_INTL_SUBDIR_CORE: add back check for localeconv, removed in
|
||||
newer gettext releases
|
||||
|
||||
9/16
|
||||
----
|
||||
builtins/help.def
|
||||
- help_builtin: make the closing quote printed after the argument list
|
||||
for a glob pattern argument a translatable string to ease translation
|
||||
for certain languages. Report from Roland Illig <roland.illig@gmx.de>
|
||||
|
||||
builtins/{reserved,complete,exec,getopts}.def
|
||||
- minor typographical fixes from Roland Illig <roland.illig@gmx.de>
|
||||
|
||||
siglist.c
|
||||
- include general.h for INT_STRLEN_BOUND
|
||||
- initialize_siglist: use the same string for the strlen and xmalloc
|
||||
for the message about an unknown signal number; use INT_STRLEN_BOUND
|
||||
instead of a fixed 10 for the number
|
||||
|
||||
builtins/getopts.def,doc/{bash.1,bashref.texi}
|
||||
- getopts: minor changes to the description of the effect of supplying
|
||||
additional arguments. Report from Roland Illig <roland.illig@gmx.de>
|
||||
|
||||
9/17
|
||||
----
|
||||
jobs.[ch]
|
||||
- save_proc_status: external interface to bgp_add, takes care of
|
||||
blocking and unblocking SIGCHLD
|
||||
- __P -> PARAMS
|
||||
|
||||
9/18
|
||||
----
|
||||
jobs.[ch]
|
||||
- procsub_{free,add,search,delete,waitpid,waitall,clear,prune}: new
|
||||
functions to keep track of the list of active process substitutions
|
||||
and their statuses. Implementation is currently a singly-linked list
|
||||
of PROCESS *, so functions that expect a PROCESS * to manipulate
|
||||
continue to work. Inspired by report from leo.dalecki@ntymail.com
|
||||
- find_pipeline,cleanup_dead_jobs,wait_for_background_pids: call new
|
||||
procsub_* functions to manage procsub list; don't call the functions
|
||||
in subst.c any more
|
||||
|
||||
subst.c
|
||||
- process_substitute: call procsub_add with the PROCESS * returned
|
||||
from make_child; let the functions in jobs.c manage the list.
|
||||
waitchld continues to set the pid field in the fifo list as a hint
|
||||
that a particular fd or FIFO is no longer used and can be reaped
|
||||
- process_substitute: let the child process clear out any existing
|
||||
procsub pid list
|
||||
- wait_procsubs: no longer compiled in
|
||||
|
||||
sig.c
|
||||
- termsig_handler: replace discard_last_procsub_child with call to
|
||||
procsub_clear
|
||||
|
||||
lib/readline/display.c
|
||||
- init_line_structures: fix a problem which results in references to
|
||||
uninitialized memory when gdb sets the number of columns to 32767
|
||||
(their `unlimited'). Modification of change from 5/23. Report and
|
||||
fix from Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
9/19
|
||||
----
|
||||
parse.y
|
||||
- xparse_dolparen: after calling parse_string to consume input, make
|
||||
sure to reset the parser (reset_parser()) before restoring the EOF
|
||||
token and the parser_state variable. Fixes issue with nested traps
|
||||
running command substitutions in command lines with command
|
||||
substitutions reported by Travis Everett <travis.a.everett@gmail.com>
|
||||
|
||||
9/20
|
||||
----
|
||||
doc/{bashref.texi,bash.1}
|
||||
- fixed a typo in the example for the =~ operator: the ? should follow
|
||||
the (a), not precede it. Report from hk <hkadeveloper@gmail.com>
|
||||
- some changes to the text describing regular expression matching for
|
||||
the =~ operator
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@ This file is caller.def, from which is created caller.c. It implements the
|
||||
builtin "caller" in Bash.
|
||||
|
||||
Copyright (C) 2002-2008 Rocky Bernstein for Free Software Foundation, Inc.
|
||||
Copyright (C) 2008-2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 2008-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -135,8 +135,8 @@ caller_builtin (list)
|
||||
static char *caller_doc[] = {
|
||||
N_("Returns the context of the current subroutine call.\n\
|
||||
\n\
|
||||
Without EXPR, returns "$line $filename". With EXPR, returns\n\
|
||||
"$line $subroutine $filename"; this extra information can be used to\n\
|
||||
Without EXPR, returns \"$line $filename\". With EXPR, returns\n\
|
||||
\"$line $subroutine $filename\"; this extra information can be used to\n\
|
||||
provide a stack trace.\n\
|
||||
\n\
|
||||
The value of EXPR indicates how many call frames to go back before the\n\
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
This file is complete.def, from which is created complete.c.
|
||||
It implements the builtins "complete", "compgen", and "compopt" in Bash.
|
||||
|
||||
Copyright (C) 1999-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -23,7 +23,7 @@ $PRODUCES complete.c
|
||||
$BUILTIN complete
|
||||
$DEPENDS_ON PROGRAMMABLE_COMPLETION
|
||||
$FUNCTION complete_builtin
|
||||
$SHORT_DOC complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
|
||||
$SHORT_DOC complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
|
||||
Specify how arguments are to be completed by Readline.
|
||||
|
||||
For each NAME, specify how arguments are to be completed. If no options
|
||||
@@ -694,7 +694,7 @@ print_cmd_completions (list)
|
||||
$BUILTIN compgen
|
||||
$DEPENDS_ON PROGRAMMABLE_COMPLETION
|
||||
$FUNCTION compgen_builtin
|
||||
$SHORT_DOC compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
|
||||
$SHORT_DOC compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
|
||||
Display possible completions depending on the options.
|
||||
|
||||
Intended to be used from within a shell function generating possible
|
||||
|
||||
+2
-2
@@ -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-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -22,7 +22,7 @@ $PRODUCES exec.c
|
||||
|
||||
$BUILTIN exec
|
||||
$FUNCTION exec_builtin
|
||||
$SHORT_DOC exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
|
||||
$SHORT_DOC exec [-cl] [-a name] [command [argument ...]] [redirection ...]
|
||||
Replace the shell with the given command.
|
||||
|
||||
Execute COMMAND, replacing this shell with the specified program.
|
||||
|
||||
@@ -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-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -22,7 +22,7 @@ $PRODUCES getopts.c
|
||||
|
||||
$BUILTIN getopts
|
||||
$FUNCTION getopts_builtin
|
||||
$SHORT_DOC getopts optstring name [arg]
|
||||
$SHORT_DOC getopts optstring name [arg ...]
|
||||
Parse option arguments.
|
||||
|
||||
Getopts is used by shell procedures to parse positional parameters
|
||||
@@ -54,8 +54,8 @@ If the shell variable OPTERR has the value 0, getopts disables the
|
||||
printing of error messages, even if the first character of
|
||||
OPTSTRING is not a colon. OPTERR has the value 1 by default.
|
||||
|
||||
Getopts normally parses the positional parameters ($0 - $9), but if
|
||||
more arguments are given, they are parsed instead.
|
||||
Getopts normally parses the positional parameters, but if arguments
|
||||
are supplied as ARG values, they are parsed instead.
|
||||
|
||||
Exit Status:
|
||||
Returns success if an option is found; fails if the end of options is
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
This file is help.def, from which is created help.c.
|
||||
It implements the builtin "help" in Bash.
|
||||
|
||||
Copyright (C) 1987-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -132,7 +132,7 @@ help_builtin (list)
|
||||
{
|
||||
printf ("%s", ngettext ("Shell commands matching keyword `", "Shell commands matching keywords `", (list->next ? 2 : 1)));
|
||||
print_word_list (list, ", ");
|
||||
printf ("'\n\n");
|
||||
printf ("%s", _("'\n\n"));
|
||||
}
|
||||
|
||||
for (match_found = 0, pattern = ""; list; list = list->next)
|
||||
|
||||
@@ -2,7 +2,7 @@ This file is reserved.def, in which the shell reserved words are defined.
|
||||
It has no direct C file production, but defines builtins for the Bash
|
||||
builtin help command.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -194,7 +194,7 @@ $SHORT_DOC (( expression ))
|
||||
Evaluate arithmetic expression.
|
||||
|
||||
The EXPRESSION is evaluated according to the rules for arithmetic
|
||||
evaluation. Equivalent to "let EXPRESSION".
|
||||
evaluation. Equivalent to `let "EXPRESSION"'.
|
||||
|
||||
Exit Status:
|
||||
Returns 1 if EXPRESSION evaluates to 0; returns 0 otherwise.
|
||||
|
||||
+9
-6
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet.ramey@case.edu
|
||||
.\"
|
||||
.\" Last Change: Mon Jul 8 15:14:50 EDT 2019
|
||||
.\" Last Change: Fri Sep 20 15:30:19 EDT 2019
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2019 July 8" "GNU Bash 5.0"
|
||||
.TH BASH 1 "2019 September 20" "GNU Bash 5.0"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -742,7 +742,9 @@ to be matched as a string.
|
||||
An additional binary operator, \fB=~\fP, is available, with the same
|
||||
precedence as \fB==\fP and \fB!=\fP.
|
||||
When it is used, the string to the right of the operator is considered
|
||||
a POSIX extended regular expression and matched accordingly (as in \fIregex\fP(3)).
|
||||
a POSIX extended regular expression and matched accordingly
|
||||
(using the POSIX \fIregcomp\fP and \fIregexec\fP interfaces
|
||||
usually described in \fIregex\fP(3)).
|
||||
The return value is 0 if the string matches
|
||||
the pattern, and 1 otherwise.
|
||||
If the regular expression is syntactically incorrect, the conditional
|
||||
@@ -8494,7 +8496,7 @@ does not specify a valid job or
|
||||
.I jobspec
|
||||
specifies a job that was started without job control.
|
||||
.TP
|
||||
\fBgetopts\fP \fIoptstring\fP \fIname\fP [\fIargs\fP]
|
||||
\fBgetopts\fP \fIoptstring\fP \fIname\fP [\fIarg ...\fP]
|
||||
.B getopts
|
||||
is used by shell procedures to parse positional parameters.
|
||||
.I optstring
|
||||
@@ -8540,8 +8542,9 @@ and \fIname\fP is set to ?.
|
||||
.sp 1
|
||||
.B getopts
|
||||
normally parses the positional parameters, but if more arguments are
|
||||
given in
|
||||
.IR args ,
|
||||
supplied as
|
||||
.I arg
|
||||
values,
|
||||
.B getopts
|
||||
parses those instead.
|
||||
.sp 1
|
||||
|
||||
Binary file not shown.
+4451
-4441
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -1,4 +1,4 @@
|
||||
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018/MacPorts 2018.47642_7) (preloaded format=pdfetex 2019.1.16) 8 JUL 2019 15:16
|
||||
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018/MacPorts 2018.47642_7) (preloaded format=pdfetex 2019.1.16) 20 SEP 2019 14:50
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
file:line:error style messages enabled.
|
||||
@@ -286,7 +286,7 @@ Overfull \vbox (0.67252pt too high) has occurred while \output is active
|
||||
Here is how much of TeX's memory you used:
|
||||
4069 strings out of 497100
|
||||
47090 string characters out of 6206794
|
||||
137042 words of memory out of 5000000
|
||||
137054 words of memory out of 5000000
|
||||
4846 multiletter control sequences out of 15000+600000
|
||||
34315 words of font info for 116 fonts, out of 8000000 for 9000
|
||||
51 hyphenation exceptions out of 8191
|
||||
@@ -308,7 +308,7 @@ s/type1/public/amsfonts/cm/cmtt12.pfb></opt/local/share/texmf-texlive/fonts/typ
|
||||
e1/public/amsfonts/cm/cmtt9.pfb></opt/local/share/texmf-texlive/fonts/type1/pub
|
||||
lic/cm-super/sfrm1095.pfb></opt/local/share/texmf-texlive/fonts/type1/public/cm
|
||||
-super/sfrm1440.pfb>
|
||||
Output written on bashref.pdf (187 pages, 757503 bytes).
|
||||
Output written on bashref.pdf (187 pages, 757573 bytes).
|
||||
PDF statistics:
|
||||
2644 PDF objects out of 2984 (max. 8388607)
|
||||
2411 compressed objects within 25 object streams
|
||||
|
||||
Binary file not shown.
+9
-7
@@ -1033,7 +1033,8 @@ An additional binary operator, @samp{=~}, is available, with the same
|
||||
precedence as @samp{==} and @samp{!=}.
|
||||
When it is used, the string to the right of the operator is considered
|
||||
a @sc{POSIX} extended regular expression and matched accordingly
|
||||
(as in @i{regex}3)).
|
||||
(using the @sc{POSIX} @code{regcomp} and @code{regexec} interfaces
|
||||
usually described in @i{regex}(3)).
|
||||
The return value is 0 if the string matches
|
||||
the pattern, and 1 otherwise.
|
||||
If the regular expression is syntactically incorrect, the conditional
|
||||
@@ -1057,11 +1058,12 @@ string matching the @var{n}th parenthesized subexpression.
|
||||
|
||||
For example, the following will match a line
|
||||
(stored in the shell variable @var{line})
|
||||
if there is a sequence of characters in the value consisting of
|
||||
if there is a sequence of characters anywhere in the value consisting of
|
||||
any number, including zero, of
|
||||
space characters, zero or one instances of @samp{a}, then a @samp{b}:
|
||||
characters in the @code{space} character class,
|
||||
zero or one instances of @samp{a}, then a @samp{b}:
|
||||
@example
|
||||
[[ $line =~ [[:space:]]*?(a)b ]]
|
||||
[[ $line =~ [[:space:]]*(a)?b ]]
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@@ -1077,7 +1079,7 @@ expressions while paying attention to the shell's quote removal.
|
||||
Using a shell variable to store the pattern decreases these problems.
|
||||
For example, the following is equivalent to the above:
|
||||
@example
|
||||
pattern='[[:space:]]*?(a)b'
|
||||
pattern='[[:space:]]*(a)?b'
|
||||
[[ $line =~ $pattern ]]
|
||||
@end example
|
||||
|
||||
@@ -3574,7 +3576,7 @@ with a name that is not a shell function.
|
||||
@item getopts
|
||||
@btindex getopts
|
||||
@example
|
||||
getopts @var{optstring} @var{name} [@var{args}]
|
||||
getopts @var{optstring} @var{name} [@var{arg} @dots{}]
|
||||
@end example
|
||||
|
||||
@code{getopts} is used by shell scripts to parse positional parameters.
|
||||
@@ -3603,7 +3605,7 @@ and @var{name} is set to @samp{?}.
|
||||
|
||||
@code{getopts}
|
||||
normally parses the positional parameters, but if more arguments are
|
||||
given in @var{args}, @code{getopts} parses those instead.
|
||||
supplied as @var{arg} values, @code{getopts} parses those instead.
|
||||
|
||||
@code{getopts} can report errors in two ways. If the first character of
|
||||
@var{optstring} is a colon, @var{silent}
|
||||
|
||||
+3
-3
@@ -2,10 +2,10 @@
|
||||
Copyright (C) 1988-2019 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Mon Jul 8 15:10:15 EDT 2019
|
||||
@set LASTCHANGE Fri Sep 20 15:29:59 EDT 2019
|
||||
|
||||
@set EDITION 5.0
|
||||
@set VERSION 5.0
|
||||
|
||||
@set UPDATED 8 July 2019
|
||||
@set UPDATED-MONTH July 2019
|
||||
@set UPDATED 20 September 2019
|
||||
@set UPDATED-MONTH September 2019
|
||||
|
||||
@@ -4304,15 +4304,6 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
|
||||
if (pipe_out != NO_PIPE)
|
||||
result = last_command_exit_value;
|
||||
close_pipes (pipe_in, pipe_out);
|
||||
#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
|
||||
#if 0
|
||||
/* Close /dev/fd file descriptors in the parent after forking the
|
||||
last child in a (possibly one-element) pipeline. Defer this
|
||||
until any running shell function completes. */
|
||||
if (pipe_out == NO_PIPE && variable_context == 0) /* XXX */
|
||||
unlink_fifo_list (); /* XXX */
|
||||
#endif
|
||||
#endif
|
||||
command_line = (char *)NULL; /* don't free this. */
|
||||
#if 0
|
||||
bind_lastarg ((char *)NULL);
|
||||
|
||||
@@ -87,7 +87,7 @@ extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
#if !defined (HAVE_KILLPG)
|
||||
extern int killpg __P((pid_t, int));
|
||||
extern int killpg PARAMS((pid_t, int));
|
||||
#endif
|
||||
|
||||
#if !DEFAULT_CHILD_MAX
|
||||
@@ -162,7 +162,7 @@ extern int killpg __P((pid_t, int));
|
||||
/* The number of additional slots to allocate when we run out. */
|
||||
#define JOB_SLOTS 8
|
||||
|
||||
typedef int sh_job_map_func_t __P((JOB *, int, int, int));
|
||||
typedef int sh_job_map_func_t PARAMS((JOB *, int, int, int));
|
||||
|
||||
/* Variables used here but defined in other files. */
|
||||
extern sigset_t top_level_mask;
|
||||
@@ -170,13 +170,15 @@ extern WORD_LIST *subst_assign_varlist;
|
||||
|
||||
extern SigHandler **original_signals;
|
||||
|
||||
extern void set_original_signal __P((int, SigHandler *));
|
||||
extern void set_original_signal PARAMS((int, SigHandler *));
|
||||
|
||||
static struct jobstats zerojs = { -1L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NO_JOB, NO_JOB, 0, 0 };
|
||||
struct jobstats js = { -1L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NO_JOB, NO_JOB, 0, 0 };
|
||||
|
||||
ps_index_t pidstat_table[PIDSTAT_TABLE_SZ];
|
||||
struct bgpids bgpids = { 0, 0, 0 };
|
||||
struct bgpids bgpids = { 0, 0, 0, 0 };
|
||||
|
||||
struct procchain procsubs = { 0, 0, 0 };
|
||||
|
||||
/* The array of known jobs. */
|
||||
JOB **jobs = (JOB **)NULL;
|
||||
@@ -236,75 +238,75 @@ PROCESS *last_procsub_child = (PROCESS *)NULL;
|
||||
|
||||
void debug_print_pgrps (void);
|
||||
|
||||
static sighandler wait_sigint_handler __P((int));
|
||||
static sighandler sigchld_handler __P((int));
|
||||
static sighandler sigcont_sighandler __P((int));
|
||||
static sighandler sigstop_sighandler __P((int));
|
||||
static sighandler wait_sigint_handler PARAMS((int));
|
||||
static sighandler sigchld_handler PARAMS((int));
|
||||
static sighandler sigcont_sighandler PARAMS((int));
|
||||
static sighandler sigstop_sighandler PARAMS((int));
|
||||
|
||||
static int waitchld __P((pid_t, int));
|
||||
static int waitchld PARAMS((pid_t, int));
|
||||
|
||||
static PROCESS *find_pid_in_pipeline __P((pid_t, PROCESS *, int));
|
||||
static PROCESS *find_pipeline __P((pid_t, int, int *));
|
||||
static PROCESS *find_process __P((pid_t, int, int *));
|
||||
static PROCESS *find_pid_in_pipeline PARAMS((pid_t, PROCESS *, int));
|
||||
static PROCESS *find_pipeline PARAMS((pid_t, int, int *));
|
||||
static PROCESS *find_process PARAMS((pid_t, int, int *));
|
||||
|
||||
static char *current_working_directory __P((void));
|
||||
static char *job_working_directory __P((void));
|
||||
static char *j_strsignal __P((int));
|
||||
static char *printable_job_status __P((int, PROCESS *, int));
|
||||
static char *current_working_directory PARAMS((void));
|
||||
static char *job_working_directory PARAMS((void));
|
||||
static char *j_strsignal PARAMS((int));
|
||||
static char *printable_job_status PARAMS((int, PROCESS *, int));
|
||||
|
||||
static PROCESS *find_last_proc __P((int, int));
|
||||
static pid_t find_last_pid __P((int, int));
|
||||
static PROCESS *find_last_proc PARAMS((int, int));
|
||||
static pid_t find_last_pid PARAMS((int, int));
|
||||
|
||||
static int set_new_line_discipline __P((int));
|
||||
static int map_over_jobs __P((sh_job_map_func_t *, int, int));
|
||||
static int job_last_stopped __P((int));
|
||||
static int job_last_running __P((int));
|
||||
static int most_recent_job_in_state __P((int, JOB_STATE));
|
||||
static int find_job __P((pid_t, int, PROCESS **));
|
||||
static int print_job __P((JOB *, int, int, int));
|
||||
static int process_exit_status __P((WAIT));
|
||||
static int process_exit_signal __P((WAIT));
|
||||
static int set_job_status_and_cleanup __P((int));
|
||||
static int set_new_line_discipline PARAMS((int));
|
||||
static int map_over_jobs PARAMS((sh_job_map_func_t *, int, int));
|
||||
static int job_last_stopped PARAMS((int));
|
||||
static int job_last_running PARAMS((int));
|
||||
static int most_recent_job_in_state PARAMS((int, JOB_STATE));
|
||||
static int find_job PARAMS((pid_t, int, PROCESS **));
|
||||
static int print_job PARAMS((JOB *, int, int, int));
|
||||
static int process_exit_status PARAMS((WAIT));
|
||||
static int process_exit_signal PARAMS((WAIT));
|
||||
static int set_job_status_and_cleanup PARAMS((int));
|
||||
|
||||
static WAIT job_signal_status __P((int));
|
||||
static WAIT raw_job_exit_status __P((int));
|
||||
static WAIT job_signal_status PARAMS((int));
|
||||
static WAIT raw_job_exit_status PARAMS((int));
|
||||
|
||||
static void notify_of_job_status __P((void));
|
||||
static void reset_job_indices __P((void));
|
||||
static void cleanup_dead_jobs __P((void));
|
||||
static int processes_in_job __P((int));
|
||||
static void realloc_jobs_list __P((void));
|
||||
static int compact_jobs_list __P((int));
|
||||
static void add_process __P((char *, pid_t));
|
||||
static void print_pipeline __P((PROCESS *, int, int, FILE *));
|
||||
static void pretty_print_job __P((int, int, FILE *));
|
||||
static void set_current_job __P((int));
|
||||
static void reset_current __P((void));
|
||||
static void set_job_running __P((int));
|
||||
static void setjstatus __P((int));
|
||||
static int maybe_give_terminal_to __P((pid_t, pid_t, int));
|
||||
static void mark_all_jobs_as_dead __P((void));
|
||||
static void mark_dead_jobs_as_notified __P((int));
|
||||
static void restore_sigint_handler __P((void));
|
||||
static void notify_of_job_status PARAMS((void));
|
||||
static void reset_job_indices PARAMS((void));
|
||||
static void cleanup_dead_jobs PARAMS((void));
|
||||
static int processes_in_job PARAMS((int));
|
||||
static void realloc_jobs_list PARAMS((void));
|
||||
static int compact_jobs_list PARAMS((int));
|
||||
static void add_process PARAMS((char *, pid_t));
|
||||
static void print_pipeline PARAMS((PROCESS *, int, int, FILE *));
|
||||
static void pretty_print_job PARAMS((int, int, FILE *));
|
||||
static void set_current_job PARAMS((int));
|
||||
static void reset_current PARAMS((void));
|
||||
static void set_job_running PARAMS((int));
|
||||
static void setjstatus PARAMS((int));
|
||||
static int maybe_give_terminal_to PARAMS((pid_t, pid_t, int));
|
||||
static void mark_all_jobs_as_dead PARAMS((void));
|
||||
static void mark_dead_jobs_as_notified PARAMS((int));
|
||||
static void restore_sigint_handler PARAMS((void));
|
||||
#if defined (PGRP_PIPE)
|
||||
static void pipe_read __P((int *));
|
||||
static void pipe_read PARAMS((int *));
|
||||
#endif
|
||||
|
||||
/* Hash table manipulation */
|
||||
|
||||
static ps_index_t *pshash_getbucket __P((pid_t));
|
||||
static void pshash_delindex __P((ps_index_t));
|
||||
static ps_index_t *pshash_getbucket PARAMS((pid_t));
|
||||
static void pshash_delindex PARAMS((ps_index_t));
|
||||
|
||||
/* Saved background process status management */
|
||||
static struct pidstat *bgp_add __P((pid_t, int));
|
||||
static int bgp_delete __P((pid_t));
|
||||
static void bgp_clear __P((void));
|
||||
static int bgp_search __P((pid_t));
|
||||
static struct pidstat *bgp_add PARAMS((pid_t, int));
|
||||
static int bgp_delete PARAMS((pid_t));
|
||||
static void bgp_clear PARAMS((void));
|
||||
static int bgp_search PARAMS((pid_t));
|
||||
|
||||
static struct pipeline_saver *alloc_pipeline_saver __P((void));
|
||||
static struct pipeline_saver *alloc_pipeline_saver PARAMS((void));
|
||||
|
||||
static ps_index_t bgp_getindex __P((void));
|
||||
static void bgp_resize __P((void)); /* XXX */
|
||||
static ps_index_t bgp_getindex PARAMS((void));
|
||||
static void bgp_resize PARAMS((void)); /* XXX */
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
static int *pstatuses; /* list of pipeline statuses */
|
||||
@@ -441,6 +443,7 @@ cleanup_the_pipeline ()
|
||||
discard_pipeline (disposer);
|
||||
}
|
||||
|
||||
/* Not used right now */
|
||||
void
|
||||
discard_last_procsub_child ()
|
||||
{
|
||||
@@ -889,7 +892,7 @@ bgp_delete (pid)
|
||||
break;
|
||||
if (orig_psi == bgpids.storage[psi].bucket_next) /* catch reported bug */
|
||||
{
|
||||
internal_warning ("bgp_delete: LOOP: psi (%d) == storage[psi].bucket_next", psi);
|
||||
internal_warning (_("bgp_delete: LOOP: psi (%d) == storage[psi].bucket_next"), psi);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -942,7 +945,7 @@ bgp_search (pid)
|
||||
return (bgpids.storage[psi].status);
|
||||
if (orig_psi == bgpids.storage[psi].bucket_next) /* catch reported bug */
|
||||
{
|
||||
internal_warning ("bgp_search: LOOP: psi (%d) == storage[psi].bucket_next", psi);
|
||||
internal_warning (_("bgp_search: LOOP: psi (%d) == storage[psi].bucket_next"), psi);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -958,6 +961,195 @@ bgp_prune ()
|
||||
}
|
||||
#endif
|
||||
|
||||
/* External interface to bgp_add; takes care of blocking and unblocking
|
||||
SIGCHLD. Not really used. */
|
||||
void
|
||||
save_proc_status (pid, status)
|
||||
pid_t pid;
|
||||
int status;
|
||||
{
|
||||
sigset_t set, oset;
|
||||
|
||||
BLOCK_CHILD (set, oset);
|
||||
bgp_add (pid, status);
|
||||
UNBLOCK_CHILD (oset);
|
||||
}
|
||||
|
||||
#if defined (PROCESS_SUBSTITUTION)
|
||||
/* Functions to add and remove PROCESS * children from the list of running
|
||||
asynchronous process substitutions. The list is currently a simple singly
|
||||
linked list of PROCESS *, so it works with the set of callers that want
|
||||
a child. subst.c:process_substitute adds to the list, the various wait*
|
||||
functions manipulate child->running and child->status, and processes are
|
||||
eventually removed from the list and added to the bgpids table. */
|
||||
|
||||
static void
|
||||
procsub_free (p)
|
||||
PROCESS *p;
|
||||
{
|
||||
FREE (p->command);
|
||||
free (p);
|
||||
}
|
||||
|
||||
PROCESS *
|
||||
procsub_add (p)
|
||||
PROCESS *p;
|
||||
{
|
||||
sigset_t set, oset;
|
||||
|
||||
BLOCK_CHILD (set, oset);
|
||||
if (procsubs.head == 0)
|
||||
{
|
||||
procsubs.head = procsubs.end = p;
|
||||
procsubs.nproc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
procsubs.end->next = p;
|
||||
procsubs.end = p;
|
||||
}
|
||||
procsubs.nproc++;
|
||||
UNBLOCK_CHILD (oset);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
PROCESS *
|
||||
procsub_search (pid)
|
||||
pid_t pid;
|
||||
{
|
||||
PROCESS *p;
|
||||
sigset_t set, oset;
|
||||
|
||||
BLOCK_CHILD (set, oset);
|
||||
for (p = procsubs.head; p; p = p->next)
|
||||
if (p->pid == pid)
|
||||
break;
|
||||
UNBLOCK_CHILD (oset);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
PROCESS *
|
||||
procsub_delete (pid)
|
||||
pid_t pid;
|
||||
{
|
||||
PROCESS *p, *prev;
|
||||
sigset_t set, oset;
|
||||
|
||||
BLOCK_CHILD (set, oset);
|
||||
for (p = prev = procsubs.head; p; prev = p, p = p->next)
|
||||
if (p->pid == pid)
|
||||
{
|
||||
prev->next = p->next;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == 0)
|
||||
{
|
||||
UNBLOCK_CHILD (oset);
|
||||
return p;
|
||||
}
|
||||
|
||||
if (p == procsubs.head)
|
||||
procsubs.head = procsubs.head->next;
|
||||
else if (p == procsubs.end)
|
||||
procsubs.end = prev;
|
||||
|
||||
procsubs.nproc--;
|
||||
if (procsubs.nproc == 0)
|
||||
procsubs.head = procsubs.end = 0;
|
||||
else if (procsubs.nproc == 1) /* XXX */
|
||||
procsubs.end = procsubs.head;
|
||||
|
||||
/* this can't be called anywhere in a signal handling path */
|
||||
bgp_add (p->pid, process_exit_status (p->status));
|
||||
UNBLOCK_CHILD (oset);
|
||||
return (p);
|
||||
}
|
||||
|
||||
int
|
||||
procsub_waitpid (pid)
|
||||
pid_t pid;
|
||||
{
|
||||
PROCESS *p;
|
||||
int r;
|
||||
|
||||
p = procsub_search (pid);
|
||||
if (p == 0)
|
||||
return -1;
|
||||
if (p->running == PS_DONE)
|
||||
return (p->status);
|
||||
r = wait_for (p->pid);
|
||||
return (r); /* defer removing until later */
|
||||
}
|
||||
|
||||
void
|
||||
procsub_waitall ()
|
||||
{
|
||||
PROCESS *p;
|
||||
int r;
|
||||
|
||||
for (p = procsubs.head; p; p = p->next)
|
||||
{
|
||||
if (p->running == PS_DONE)
|
||||
continue;
|
||||
r = wait_for (p->pid);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
procsub_clear ()
|
||||
{
|
||||
PROCESS *p, *ps;
|
||||
sigset_t set, oset;
|
||||
|
||||
BLOCK_CHILD (set, oset);
|
||||
|
||||
for (ps = procsubs.head; ps; )
|
||||
{
|
||||
p = ps;
|
||||
ps = ps->next;
|
||||
procsub_free (p);
|
||||
}
|
||||
procsubs.head = procsubs.end = 0;
|
||||
procsubs.nproc = 0;
|
||||
UNBLOCK_CHILD (oset);
|
||||
}
|
||||
|
||||
/* Must be called with SIGCHLD blocked. */
|
||||
void
|
||||
procsub_prune ()
|
||||
{
|
||||
PROCESS *ohead, *oend, *ps, *p;
|
||||
int onproc;
|
||||
|
||||
if (procsubs.nproc == 0)
|
||||
return;
|
||||
|
||||
ohead = procsubs.head;
|
||||
oend = procsubs.end;
|
||||
onproc = procsubs.nproc;
|
||||
|
||||
procsubs.head = procsubs.end = 0;
|
||||
procsubs.nproc = 0;
|
||||
|
||||
for (p = ohead; p; )
|
||||
{
|
||||
ps = p->next;
|
||||
p->next = 0;
|
||||
if (p->running == PS_DONE)
|
||||
{
|
||||
bgp_add (p->pid, process_exit_status (p->status));
|
||||
procsub_free (p);
|
||||
}
|
||||
else
|
||||
procsub_add (p);
|
||||
p = ps;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Reset the values of js.j_lastj and js.j_firstj after one or both have
|
||||
been deleted. The caller should check whether js.j_njobs is 0 before
|
||||
calling this. This wraps around, but the rest of the code does not. At
|
||||
@@ -981,7 +1173,7 @@ reset_job_indices ()
|
||||
js.j_firstj++;
|
||||
}
|
||||
if (js.j_firstj == old)
|
||||
js.j_firstj = js.j_lastj = js.j_njobs = 0;
|
||||
js.j_firstj = js.j_lastj = js.j_njobs = 0;
|
||||
}
|
||||
if (jobs[js.j_lastj] == 0)
|
||||
{
|
||||
@@ -997,7 +1189,7 @@ reset_job_indices ()
|
||||
js.j_lastj--;
|
||||
}
|
||||
if (js.j_lastj == old)
|
||||
js.j_firstj = js.j_lastj = js.j_njobs = 0;
|
||||
js.j_firstj = js.j_lastj = js.j_njobs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1029,13 +1221,8 @@ cleanup_dead_jobs ()
|
||||
}
|
||||
|
||||
#if defined (PROCESS_SUBSTITUTION)
|
||||
if (last_procsub_child && last_procsub_child->running == PS_DONE)
|
||||
{
|
||||
bgp_add (last_procsub_child->pid, process_exit_status (last_procsub_child->status)); /* XXX */
|
||||
discard = last_procsub_child;
|
||||
last_procsub_child = (PROCESS *)NULL;
|
||||
discard_pipeline (discard);
|
||||
}
|
||||
procsub_prune ();
|
||||
last_procsub_child = (PROCESS *)NULL;
|
||||
#endif
|
||||
|
||||
#if defined (COPROCESS_SUPPORT)
|
||||
@@ -1307,10 +1494,10 @@ add_process (name, pid)
|
||||
{
|
||||
# ifdef DEBUG
|
||||
if (j == NO_JOB)
|
||||
internal_warning (_("add_process: process %5ld (%s) in the_pipeline"), (long)p->pid, p->command);
|
||||
internal_warning ("add_process: process %5ld (%s) in the_pipeline", (long)p->pid, p->command);
|
||||
# endif
|
||||
if (PALIVE (p))
|
||||
internal_warning (_("add_process: pid %5ld (%s) marked as still alive"), (long)p->pid, p->command);
|
||||
internal_warning (_("add_process: pid %5ld (%s) marked as still alive"), (long)p->pid, p->command);
|
||||
p->running = PS_RECYCLED; /* mark as recycled */
|
||||
}
|
||||
#endif
|
||||
@@ -1533,6 +1720,7 @@ find_pipeline (pid, alive_only, jobp)
|
||||
p = (PROCESS *)NULL;
|
||||
if (jobp)
|
||||
*jobp = NO_JOB;
|
||||
|
||||
if (the_pipeline && (p = find_pid_in_pipeline (pid, the_pipeline, alive_only)))
|
||||
return (p);
|
||||
|
||||
@@ -1540,10 +1728,11 @@ find_pipeline (pid, alive_only, jobp)
|
||||
for (save = saved_pipeline; save; save = save->next)
|
||||
if (save->pipeline && (p = find_pid_in_pipeline (pid, save->pipeline, alive_only)))
|
||||
return (p);
|
||||
|
||||
/* Now look in the last process substitution pipeline, since that sets $! */
|
||||
if (last_procsub_child && (p = find_pid_in_pipeline (pid, last_procsub_child, alive_only)))
|
||||
|
||||
#if defined (PROCESS_SUBSTITUTION)
|
||||
if (procsubs.nproc > 0 && (p = procsub_search (pid)) && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p)))
|
||||
return (p);
|
||||
#endif
|
||||
|
||||
job = find_job (pid, alive_only, &p);
|
||||
if (jobp)
|
||||
@@ -2090,7 +2279,7 @@ make_child (command, async_p)
|
||||
#endif
|
||||
#if defined (RECYCLES_PIDS)
|
||||
if (last_asynchronous_pid == mypid)
|
||||
/* Avoid pid aliasing. 1 seems like a safe, unusual pid value. */
|
||||
/* Avoid pid aliasing. 1 seems like a safe, unusual pid value. */
|
||||
last_asynchronous_pid = 1;
|
||||
#endif
|
||||
}
|
||||
@@ -2128,7 +2317,7 @@ make_child (command, async_p)
|
||||
last_asynchronous_pid = pid;
|
||||
#if defined (RECYCLES_PIDS)
|
||||
else if (last_asynchronous_pid == pid)
|
||||
/* Avoid pid aliasing. 1 seems like a safe, unusual pid value. */
|
||||
/* Avoid pid aliasing. 1 seems like a safe, unusual pid value. */
|
||||
last_asynchronous_pid = 1;
|
||||
#endif
|
||||
|
||||
@@ -2137,7 +2326,7 @@ make_child (command, async_p)
|
||||
delete_old_job (pid);
|
||||
|
||||
/* Perform the check for pid reuse unconditionally. Some systems reuse
|
||||
PIDs before giving a process CHILD_MAX/_SC_CHILD_MAX unique ones. */
|
||||
PIDs before giving a process CHILD_MAX/_SC_CHILD_MAX unique ones. */
|
||||
bgp_delete (pid); /* new process, discard any saved status */
|
||||
|
||||
last_made_pid = pid;
|
||||
@@ -2501,10 +2690,7 @@ wait_for_background_pids (ps)
|
||||
}
|
||||
|
||||
#if defined (PROCESS_SUBSTITUTION)
|
||||
if (last_procsub_child && last_procsub_child->pid != NO_PID && last_procsub_child->pid == last_asynchronous_pid)
|
||||
r = wait_for (last_procsub_child->pid);
|
||||
wait_procsubs ();
|
||||
reap_procsubs ();
|
||||
procsub_waitall ();
|
||||
#endif
|
||||
|
||||
/* POSIX.2 says the shell can discard the statuses of all completed jobs if
|
||||
@@ -2740,11 +2926,11 @@ wait_for (pid)
|
||||
|
||||
temp_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
|
||||
if (temp_sigint_handler == wait_sigint_handler)
|
||||
{
|
||||
{
|
||||
#if defined (DEBUG)
|
||||
internal_warning ("wait_for: recursively setting old_sigint_handler to wait_sigint_handler: running_trap = %d", running_trap);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
old_sigint_handler = temp_sigint_handler;
|
||||
waiting_for_child = 0;
|
||||
@@ -3022,7 +3208,7 @@ if (job == NO_JOB)
|
||||
}
|
||||
|
||||
/* Moved here from set_job_status_and_cleanup, which is in the SIGCHLD
|
||||
signal handler path */
|
||||
signal handler path */
|
||||
if (DEADJOB (job) && IS_FOREGROUND (job) /*&& subshell_environment == 0*/)
|
||||
setjstatus (job);
|
||||
|
||||
@@ -3142,8 +3328,8 @@ return_job:
|
||||
/* Make sure there is a background job to wait for */
|
||||
BLOCK_CHILD (set, oset);
|
||||
for (i = 0; i < js.j_jobslots; i++)
|
||||
if (jobs[i] && RUNNING (i) && IS_FOREGROUND (i) == 0)
|
||||
break;
|
||||
if (jobs[i] && RUNNING (i) && IS_FOREGROUND (i) == 0)
|
||||
break;
|
||||
if (i == js.j_jobslots)
|
||||
{
|
||||
UNBLOCK_CHILD (oset);
|
||||
@@ -3678,10 +3864,10 @@ itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, bloc
|
||||
/* If the child process did die due to SIGINT, forget our assumption
|
||||
that it caught or otherwise handled it. */
|
||||
if (WIFSIGNALED (status) && WTERMSIG (status) == SIGINT)
|
||||
child_caught_sigint = 0;
|
||||
child_caught_sigint = 0;
|
||||
|
||||
/* children_exited is used to run traps on SIGCHLD. We don't want to
|
||||
run the trap if a process is just being continued. */
|
||||
run the trap if a process is just being continued. */
|
||||
if (WIFCONTINUED(status) == 0)
|
||||
{
|
||||
children_exited++;
|
||||
@@ -3697,7 +3883,9 @@ itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, bloc
|
||||
|
||||
#if defined (PROCESS_SUBSTITUTION)
|
||||
/* Only manipulate the list of process substitutions while SIGCHLD
|
||||
is blocked. */
|
||||
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)
|
||||
set_procsub_status (ind, pid, WSTATUS (status));
|
||||
#endif
|
||||
@@ -4693,7 +4881,7 @@ mark_dead_jobs_as_notified (force)
|
||||
way to avoid pid aliasing and reuse problems than keeping the POSIX-
|
||||
mandated CHILD_MAX jobs around. delete_job() takes care of keeping the
|
||||
bgpids list regulated. */
|
||||
|
||||
|
||||
/* Count the number of dead jobs */
|
||||
/* XXX could use js.j_firstj here */
|
||||
for (i = ndead = ndeadproc = 0; i < js.j_jobslots; i++)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* jobs.h -- structures and definitions used by the jobs.c file. */
|
||||
|
||||
/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -175,6 +175,14 @@ struct procstat {
|
||||
bits16_t status;
|
||||
};
|
||||
|
||||
/* A standalone singly-linked list of PROCESS *, used in various places
|
||||
including keeping track of process substitutions. */
|
||||
struct procchain {
|
||||
PROCESS *head;
|
||||
PROCESS *end;
|
||||
int nproc;
|
||||
};
|
||||
|
||||
#define NO_JOB -1 /* An impossible job array index. */
|
||||
#define DUP_JOB -2 /* A possible return value for get_job_spec (). */
|
||||
#define BAD_JOBSPEC -3 /* Bad syntax for job spec. */
|
||||
@@ -203,87 +211,97 @@ extern PROCESS *last_procsub_child;
|
||||
|
||||
extern JOB **jobs;
|
||||
|
||||
extern void making_children __P((void));
|
||||
extern void stop_making_children __P((void));
|
||||
extern void cleanup_the_pipeline __P((void));
|
||||
extern void discard_last_procsub_child __P((void));
|
||||
extern void save_pipeline __P((int));
|
||||
extern PROCESS *restore_pipeline __P((int));
|
||||
extern void start_pipeline __P((void));
|
||||
extern int stop_pipeline __P((int, COMMAND *));
|
||||
extern int discard_pipeline __P((PROCESS *));
|
||||
extern void append_process __P((char *, pid_t, int, int));
|
||||
extern void making_children PARAMS((void));
|
||||
extern void stop_making_children PARAMS((void));
|
||||
extern void cleanup_the_pipeline PARAMS((void));
|
||||
extern void discard_last_procsub_child PARAMS((void));
|
||||
extern void save_pipeline PARAMS((int));
|
||||
extern PROCESS *restore_pipeline PARAMS((int));
|
||||
extern void start_pipeline PARAMS((void));
|
||||
extern int stop_pipeline PARAMS((int, COMMAND *));
|
||||
extern int discard_pipeline PARAMS((PROCESS *));
|
||||
extern void append_process PARAMS((char *, pid_t, int, int));
|
||||
|
||||
extern void delete_job __P((int, int));
|
||||
extern void nohup_job __P((int));
|
||||
extern void delete_all_jobs __P((int));
|
||||
extern void nohup_all_jobs __P((int));
|
||||
extern void save_proc_status PARAMS((pid_t, int));
|
||||
|
||||
extern int count_all_jobs __P((void));
|
||||
extern PROCESS *procsub_add PARAMS((PROCESS *));
|
||||
extern PROCESS *procsub_search PARAMS((pid_t));
|
||||
extern PROCESS *procsub_delete PARAMS((pid_t));
|
||||
extern int procsub_waitpid PARAMS((pid_t));
|
||||
extern void procsub_waitall PARAMS((void));
|
||||
extern void procsub_clear PARAMS((void));
|
||||
extern void procsub_prune PARAMS((void));
|
||||
|
||||
extern void terminate_current_pipeline __P((void));
|
||||
extern void terminate_stopped_jobs __P((void));
|
||||
extern void hangup_all_jobs __P((void));
|
||||
extern void kill_current_pipeline __P((void));
|
||||
extern void delete_job PARAMS((int, int));
|
||||
extern void nohup_job PARAMS((int));
|
||||
extern void delete_all_jobs PARAMS((int));
|
||||
extern void nohup_all_jobs PARAMS((int));
|
||||
|
||||
extern int count_all_jobs PARAMS((void));
|
||||
|
||||
extern void terminate_current_pipeline PARAMS((void));
|
||||
extern void terminate_stopped_jobs PARAMS((void));
|
||||
extern void hangup_all_jobs PARAMS((void));
|
||||
extern void kill_current_pipeline PARAMS((void));
|
||||
|
||||
#if defined (__STDC__) && defined (pid_t)
|
||||
extern int get_job_by_pid __P((int, int));
|
||||
extern void describe_pid __P((int));
|
||||
extern int get_job_by_pid PARAMS((int, int));
|
||||
extern void describe_pid PARAMS((int));
|
||||
#else
|
||||
extern int get_job_by_pid __P((pid_t, int));
|
||||
extern void describe_pid __P((pid_t));
|
||||
extern int get_job_by_pid PARAMS((pid_t, int));
|
||||
extern void describe_pid PARAMS((pid_t));
|
||||
#endif
|
||||
|
||||
extern void list_one_job __P((JOB *, int, int, int));
|
||||
extern void list_all_jobs __P((int));
|
||||
extern void list_stopped_jobs __P((int));
|
||||
extern void list_running_jobs __P((int));
|
||||
extern void list_one_job PARAMS((JOB *, int, int, int));
|
||||
extern void list_all_jobs PARAMS((int));
|
||||
extern void list_stopped_jobs PARAMS((int));
|
||||
extern void list_running_jobs PARAMS((int));
|
||||
|
||||
extern pid_t make_child __P((char *, int));
|
||||
extern pid_t make_child PARAMS((char *, int));
|
||||
|
||||
extern int get_tty_state __P((void));
|
||||
extern int set_tty_state __P((void));
|
||||
extern int get_tty_state PARAMS((void));
|
||||
extern int set_tty_state PARAMS((void));
|
||||
|
||||
extern int job_exit_status __P((int));
|
||||
extern int job_exit_signal __P((int));
|
||||
extern int job_exit_status PARAMS((int));
|
||||
extern int job_exit_signal PARAMS((int));
|
||||
|
||||
extern int wait_for_single_pid __P((pid_t, int));
|
||||
extern void wait_for_background_pids __P((struct procstat *));
|
||||
extern int wait_for __P((pid_t));
|
||||
extern int wait_for_job __P((int, int, struct procstat *));
|
||||
extern int wait_for_any_job __P((int, struct procstat *));
|
||||
extern int wait_for_single_pid PARAMS((pid_t, int));
|
||||
extern void wait_for_background_pids PARAMS((struct procstat *));
|
||||
extern int wait_for PARAMS((pid_t));
|
||||
extern int wait_for_job PARAMS((int, int, struct procstat *));
|
||||
extern int wait_for_any_job PARAMS((int, struct procstat *));
|
||||
|
||||
extern void wait_sigint_cleanup __P((void));
|
||||
extern void wait_sigint_cleanup PARAMS((void));
|
||||
|
||||
extern void notify_and_cleanup __P((void));
|
||||
extern void reap_dead_jobs __P((void));
|
||||
extern int start_job __P((int, int));
|
||||
extern int kill_pid __P((pid_t, int, int));
|
||||
extern int initialize_job_control __P((int));
|
||||
extern void initialize_job_signals __P((void));
|
||||
extern int give_terminal_to __P((pid_t, int));
|
||||
extern void notify_and_cleanup PARAMS((void));
|
||||
extern void reap_dead_jobs PARAMS((void));
|
||||
extern int start_job PARAMS((int, int));
|
||||
extern int kill_pid PARAMS((pid_t, int, int));
|
||||
extern int initialize_job_control PARAMS((int));
|
||||
extern void initialize_job_signals PARAMS((void));
|
||||
extern int give_terminal_to PARAMS((pid_t, int));
|
||||
|
||||
extern void run_sigchld_trap __P((int));
|
||||
extern void run_sigchld_trap PARAMS((int));
|
||||
|
||||
extern int freeze_jobs_list __P((void));
|
||||
extern void unfreeze_jobs_list __P((void));
|
||||
extern void set_jobs_list_frozen __P((int));
|
||||
extern int set_job_control __P((int));
|
||||
extern void without_job_control __P((void));
|
||||
extern void end_job_control __P((void));
|
||||
extern void restart_job_control __P((void));
|
||||
extern void set_sigchld_handler __P((void));
|
||||
extern void ignore_tty_job_signals __P((void));
|
||||
extern void default_tty_job_signals __P((void));
|
||||
extern void get_original_tty_job_signals __P((void));
|
||||
extern int freeze_jobs_list PARAMS((void));
|
||||
extern void unfreeze_jobs_list PARAMS((void));
|
||||
extern void set_jobs_list_frozen PARAMS((int));
|
||||
extern int set_job_control PARAMS((int));
|
||||
extern void without_job_control PARAMS((void));
|
||||
extern void end_job_control PARAMS((void));
|
||||
extern void restart_job_control PARAMS((void));
|
||||
extern void set_sigchld_handler PARAMS((void));
|
||||
extern void ignore_tty_job_signals PARAMS((void));
|
||||
extern void default_tty_job_signals PARAMS((void));
|
||||
extern void get_original_tty_job_signals PARAMS((void));
|
||||
|
||||
extern void init_job_stats __P((void));
|
||||
extern void init_job_stats PARAMS((void));
|
||||
|
||||
extern void close_pgrp_pipe __P((void));
|
||||
extern void save_pgrp_pipe __P((int *, int));
|
||||
extern void restore_pgrp_pipe __P((int *));
|
||||
extern void close_pgrp_pipe PARAMS((void));
|
||||
extern void save_pgrp_pipe PARAMS((int *, int));
|
||||
extern void restore_pgrp_pipe PARAMS((int *));
|
||||
|
||||
extern void set_maxchild __P((int));
|
||||
extern void set_maxchild PARAMS((int));
|
||||
|
||||
extern int job_control; /* set to 0 in nojobs.c */
|
||||
|
||||
|
||||
@@ -605,7 +605,9 @@ static void
|
||||
init_line_structures (int minsize)
|
||||
{
|
||||
register int n;
|
||||
int osize;
|
||||
|
||||
osize = minsize;
|
||||
if (minsize <= _rl_screenwidth) /* XXX - for gdb */
|
||||
minsize = _rl_screenwidth + 1;
|
||||
|
||||
@@ -625,7 +627,7 @@ init_line_structures (int minsize)
|
||||
invisible_line = (char *)xrealloc (invisible_line, line_size);
|
||||
}
|
||||
|
||||
for (n = minsize; n < line_size; n++)
|
||||
for (n = osize; n < line_size; n++)
|
||||
{
|
||||
visible_line[n] = 0;
|
||||
invisible_line[n] = 1;
|
||||
|
||||
@@ -4435,7 +4435,7 @@ xparse_dolparen (base, string, indp, flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
|
||||
/*itrace("xparse_dolparen: size = %d shell_input_line = `%s' string=`%s'", shell_input_line_size, shell_input_line, string);*/
|
||||
sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
|
||||
if (flags & SX_NOLONGJMP)
|
||||
sflags |= SEVAL_NOLONGJMP;
|
||||
@@ -4459,11 +4459,13 @@ xparse_dolparen (base, string, indp, flags)
|
||||
if (current_token == shell_eof_token)
|
||||
yyclearin; /* might want to clear lookahead token unconditionally */
|
||||
|
||||
reset_parser ();
|
||||
/* reset_parser() clears shell_input_line and associated variables, including
|
||||
parser_state, so we want to reset things, then restore what we need. */
|
||||
restore_input_line_state (&ls);
|
||||
|
||||
shell_eof_token = orig_eof_token;
|
||||
restore_parser_state (&ps);
|
||||
reset_parser ();
|
||||
/* reset_parser clears shell_input_line and associated variables */
|
||||
restore_input_line_state (&ls);
|
||||
|
||||
#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
|
||||
pushed_string_list = saved_pushed_strings;
|
||||
|
||||
@@ -584,7 +584,7 @@ termsig_handler (sig)
|
||||
#if defined (PROCESS_SUBSTITUTION)
|
||||
unlink_fifo_list ();
|
||||
# if defined (JOB_CONTROL)
|
||||
discard_last_procsub_child ();
|
||||
procsub_clear ();
|
||||
# endif
|
||||
#endif /* PROCESS_SUBSTITUTION */
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_STRSIGNAL)
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bashtypes.h"
|
||||
#include "general.h"
|
||||
#include <signal.h>
|
||||
|
||||
#include "siglist.h"
|
||||
@@ -33,7 +33,6 @@
|
||||
#endif
|
||||
|
||||
#include "bashintl.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
char *sys_siglist[NSIG];
|
||||
|
||||
@@ -220,7 +219,7 @@ initialize_siglist ()
|
||||
if (!sys_siglist[i])
|
||||
{
|
||||
sys_siglist[i] =
|
||||
(char *)xmalloc (10 + strlen (_("Unknown Signal #")));
|
||||
(char *)xmalloc (INT_STRLEN_BOUND (int) + 1 + strlen (_("Unknown Signal #%d")));
|
||||
|
||||
sprintf (sys_siglist[i], _("Unknown Signal #%d"), i);
|
||||
}
|
||||
|
||||
@@ -5539,6 +5539,8 @@ reap_procsubs ()
|
||||
reap_some_procsubs (nfifo);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* UNUSED */
|
||||
void
|
||||
wait_procsubs ()
|
||||
{
|
||||
@@ -5549,11 +5551,12 @@ wait_procsubs ()
|
||||
if (fifo_list[i].proc != (pid_t)-1 && fifo_list[i].proc > 0)
|
||||
{
|
||||
r = wait_for (fifo_list[i].proc);
|
||||
/* add to bgpids list? have to make interface public */
|
||||
save_proc_status (fifo_list[i].proc, r);
|
||||
fifo_list[i].proc = (pid_t)-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
fifos_pending ()
|
||||
@@ -5773,6 +5776,8 @@ reap_procsubs ()
|
||||
reap_some_procsubs (totfds);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* UNUSED */
|
||||
void
|
||||
wait_procsubs ()
|
||||
{
|
||||
@@ -5783,11 +5788,12 @@ wait_procsubs ()
|
||||
if (dev_fd_list[i] != (pid_t)-1 && dev_fd_list[i] > 0)
|
||||
{
|
||||
r = wait_for (dev_fd_list[i]);
|
||||
/* add to bgpids list? have to make interface public */
|
||||
save_proc_status (dev_fd_list[i], r);
|
||||
dev_fd_list[i] = (pid_t)-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (NOTDEF)
|
||||
print_dev_fd_list ()
|
||||
@@ -5937,9 +5943,11 @@ process_substitute (string, open_for_read_in_child)
|
||||
if (pid > 0)
|
||||
{
|
||||
#if defined (JOB_CONTROL)
|
||||
if (last_procsub_child)
|
||||
discard_last_procsub_child ();
|
||||
last_procsub_child = restore_pipeline (0);
|
||||
/* We assume that last_procsub_child->next == last_procsub_child because
|
||||
of how jobs.c:add_process() works. */
|
||||
last_procsub_child->next = 0;
|
||||
procsub_add (last_procsub_child);
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_DEV_FD)
|
||||
@@ -5967,6 +5975,9 @@ process_substitute (string, open_for_read_in_child)
|
||||
/* make sure we don't have any job control */
|
||||
set_job_control (0);
|
||||
|
||||
/* Clear out any existing list of process substitutions */
|
||||
procsub_clear ();
|
||||
|
||||
/* The idea is that we want all the jobs we start from an async process
|
||||
substitution to be in the same process group, but not the same pgrp
|
||||
as our parent shell, since we don't want to affect our parent shell's
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ declare: usage: declare [-aAfFgilnrtux] [-p] [name[=value] ...]
|
||||
./errors.tests: line 74: declare: `/bin/sh': not a valid identifier
|
||||
./errors.tests: line 78: declare: cannot use `-f' to make functions
|
||||
./errors.tests: line 81: exec: -i: invalid option
|
||||
exec: usage: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
|
||||
exec: usage: exec [-cl] [-a name] [command [argument ...]] [redirection ...]
|
||||
./errors.tests: line 85: export: XPATH: not a function
|
||||
./errors.tests: line 88: break: only meaningful in a `for', `while', or `until' loop
|
||||
./errors.tests: line 89: continue: only meaningful in a `for', `while', or `until' loop
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
getopts: usage: getopts optstring name [arg]
|
||||
getopts: usage: getopts optstring name [arg ...]
|
||||
2
|
||||
getopts: usage: getopts optstring name [arg]
|
||||
getopts: usage: getopts optstring name [arg ...]
|
||||
2
|
||||
./getopts.tests: line 23: getopts: -a: invalid option
|
||||
getopts: usage: getopts optstring name [arg]
|
||||
getopts: usage: getopts optstring name [arg ...]
|
||||
-a specified
|
||||
-b bval specified
|
||||
remaining args: one two three
|
||||
|
||||
Reference in New Issue
Block a user