mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-07 02:32:27 +02:00
commit bash-20200316 snapshot
This commit is contained in:
+61
-1
@@ -7339,7 +7339,7 @@ expr.c
|
|||||||
test.c
|
test.c
|
||||||
- unary_test: allow -v N to test whether or not positional parameter
|
- unary_test: allow -v N to test whether or not positional parameter
|
||||||
N is set. Most recently suggested by Peng Yu <pengyu.ut@gmail.com>
|
N is set. Most recently suggested by Peng Yu <pengyu.ut@gmail.com>
|
||||||
and Martijn Dekker <martijn@inlv.org>
|
and Martijn Dekker <martijn@inlv.org>
|
||||||
|
|
||||||
builtins/getopts.def
|
builtins/getopts.def
|
||||||
- dogetopts: use number_of_args() to compute the number of positional
|
- dogetopts: use number_of_args() to compute the number of positional
|
||||||
@@ -7540,3 +7540,63 @@ subst.c
|
|||||||
we are returning a quoted null string to the caller by setting
|
we are returning a quoted null string to the caller by setting
|
||||||
W_HASQUOTEDNULL. Fixes bug reported by Martin Castillo
|
W_HASQUOTEDNULL. Fixes bug reported by Martin Castillo
|
||||||
<castilma@uni-bremen.de>
|
<castilma@uni-bremen.de>
|
||||||
|
|
||||||
|
3/17
|
||||||
|
----
|
||||||
|
lib/readline/histfile.c
|
||||||
|
- history_truncate_file: only chown the file if we really need to. From
|
||||||
|
alex@lisas.de via https://savannah.gnu.org/support/?110207
|
||||||
|
|
||||||
|
lib/readline/bind.c
|
||||||
|
- rl_unbind_function_in_map: since we are looking for functions, not
|
||||||
|
key sequences, descend into keymaps attached to the keymap passed
|
||||||
|
as an argument. From a report from lockywolf@gmail.com back on 2/27,
|
||||||
|
TENTATIVE CHANGE
|
||||||
|
|
||||||
|
variables.h
|
||||||
|
- MKLOC_ARRAYOK,MKLOC_ASSOCOK: new flags values for
|
||||||
|
make_local_{array,assoc}_variable so we can avoid hard-coded values
|
||||||
|
of 1 and make it possible to eventually pass in additional flags
|
||||||
|
|
||||||
|
builtins/declare.def
|
||||||
|
- declare_internal: make_local_array_variable: pass MKLOC_ASSOCOK
|
||||||
|
- declare_internal: make_local_assoc_variable: pass MKLOC_ARRAYOK
|
||||||
|
|
||||||
|
variables.c
|
||||||
|
- make_local_{array,assoc}_variable: understand new flags, pass
|
||||||
|
MKLOC_INHERIT to make_local_variable if it appears in the flags
|
||||||
|
argument
|
||||||
|
|
||||||
|
builtins/declare.def
|
||||||
|
- declare_internal: add a new -I option for local and declare that
|
||||||
|
inherits attributes and value from a variable with the same name
|
||||||
|
at a previous scope. Inspired by netbsd sh
|
||||||
|
- if -I option is supplied, pass MKLOC_INHERIT to make_local_variable
|
||||||
|
and its array counterparts make_local_{array,assoc}_variable
|
||||||
|
|
||||||
|
subst.c
|
||||||
|
- shell_expand_word_list: pass -I to declare if constructing a declare
|
||||||
|
command with make_local_declare, meaning we have an array or assoc
|
||||||
|
compound assignment. (Slighty unsatisfactory, but ok for now) Fix
|
||||||
|
for bug report from Kevin Locke <kevin@kevinlocke.name>,
|
||||||
|
https://savannah.gnu.org/support/index.php?109669
|
||||||
|
|
||||||
|
3/18
|
||||||
|
----
|
||||||
|
examples/loadables/basename.c
|
||||||
|
- basename_builtin: handle -- option without crashing. Report by Peng Yu
|
||||||
|
<pengyu.ut@gmail.com>
|
||||||
|
|
||||||
|
jobs.c
|
||||||
|
- notify_of_job_status: if in posix-mode shell is started with -c,
|
||||||
|
jobs should print the status of completed jobs. From a report by
|
||||||
|
Robert Elz <kre@munnari.oz.au> back in 12/18
|
||||||
|
|
||||||
|
3/19
|
||||||
|
----
|
||||||
|
variables.c
|
||||||
|
- assign_in_env: if we're assigning POSIXLY_CORRECT or POSIX_PEDANTIC
|
||||||
|
in the temporary environment, save the values of the options
|
||||||
|
affected by posix mode so we can restore them when we restore the
|
||||||
|
old value of the variable after the command executes. Suggested by
|
||||||
|
Martijn Dekker <martijn@inlv.org>
|
||||||
|
|||||||
+14
-9
@@ -34,6 +34,8 @@ Options:
|
|||||||
source file when debugging)
|
source file when debugging)
|
||||||
-g create global variables when used in a shell function; otherwise
|
-g create global variables when used in a shell function; otherwise
|
||||||
ignored
|
ignored
|
||||||
|
-I if creating a local variable, inherit the attributes and value
|
||||||
|
of a variable with the same name at a previous scope
|
||||||
-p display the attributes and value of each NAME
|
-p display the attributes and value of each NAME
|
||||||
|
|
||||||
Options which set attributes:
|
Options which set attributes:
|
||||||
@@ -135,9 +137,9 @@ local_builtin (list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined (ARRAY_VARS)
|
#if defined (ARRAY_VARS)
|
||||||
# define DECLARE_OPTS "+acfgilnprtuxAFG"
|
# define DECLARE_OPTS "+acfgilnprtuxAFGI"
|
||||||
#else
|
#else
|
||||||
# define DECLARE_OPTS "+cfgilnprtuxFG"
|
# define DECLARE_OPTS "+cfgilnprtuxFGI"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static SHELL_VAR *
|
static SHELL_VAR *
|
||||||
@@ -168,13 +170,13 @@ declare_internal (list, local_var)
|
|||||||
{
|
{
|
||||||
int flags_on, flags_off, *flags;
|
int flags_on, flags_off, *flags;
|
||||||
int any_failed, assign_error, pflag, nodefs, opt, onref, offref;
|
int any_failed, assign_error, pflag, nodefs, opt, onref, offref;
|
||||||
int mkglobal, chklocal;
|
int mkglobal, chklocal, inherit_flag;
|
||||||
char *t, *subscript_start;
|
char *t, *subscript_start;
|
||||||
SHELL_VAR *var, *refvar, *v;
|
SHELL_VAR *var, *refvar, *v;
|
||||||
FUNCTION_DEF *shell_fn;
|
FUNCTION_DEF *shell_fn;
|
||||||
|
|
||||||
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0;
|
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0;
|
||||||
mkglobal = chklocal = 0;
|
mkglobal = chklocal = inherit_flag = 0;
|
||||||
refvar = (SHELL_VAR *)NULL;
|
refvar = (SHELL_VAR *)NULL;
|
||||||
reset_internal_getopt ();
|
reset_internal_getopt ();
|
||||||
while ((opt = internal_getopt (list, DECLARE_OPTS)) != -1)
|
while ((opt = internal_getopt (list, DECLARE_OPTS)) != -1)
|
||||||
@@ -255,6 +257,9 @@ declare_internal (list, local_var)
|
|||||||
flags_off |= att_capcase|att_lowercase;
|
flags_off |= att_capcase|att_lowercase;
|
||||||
break;
|
break;
|
||||||
#endif /* CASEMOD_ATTRS */
|
#endif /* CASEMOD_ATTRS */
|
||||||
|
case 'I':
|
||||||
|
inherit_flag = MKLOC_INHERIT;
|
||||||
|
break;
|
||||||
CASE_HELPOPT;
|
CASE_HELPOPT;
|
||||||
default:
|
default:
|
||||||
builtin_usage ();
|
builtin_usage ();
|
||||||
@@ -452,9 +457,9 @@ restart_new_var_name:
|
|||||||
return an existing {array,assoc} variable to be flagged as an
|
return an existing {array,assoc} variable to be flagged as an
|
||||||
error below. */
|
error below. */
|
||||||
if (flags_on & att_assoc)
|
if (flags_on & att_assoc)
|
||||||
var = make_local_assoc_variable (newname, 1);
|
var = make_local_assoc_variable (newname, MKLOC_ARRAYOK|inherit_flag);
|
||||||
else if ((flags_on & att_array) || making_array_special)
|
else if ((flags_on & att_array) || making_array_special)
|
||||||
var = make_local_array_variable (newname, 1);
|
var = make_local_array_variable (newname, MKLOC_ASSOCOK|inherit_flag);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (offset == 0 && (flags_on & att_nameref))
|
if (offset == 0 && (flags_on & att_nameref))
|
||||||
@@ -468,18 +473,18 @@ restart_new_var_name:
|
|||||||
if (refvar && refvar->context != variable_context)
|
if (refvar && refvar->context != variable_context)
|
||||||
{
|
{
|
||||||
refvar = 0;
|
refvar = 0;
|
||||||
var = make_local_variable (name, 0);
|
var = make_local_variable (name, inherit_flag);
|
||||||
}
|
}
|
||||||
else if (refvar && refvar->context == variable_context)
|
else if (refvar && refvar->context == variable_context)
|
||||||
var = refvar;
|
var = refvar;
|
||||||
/* Maybe we just want to create a new local variable */
|
/* Maybe we just want to create a new local variable */
|
||||||
else if (var == 0 || var->context != variable_context)
|
else if (var == 0 || var->context != variable_context)
|
||||||
var = make_local_variable (name, 0);
|
var = make_local_variable (name, inherit_flag);
|
||||||
/* otherwise we have a var at the right context */
|
/* otherwise we have a var at the right context */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* XXX - check name for validity here with valid_nameref_value */
|
/* XXX - check name for validity here with valid_nameref_value */
|
||||||
var = make_local_variable ((flags_on & att_nameref) ? name : newname, 0); /* sets att_invisible for new vars */
|
var = make_local_variable ((flags_on & att_nameref) ? name : newname, inherit_flag); /* sets att_invisible for new vars */
|
||||||
|
|
||||||
if (var == 0)
|
if (var == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
+11
-4
@@ -5,12 +5,12 @@
|
|||||||
.\" Case Western Reserve University
|
.\" Case Western Reserve University
|
||||||
.\" chet.ramey@case.edu
|
.\" chet.ramey@case.edu
|
||||||
.\"
|
.\"
|
||||||
.\" Last Change: Wed Jan 29 14:00:16 EST 2020
|
.\" Last Change: Tue Mar 17 18:27:36 EDT 2020
|
||||||
.\"
|
.\"
|
||||||
.\" bash_builtins, strip all but Built-Ins section
|
.\" bash_builtins, strip all but Built-Ins section
|
||||||
.if \n(zZ=1 .ig zZ
|
.if \n(zZ=1 .ig zZ
|
||||||
.if \n(zY=1 .ig zY
|
.if \n(zY=1 .ig zY
|
||||||
.TH BASH 1 "2020 January 29" "GNU Bash 5.0"
|
.TH BASH 1 "2020 March 17" "GNU Bash 5.0"
|
||||||
.\"
|
.\"
|
||||||
.\" There's some problem with having a `@'
|
.\" There's some problem with having a `@'
|
||||||
.\" in a tagged paragraph with the BSD man macros.
|
.\" in a tagged paragraph with the BSD man macros.
|
||||||
@@ -8023,10 +8023,10 @@ is greater than the number of enclosing loops, the last enclosing loop
|
|||||||
(the ``top-level'' loop) is resumed.
|
(the ``top-level'' loop) is resumed.
|
||||||
The return value is 0 unless \fIn\fP is not greater than or equal to 1.
|
The return value is 0 unless \fIn\fP is not greater than or equal to 1.
|
||||||
.TP
|
.TP
|
||||||
\fBdeclare\fP [\fB\-aAfFgilnrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
|
\fBdeclare\fP [\fB\-aAfFgiIlnrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
|
||||||
.PD 0
|
.PD 0
|
||||||
.TP
|
.TP
|
||||||
\fBtypeset\fP [\fB\-aAfFgilnrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
|
\fBtypeset\fP [\fB\-aAfFgiIlnrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
|
||||||
.PD
|
.PD
|
||||||
Declare variables and/or give them attributes.
|
Declare variables and/or give them attributes.
|
||||||
If no \fIname\fPs are given then display the values of variables.
|
If no \fIname\fPs are given then display the values of variables.
|
||||||
@@ -8061,6 +8061,13 @@ The
|
|||||||
option forces variables to be created or modified at the global scope,
|
option forces variables to be created or modified at the global scope,
|
||||||
even when \fBdeclare\fP is executed in a shell function.
|
even when \fBdeclare\fP is executed in a shell function.
|
||||||
It is ignored in all other cases.
|
It is ignored in all other cases.
|
||||||
|
The
|
||||||
|
.B \-I
|
||||||
|
option causes local variables to inherit the attributes
|
||||||
|
(except the \fInameref\fP attribute)
|
||||||
|
and value of any existing variable with the same
|
||||||
|
\fIname\fP at a surrounding scope.
|
||||||
|
If there is no existing variable, the local variable is initially unset.
|
||||||
The following options can
|
The following options can
|
||||||
be used to restrict output to variables with the specified attribute or
|
be used to restrict output to variables with the specified attribute or
|
||||||
to give variables attributes:
|
to give variables attributes:
|
||||||
|
|||||||
+7
-1
@@ -4142,7 +4142,7 @@ zero if @var{command} is found, and non-zero if not.
|
|||||||
@item declare
|
@item declare
|
||||||
@btindex declare
|
@btindex declare
|
||||||
@example
|
@example
|
||||||
declare [-aAfFgilnrtux] [-p] [@var{name}[=@var{value}] @dots{}]
|
declare [-aAfFgiIlnrtux] [-p] [@var{name}[=@var{value}] @dots{}]
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Declare variables and give them attributes. If no @var{name}s
|
Declare variables and give them attributes. If no @var{name}s
|
||||||
@@ -4171,6 +4171,12 @@ The @option{-g} option forces variables to be created or modified at
|
|||||||
the global scope, even when @code{declare} is executed in a shell function.
|
the global scope, even when @code{declare} is executed in a shell function.
|
||||||
It is ignored in all other cases.
|
It is ignored in all other cases.
|
||||||
|
|
||||||
|
The @option{-I} option causes local variables to inherit the attributes
|
||||||
|
(except the @var{nameref} attribute)
|
||||||
|
and value of any existing variable with the same
|
||||||
|
@var{name} at a surrounding scope.
|
||||||
|
If there is no existing variable, the local variable is initially unset.
|
||||||
|
|
||||||
The following options can be used to restrict output to variables with
|
The following options can be used to restrict output to variables with
|
||||||
the specified attributes or to give variables attributes:
|
the specified attributes or to give variables attributes:
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -2,10 +2,10 @@
|
|||||||
Copyright (C) 1988-2020 Free Software Foundation, Inc.
|
Copyright (C) 1988-2020 Free Software Foundation, Inc.
|
||||||
@end ignore
|
@end ignore
|
||||||
|
|
||||||
@set LASTCHANGE Wed Jan 29 13:59:06 EST 2020
|
@set LASTCHANGE Tue Mar 17 18:27:12 EDT 2020
|
||||||
|
|
||||||
@set EDITION 5.0
|
@set EDITION 5.0
|
||||||
@set VERSION 5.0
|
@set VERSION 5.0
|
||||||
|
|
||||||
@set UPDATED 29 January 2020
|
@set UPDATED 17 March 2020
|
||||||
@set UPDATED-MONTH January 2020
|
@set UPDATED-MONTH March 2020
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ accept_builtin (list)
|
|||||||
if (tmoutarg)
|
if (tmoutarg)
|
||||||
{
|
{
|
||||||
long ival, uval;
|
long ival, uval;
|
||||||
opt = uconvert (tmoutarg, &ival, &uval);
|
opt = uconvert (tmoutarg, &ival, &uval, (char **)0);
|
||||||
if (opt == 0 || ival < 0 || uval < 0)
|
if (opt == 0 || ival < 0 || uval < 0)
|
||||||
{
|
{
|
||||||
builtin_error ("%s: invalid timeout specification", tmoutarg);
|
builtin_error ("%s: invalid timeout specification", tmoutarg);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
/* See Makefile for compilation details. */
|
/* See Makefile for compilation details. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (C) 1999-2009 Free Software Foundation, Inc.
|
Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GNU Bash.
|
This file is part of GNU Bash.
|
||||||
Bash is free software: you can redistribute it and/or modify
|
Bash is free software: you can redistribute it and/or modify
|
||||||
@@ -39,15 +39,14 @@ basename_builtin (list)
|
|||||||
int slen, sufflen, off;
|
int slen, sufflen, off;
|
||||||
char *string, *suffix, *fn;
|
char *string, *suffix, *fn;
|
||||||
|
|
||||||
|
if (no_options (list))
|
||||||
|
return (EX_USAGE);
|
||||||
|
list = loptend;
|
||||||
if (list == 0)
|
if (list == 0)
|
||||||
{
|
{
|
||||||
builtin_usage ();
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (no_options (list))
|
|
||||||
return (EX_USAGE);
|
|
||||||
list = loptend;
|
|
||||||
|
|
||||||
string = list->word->word;
|
string = list->word->word;
|
||||||
suffix = (char *)NULL;
|
suffix = (char *)NULL;
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include "builtins.h"
|
#include "builtins.h"
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "bashgetopt.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
strftime_builtin (list)
|
strftime_builtin (list)
|
||||||
@@ -46,15 +47,16 @@ strftime_builtin (list)
|
|||||||
int n;
|
int n;
|
||||||
intmax_t i;
|
intmax_t i;
|
||||||
|
|
||||||
|
if (no_options (list))
|
||||||
|
return (EX_USAGE);
|
||||||
|
list = loptend;
|
||||||
|
|
||||||
if (list == 0)
|
if (list == 0)
|
||||||
{
|
{
|
||||||
builtin_usage ();
|
builtin_usage ();
|
||||||
return (EX_USAGE);
|
return (EX_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (no_options (list))
|
|
||||||
return (EX_USAGE);
|
|
||||||
|
|
||||||
format = list->word->word;
|
format = list->word->word;
|
||||||
if (format == 0 || *format == 0)
|
if (format == 0 || *format == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-2
@@ -1606,8 +1606,7 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
|||||||
if (should_redir_stdin && stdin_redir == 0)
|
if (should_redir_stdin && stdin_redir == 0)
|
||||||
async_redirect_stdin ();
|
async_redirect_stdin ();
|
||||||
|
|
||||||
#if 0
|
#if 0 /* XXX - TAG:bash-5.1 */
|
||||||
/* XXX - TAG:bash-5.1 */
|
|
||||||
if (user_subshell && command->type == cm_subshell)
|
if (user_subshell && command->type == cm_subshell)
|
||||||
optimize_subshell_command (command->value.Subshell->command);
|
optimize_subshell_command (command->value.Subshell->command);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4265,14 +4265,9 @@ notify_of_job_status ()
|
|||||||
substitution, so don't print anything.
|
substitution, so don't print anything.
|
||||||
Otherwise, if the shell is not interactive, POSIX says that `jobs'
|
Otherwise, if the shell is not interactive, POSIX says that `jobs'
|
||||||
is the only way to notify of job status. */
|
is the only way to notify of job status. */
|
||||||
#if 1
|
|
||||||
if ((job_control == 0 && interactive_shell) ||
|
|
||||||
(startup_state == 2 && (subshell_environment & SUBSHELL_COMSUB)))
|
|
||||||
#else /* TAG:bash-5.1 */
|
|
||||||
if ((job_control == 0 && interactive_shell) ||
|
if ((job_control == 0 && interactive_shell) ||
|
||||||
(startup_state == 2 && (subshell_environment & SUBSHELL_COMSUB)) ||
|
(startup_state == 2 && (subshell_environment & SUBSHELL_COMSUB)) ||
|
||||||
(startup_state == 2 && posixly_correct && (subshell_environment & SUBSHELL_COMSUB) == 0))
|
(startup_state == 2 && posixly_correct && (subshell_environment & SUBSHELL_COMSUB) == 0))
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
/* POSIX.2 compatibility: if the shell is not interactive,
|
/* POSIX.2 compatibility: if the shell is not interactive,
|
||||||
hang onto the job corresponding to the last asynchronous
|
hang onto the job corresponding to the last asynchronous
|
||||||
|
|||||||
@@ -262,6 +262,13 @@ rl_unbind_function_in_map (rl_command_func_t *func, Keymap map)
|
|||||||
map[i].function = (rl_command_func_t *)NULL;
|
map[i].function = (rl_command_func_t *)NULL;
|
||||||
rval = 1;
|
rval = 1;
|
||||||
}
|
}
|
||||||
|
else if (map[i].type == ISKMAP) /* TAG:readline-8.1 */
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
r = rl_unbind_function_in_map (func, FUNCTION_TO_KEYMAP (map, i));
|
||||||
|
if (r == 1)
|
||||||
|
rval = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-7
@@ -507,6 +507,12 @@ histfile_restore (const char *backup, const char *orig)
|
|||||||
return (history_rename (backup, orig));
|
return (history_rename (backup, orig));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Should we call chown, based on whether finfo and nfinfo describe different
|
||||||
|
files with different owners? */
|
||||||
|
|
||||||
|
#define SHOULD_CHOWN(finfo, nfinfo) \
|
||||||
|
(finfo.st_uid != nfinfo.st_uid || finfo.st_gid != nfinfo.st_gid)
|
||||||
|
|
||||||
/* Truncate the history file FNAME, leaving only LINES trailing lines.
|
/* Truncate the history file FNAME, leaving only LINES trailing lines.
|
||||||
If FNAME is NULL, then use ~/.history. Writes a new file and renames
|
If FNAME is NULL, then use ~/.history. Writes a new file and renames
|
||||||
it to the original name. Returns 0 on success, errno on failure. */
|
it to the original name. Returns 0 on success, errno on failure. */
|
||||||
@@ -515,7 +521,7 @@ history_truncate_file (const char *fname, int lines)
|
|||||||
{
|
{
|
||||||
char *buffer, *filename, *tempname, *bp, *bp1; /* bp1 == bp+1 */
|
char *buffer, *filename, *tempname, *bp, *bp1; /* bp1 == bp+1 */
|
||||||
int file, chars_read, rv, orig_lines, exists, r;
|
int file, chars_read, rv, orig_lines, exists, r;
|
||||||
struct stat finfo;
|
struct stat finfo, nfinfo;
|
||||||
size_t file_size;
|
size_t file_size;
|
||||||
|
|
||||||
history_lines_written_to_file = 0;
|
history_lines_written_to_file = 0;
|
||||||
@@ -536,6 +542,9 @@ history_truncate_file (const char *fname, int lines)
|
|||||||
}
|
}
|
||||||
exists = 1;
|
exists = 1;
|
||||||
|
|
||||||
|
nfinfo.st_uid = finfo.st_uid;
|
||||||
|
nfinfo.st_gid = finfo.st_gid;
|
||||||
|
|
||||||
if (S_ISREG (finfo.st_mode) == 0)
|
if (S_ISREG (finfo.st_mode) == 0)
|
||||||
{
|
{
|
||||||
close (file);
|
close (file);
|
||||||
@@ -624,6 +633,9 @@ history_truncate_file (const char *fname, int lines)
|
|||||||
if (write (file, bp, chars_read - (bp - buffer)) < 0)
|
if (write (file, bp, chars_read - (bp - buffer)) < 0)
|
||||||
rv = errno;
|
rv = errno;
|
||||||
|
|
||||||
|
if (fstat (file, &nfinfo) < 0 && rv == 0)
|
||||||
|
rv = errno;
|
||||||
|
|
||||||
if (close (file) < 0 && rv == 0)
|
if (close (file) < 0 && rv == 0)
|
||||||
rv = errno;
|
rv = errno;
|
||||||
}
|
}
|
||||||
@@ -651,7 +663,7 @@ history_truncate_file (const char *fname, int lines)
|
|||||||
user is running this, it's a no-op. If the shell is running after sudo
|
user is running this, it's a no-op. If the shell is running after sudo
|
||||||
with a shared history file, we don't want to leave the history file
|
with a shared history file, we don't want to leave the history file
|
||||||
owned by root. */
|
owned by root. */
|
||||||
if (rv == 0 && exists)
|
if (rv == 0 && exists && SHOULD_CHOWN (finfo, nfinfo))
|
||||||
r = chown (filename, finfo.st_uid, finfo.st_gid);
|
r = chown (filename, finfo.st_uid, finfo.st_gid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -670,7 +682,7 @@ history_do_write (const char *filename, int nelements, int overwrite)
|
|||||||
register int i;
|
register int i;
|
||||||
char *output, *tempname, *histname;
|
char *output, *tempname, *histname;
|
||||||
int file, mode, rv, exists;
|
int file, mode, rv, exists;
|
||||||
struct stat finfo;
|
struct stat finfo, nfinfo;
|
||||||
#ifdef HISTORY_USE_MMAP
|
#ifdef HISTORY_USE_MMAP
|
||||||
size_t cursize;
|
size_t cursize;
|
||||||
|
|
||||||
@@ -715,15 +727,11 @@ history_do_write (const char *filename, int nelements, int overwrite)
|
|||||||
the_history = history_list ();
|
the_history = history_list ();
|
||||||
/* Calculate the total number of bytes to write. */
|
/* Calculate the total number of bytes to write. */
|
||||||
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
|
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
|
||||||
#if 0
|
|
||||||
buffer_size += 2 + HISTENT_BYTES (the_history[i]);
|
|
||||||
#else
|
|
||||||
{
|
{
|
||||||
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
|
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
|
||||||
buffer_size += strlen (the_history[i]->timestamp) + 1;
|
buffer_size += strlen (the_history[i]->timestamp) + 1;
|
||||||
buffer_size += strlen (the_history[i]->line) + 1;
|
buffer_size += strlen (the_history[i]->line) + 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Allocate the buffer, and fill it. */
|
/* Allocate the buffer, and fill it. */
|
||||||
#ifdef HISTORY_USE_MMAP
|
#ifdef HISTORY_USE_MMAP
|
||||||
|
|||||||
@@ -7448,8 +7448,7 @@ verify_substring_values (v, value, substr, vtype, e1p, e2p)
|
|||||||
from end of positional parameters? */
|
from end of positional parameters? */
|
||||||
#if 1
|
#if 1
|
||||||
if ((vtype == VT_ARRAYVAR || vtype == VT_POSPARMS) && *e2p < 0)
|
if ((vtype == VT_ARRAYVAR || vtype == VT_POSPARMS) && *e2p < 0)
|
||||||
#else
|
#else /* XXX - TAG: bash-5.1 */
|
||||||
/* XXX - TAG: bash-5.1 */
|
|
||||||
if (vtype == VT_ARRAYVAR && *e2p < 0)
|
if (vtype == VT_ARRAYVAR && *e2p < 0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@@ -11517,14 +11516,20 @@ shell_expand_word_list (tlist, eflags)
|
|||||||
opts[opti++] = 'A';
|
opts[opti++] = 'A';
|
||||||
}
|
}
|
||||||
else if (tlist->word->flags & W_ASSIGNASSOC)
|
else if (tlist->word->flags & W_ASSIGNASSOC)
|
||||||
opts[opti++] = 'A';
|
{
|
||||||
|
opts[opti++] = 'A';
|
||||||
|
opts[opti++] = 'I';
|
||||||
|
}
|
||||||
else if ((tlist->word->flags & (W_ASSIGNARRAY|W_ASSNGLOBAL)) == (W_ASSIGNARRAY|W_ASSNGLOBAL))
|
else if ((tlist->word->flags & (W_ASSIGNARRAY|W_ASSNGLOBAL)) == (W_ASSIGNARRAY|W_ASSNGLOBAL))
|
||||||
{
|
{
|
||||||
opts[opti++] = 'g';
|
opts[opti++] = 'g';
|
||||||
opts[opti++] = 'a';
|
opts[opti++] = 'a';
|
||||||
}
|
}
|
||||||
else if (tlist->word->flags & W_ASSIGNARRAY)
|
else if (tlist->word->flags & W_ASSIGNARRAY)
|
||||||
opts[opti++] = 'a';
|
{
|
||||||
|
opts[opti++] = 'a';
|
||||||
|
opts[opti++] = 'I';
|
||||||
|
}
|
||||||
else if (tlist->word->flags & W_ASSNGLOBAL)
|
else if (tlist->word->flags & W_ASSNGLOBAL)
|
||||||
opts[opti++] = 'g';
|
opts[opti++] = 'g';
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
#define ASS_NOEXPAND 0x0080 /* don't expand associative array subscripts */
|
#define ASS_NOEXPAND 0x0080 /* don't expand associative array subscripts */
|
||||||
#define ASS_NOEVAL 0x0100 /* don't evaluate value as expression */
|
#define ASS_NOEVAL 0x0100 /* don't evaluate value as expression */
|
||||||
#define ASS_NOLONGJMP 0x0200 /* don't longjmp on fatal assignment error */
|
#define ASS_NOLONGJMP 0x0200 /* don't longjmp on fatal assignment error */
|
||||||
|
#define ASS_NOINVIS 0x0400 /* don't resolve local invisible variables */
|
||||||
|
|
||||||
/* Flags for the string extraction functions. */
|
/* Flags for the string extraction functions. */
|
||||||
#define SX_NOALLOC 0x0001 /* just skip; don't return substring */
|
#define SX_NOALLOC 0x0001 /* just skip; don't return substring */
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||||
THIS_SH=$BUILD_DIR/bash
|
THIS_SH=$BUILD_DIR/bash
|
||||||
PATH=$PATH:$BUILD_DIR
|
PATH=$PATH:$BUILD_DIR
|
||||||
|
|
||||||
|
|||||||
Executable
+13
@@ -0,0 +1,13 @@
|
|||||||
|
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||||
|
THIS_SH="$BUILD_DIR/bash -x"
|
||||||
|
PATH=$PATH:$BUILD_DIR
|
||||||
|
|
||||||
|
export THIS_SH PATH BUILD_DIR
|
||||||
|
|
||||||
|
: ${TMPDIR:=/tmp}
|
||||||
|
export TMPDIR
|
||||||
|
|
||||||
|
export BASH_TSTOUT=/tmp/xx
|
||||||
|
rm -f ${BASH_TSTOUT}
|
||||||
|
|
||||||
|
/bin/sh -x "$@"
|
||||||
+18
-16
@@ -40,33 +40,35 @@ async list wait-for-background-pids
|
|||||||
async list wait for child
|
async list wait for child
|
||||||
forked
|
forked
|
||||||
wait-when-no-children
|
wait-when-no-children
|
||||||
|
posix jobs output
|
||||||
|
[1]+ Done sleep 1
|
||||||
wait-for-job
|
wait-for-job
|
||||||
./jobs.tests: line 79: wait: %2: no such job
|
./jobs.tests: line 82: wait: %2: no such job
|
||||||
127
|
127
|
||||||
async list wait-for-job
|
async list wait-for-job
|
||||||
forked
|
forked
|
||||||
fg-bg 1
|
fg-bg 1
|
||||||
sleep 5
|
sleep 2
|
||||||
fg-bg 2
|
fg-bg 2
|
||||||
sleep 5
|
sleep 2
|
||||||
fg-bg 3
|
fg-bg 3
|
||||||
sleep 5
|
sleep 2
|
||||||
fg-bg 4
|
fg-bg 4
|
||||||
sleep 5
|
sleep 2
|
||||||
fg-bg 5
|
fg-bg 5
|
||||||
./jobs.tests: line 106: fg: %2: no such job
|
./jobs.tests: line 109: fg: %2: no such job
|
||||||
./jobs.tests: line 107: bg: job 1 already in background
|
./jobs.tests: line 110: bg: job 1 already in background
|
||||||
fg-bg 6
|
fg-bg 6
|
||||||
./jobs.tests: line 114: fg: -s: invalid option
|
./jobs.tests: line 117: fg: -s: invalid option
|
||||||
fg: usage: fg [job_spec]
|
fg: usage: fg [job_spec]
|
||||||
./jobs.tests: line 115: bg: -s: invalid option
|
./jobs.tests: line 118: bg: -s: invalid option
|
||||||
bg: usage: bg [job_spec ...]
|
bg: usage: bg [job_spec ...]
|
||||||
./jobs.tests: line 120: disown: -s: invalid option
|
./jobs.tests: line 123: disown: -s: invalid option
|
||||||
disown: usage: disown [-h] [-ar] [jobspec ... | pid ...]
|
disown: usage: disown [-h] [-ar] [jobspec ... | pid ...]
|
||||||
./jobs.tests: line 124: disown: %1: no such job
|
./jobs.tests: line 127: disown: %1: no such job
|
||||||
./jobs.tests: line 127: disown: %2: no such job
|
./jobs.tests: line 130: disown: %2: no such job
|
||||||
wait-for-non-child
|
wait-for-non-child
|
||||||
./jobs.tests: line 130: wait: pid 1 is not a child of this shell
|
./jobs.tests: line 133: wait: pid 1 is not a child of this shell
|
||||||
127
|
127
|
||||||
3 -- 1 2 3 -- 1 - 2 - 3
|
3 -- 1 2 3 -- 1 - 2 - 3
|
||||||
[1] Running sleep 300 &
|
[1] Running sleep 300 &
|
||||||
@@ -76,8 +78,8 @@ running jobs:
|
|||||||
[1] Running sleep 300 &
|
[1] Running sleep 300 &
|
||||||
[2]- Running sleep 350 &
|
[2]- Running sleep 350 &
|
||||||
[3]+ Running sleep 400 &
|
[3]+ Running sleep 400 &
|
||||||
./jobs.tests: line 147: kill: %4: no such job
|
./jobs.tests: line 150: kill: %4: no such job
|
||||||
./jobs.tests: line 149: jobs: %4: no such job
|
./jobs.tests: line 152: jobs: %4: no such job
|
||||||
current job:
|
current job:
|
||||||
[3]+ Running sleep 400 &
|
[3]+ Running sleep 400 &
|
||||||
previous job:
|
previous job:
|
||||||
@@ -105,5 +107,5 @@ after kill -STOP, backgrounding %3:
|
|||||||
killing...
|
killing...
|
||||||
done
|
done
|
||||||
after KILL -STOP, foregrounding %1
|
after KILL -STOP, foregrounding %1
|
||||||
sleep 10
|
sleep 4
|
||||||
done
|
done
|
||||||
|
|||||||
+20
-17
@@ -49,7 +49,7 @@ wait # make sure we reap the processes while stderr is still redirected
|
|||||||
exec 2>&5
|
exec 2>&5
|
||||||
|
|
||||||
echo wait-for-pid
|
echo wait-for-pid
|
||||||
sleep 10 &
|
sleep 4 &
|
||||||
wait $!
|
wait $!
|
||||||
|
|
||||||
echo wait-errors
|
echo wait-errors
|
||||||
@@ -57,52 +57,55 @@ wait 1-1
|
|||||||
wait -- -4
|
wait -- -4
|
||||||
|
|
||||||
echo wait-for-background-pids
|
echo wait-for-background-pids
|
||||||
sleep 5 &
|
sleep 2 &
|
||||||
sleep 8 &
|
sleep 4 &
|
||||||
wait
|
wait
|
||||||
|
|
||||||
echo async list wait-for-background-pids
|
echo async list wait-for-background-pids
|
||||||
sleep 5 & sleep 8 &
|
sleep 2 & sleep 4 &
|
||||||
wait
|
wait
|
||||||
|
|
||||||
echo async list wait for child
|
echo async list wait for child
|
||||||
sleep 5 & echo forked
|
sleep 2 & echo forked
|
||||||
wait
|
wait
|
||||||
|
|
||||||
echo wait-when-no-children
|
echo wait-when-no-children
|
||||||
wait
|
wait
|
||||||
|
|
||||||
|
echo posix jobs output
|
||||||
|
${THIS_SH} -o posix -c 'sleep 1 & P=$! ; sleep 2; jobs; wait'
|
||||||
|
|
||||||
set -m
|
set -m
|
||||||
|
|
||||||
echo wait-for-job
|
echo wait-for-job
|
||||||
sleep 5 &
|
sleep 3 &
|
||||||
wait %2 # this should be a no-such-job error
|
wait %2 # this should be a no-such-job error
|
||||||
echo $?
|
echo $?
|
||||||
wait %1
|
wait %1
|
||||||
|
|
||||||
echo async list wait-for-job
|
echo async list wait-for-job
|
||||||
sleep 5 & echo forked
|
sleep 2 & echo forked
|
||||||
wait %1
|
wait %1
|
||||||
|
|
||||||
echo fg-bg 1
|
echo fg-bg 1
|
||||||
sleep 5 &
|
sleep 2 &
|
||||||
%1
|
%1
|
||||||
|
|
||||||
echo fg-bg 2
|
echo fg-bg 2
|
||||||
sleep 5 &
|
sleep 2 &
|
||||||
fg %%
|
fg %%
|
||||||
|
|
||||||
echo fg-bg 3
|
echo fg-bg 3
|
||||||
sleep 5 &
|
sleep 2 &
|
||||||
fg %s
|
fg %s
|
||||||
|
|
||||||
echo fg-bg 4
|
echo fg-bg 4
|
||||||
sleep 5 &
|
sleep 2 &
|
||||||
fg %?ee
|
fg %?ee
|
||||||
|
|
||||||
# these next two are error cases
|
# these next two are error cases
|
||||||
echo fg-bg 5
|
echo fg-bg 5
|
||||||
sleep 15 &
|
sleep 2 &
|
||||||
fg %2 # this should be a no-such-job error
|
fg %2 # this should be a no-such-job error
|
||||||
bg %1 # this should be a `bg background job?' error
|
bg %1 # this should be a `bg background job?' error
|
||||||
wait
|
wait
|
||||||
@@ -110,7 +113,7 @@ wait
|
|||||||
# these may someday mean to start the jobs, but not print the line
|
# these may someday mean to start the jobs, but not print the line
|
||||||
# describing the status, but for now they are errors
|
# describing the status, but for now they are errors
|
||||||
echo fg-bg 6
|
echo fg-bg 6
|
||||||
sleep 5 &
|
sleep 2 &
|
||||||
fg -s %1
|
fg -s %1
|
||||||
bg -s %1
|
bg -s %1
|
||||||
wait
|
wait
|
||||||
@@ -153,7 +156,7 @@ echo previous job:
|
|||||||
jobs %-
|
jobs %-
|
||||||
|
|
||||||
kill -STOP %2
|
kill -STOP %2
|
||||||
sleep 5 # give time for the shell to get the stop notification
|
sleep 3 # give time for the shell to get the stop notification
|
||||||
echo after kill -STOP
|
echo after kill -STOP
|
||||||
echo running jobs:
|
echo running jobs:
|
||||||
jobs -r
|
jobs -r
|
||||||
@@ -177,7 +180,7 @@ echo stopped jobs:
|
|||||||
jobs -s
|
jobs -s
|
||||||
|
|
||||||
kill -STOP %3
|
kill -STOP %3
|
||||||
sleep 5 # give time for the shell to get the stop notification
|
sleep 3 # give time for the shell to get the stop notification
|
||||||
echo after kill -STOP, backgrounding %3:
|
echo after kill -STOP, backgrounding %3:
|
||||||
bg %3
|
bg %3
|
||||||
|
|
||||||
@@ -195,9 +198,9 @@ echo done
|
|||||||
|
|
||||||
exec 2>&5
|
exec 2>&5
|
||||||
|
|
||||||
sleep 10 &
|
sleep 4 &
|
||||||
kill -STOP %1
|
kill -STOP %1
|
||||||
sleep 5 # give time for the shell to get the stop notification
|
sleep 2 # give time for the shell to get the stop notification
|
||||||
echo after KILL -STOP, foregrounding %1
|
echo after KILL -STOP, foregrounding %1
|
||||||
fg %1
|
fg %1
|
||||||
|
|
||||||
|
|||||||
@@ -294,3 +294,5 @@ xtrace off
|
|||||||
--
|
--
|
||||||
./shopt.tests: line 106: shopt: xyz1: invalid shell option name
|
./shopt.tests: line 106: shopt: xyz1: invalid shell option name
|
||||||
./shopt.tests: line 107: shopt: xyz1: invalid option name
|
./shopt.tests: line 107: shopt: xyz1: invalid option name
|
||||||
|
expand_aliases on
|
||||||
|
expand_aliases on
|
||||||
|
|||||||
@@ -107,3 +107,7 @@ shopt -p xyz1
|
|||||||
shopt -o -p xyz1
|
shopt -o -p xyz1
|
||||||
|
|
||||||
${THIS_SH} ./shopt1.sub
|
${THIS_SH} ./shopt1.sub
|
||||||
|
|
||||||
|
# test whether or not temporary variable assignments that manipulate posix
|
||||||
|
# mode restore the previous state or the default non-posix state
|
||||||
|
${THIS_SH} -c 'shopt -s expand_aliases ; shopt expand_aliases ; POSIXLY_CORRECT=y true ; shopt expand_aliases'
|
||||||
|
|||||||
+12
-8
@@ -2951,14 +2951,17 @@ make_new_array_variable (name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SHELL_VAR *
|
SHELL_VAR *
|
||||||
make_local_array_variable (name, assoc_ok)
|
make_local_array_variable (name, flags)
|
||||||
char *name;
|
char *name;
|
||||||
int assoc_ok;
|
int flags;
|
||||||
{
|
{
|
||||||
SHELL_VAR *var;
|
SHELL_VAR *var;
|
||||||
ARRAY *array;
|
ARRAY *array;
|
||||||
|
int assoc_ok;
|
||||||
|
|
||||||
var = make_local_variable (name, 0); /* XXX for now */
|
assoc_ok = flags & MKLOC_ASSOCOK;
|
||||||
|
|
||||||
|
var = make_local_variable (name, flags & MKLOC_INHERIT); /* XXX for now */
|
||||||
/* If ASSOC_OK is non-zero, assume that we are ok with letting an assoc
|
/* If ASSOC_OK is non-zero, assume that we are ok with letting an assoc
|
||||||
variable return to the caller without converting it. The caller will
|
variable return to the caller without converting it. The caller will
|
||||||
either flag an error or do the conversion itself. */
|
either flag an error or do the conversion itself. */
|
||||||
@@ -3004,14 +3007,17 @@ make_new_assoc_variable (name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SHELL_VAR *
|
SHELL_VAR *
|
||||||
make_local_assoc_variable (name, array_ok)
|
make_local_assoc_variable (name, flags)
|
||||||
char *name;
|
char *name;
|
||||||
int array_ok;
|
int flags;
|
||||||
{
|
{
|
||||||
SHELL_VAR *var;
|
SHELL_VAR *var;
|
||||||
HASH_TABLE *hash;
|
HASH_TABLE *hash;
|
||||||
|
int array_ok;
|
||||||
|
|
||||||
var = make_local_variable (name, 0); /* XXX for now */
|
array_ok = flags & MKLOC_ARRAYOK;
|
||||||
|
|
||||||
|
var = make_local_variable (name, flags & MKLOC_INHERIT); /* XXX for now */
|
||||||
/* If ARRAY_OK is non-zero, assume that we are ok with letting an array
|
/* If ARRAY_OK is non-zero, assume that we are ok with letting an array
|
||||||
variable return to the caller without converting it. The caller will
|
variable return to the caller without converting it. The caller will
|
||||||
either flag an error or do the conversion itself. */
|
either flag an error or do the conversion itself. */
|
||||||
@@ -3791,10 +3797,8 @@ assign_in_env (word, flags)
|
|||||||
|
|
||||||
if (flags)
|
if (flags)
|
||||||
{
|
{
|
||||||
#if 0 /* TAG:bash-5.1 from Martijn Dekker */
|
|
||||||
if (STREQ (newname, "POSIXLY_CORRECT") || STREQ (newname, "POSIX_PEDANDTIC"))
|
if (STREQ (newname, "POSIXLY_CORRECT") || STREQ (newname, "POSIX_PEDANDTIC"))
|
||||||
save_posix_options (); /* XXX one level of saving right now */
|
save_posix_options (); /* XXX one level of saving right now */
|
||||||
#endif
|
|
||||||
stupidly_hack_special_variables (newname);
|
stupidly_hack_special_variables (newname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -221,8 +221,10 @@ typedef struct _vlist {
|
|||||||
|
|
||||||
#define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
|
#define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
|
||||||
|
|
||||||
/* Flag values for make_local_variable */
|
/* Flag values for make_local_variable and its array counterparts */
|
||||||
#define MKLOC_INHERIT 0x01
|
#define MKLOC_ASSOCOK 0x01
|
||||||
|
#define MKLOC_ARRAYOK 0x02
|
||||||
|
#define MKLOC_INHERIT 0x04
|
||||||
|
|
||||||
/* Special value for nameref with invalid value for creation or assignment */
|
/* Special value for nameref with invalid value for creation or assignment */
|
||||||
extern SHELL_VAR nameref_invalid_value;
|
extern SHELL_VAR nameref_invalid_value;
|
||||||
|
|||||||
Reference in New Issue
Block a user