mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 15:43:18 +02:00
commit bash-20151023 snapshot
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
This document details the changes between this version, bash-4.4-beta, and
|
||||
the previous version, bash-4.4-alpha.
|
||||
|
||||
1. Change to Bash
|
||||
1. Changes to Bash
|
||||
|
||||
a. Fixed two bugs that caused out-of-bounds reads when skipping over assignment
|
||||
statements while finding the word on which to perform programmable
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
This document details the changes between this version, bash-4.4-beta, and
|
||||
the previous version, bash-4.4-alpha.
|
||||
|
||||
1. Change to Bash
|
||||
1. Changes to Bash
|
||||
|
||||
a. Fixed two bugs that caused out-of-bounds reads when skipping over assignment
|
||||
statements while finding the word on which to perform programmable
|
||||
|
||||
+87
-3
@@ -9754,12 +9754,13 @@ variables.c
|
||||
10/13
|
||||
-----
|
||||
variables.c
|
||||
- initialize_shell_variables: add call to sv_shcompat, so BASH_COMPAT can
|
||||
be set in the initial environment
|
||||
- initialize_shell_variables: add call to sv_shcompat, so BASH_COMPAT
|
||||
can be set in the initial environment
|
||||
|
||||
execute_cmd.c
|
||||
- execute_function: set loop_level to 0 only if shell_compatibility_level
|
||||
is greater than bash-4.3; this was kind of an incompatible change
|
||||
is greater than bash-4.3; this was kind of an incompatible change.
|
||||
Report from Carlos Pita <carolosjosepita@gmail.com>
|
||||
|
||||
COMPAT,doc/{bash.1,bashref.texi}
|
||||
- compat43: added loop_level changes to description
|
||||
@@ -9782,3 +9783,86 @@ subst.c
|
||||
on the assignment string, so spaces in the assignment survive word
|
||||
splitting. Fixes bug reported by isabella parakiss
|
||||
<izaberina@gmail.com>
|
||||
|
||||
10/20
|
||||
-----
|
||||
doc/{bash.1,bashref.texi}
|
||||
- word splitting: make sure that newline is listed as one of the IFS
|
||||
whitespace characters. Fixes omission reported by ziyunfei
|
||||
<446240525@qq.com>
|
||||
|
||||
lib/readline/histfile.c
|
||||
- history_do_write: make sure that we only create and use the tempfile if
|
||||
the history file exists and is a regular file. Reported several times,
|
||||
most recent check the result of a report from <marko.teiste@gmail.com>
|
||||
|
||||
10/22
|
||||
-----
|
||||
jobs.c
|
||||
- delete_all_jobs: if running_only == 0, we are eventually going to
|
||||
clear the bgpids list, so don't bother to add pids to it in
|
||||
delete_job (call with DEL_NOBGPID flag if running_only == 0)
|
||||
|
||||
10/24
|
||||
-----
|
||||
jobs.[ch]
|
||||
- bgpids: new implementation from a patch from John Fremlin
|
||||
<john@fb.com>, uses an array for the list of the last CHILD_MAX
|
||||
terminated background pids, and a separate hash table to search it.
|
||||
The storage can be freed as a unit, and the size of the hash table
|
||||
(currently 4096) is independent of the size of the bgpids table
|
||||
|
||||
subst.c
|
||||
- inherit_errexit: new variable to control whether or not command
|
||||
substitution inherits the -e (errexit) option. Disabled by default
|
||||
|
||||
general.c
|
||||
- posix_initialize: set inherit_errexit = 1 when Posix mode is enabled
|
||||
|
||||
builtins/shopt.def
|
||||
- inherit_errexit: new shell option, tracks value of inherit_errexit,
|
||||
allows command substitution to inherit the setting of errexit without
|
||||
posix mode. From a request and patch submitted by Christoph Gysin
|
||||
<christoph.gysin@gmail.com>
|
||||
|
||||
{version,version2}.c
|
||||
- use #if HAVE_SNPRINTF instead of #if defined in case configure
|
||||
decides to #define it to 0. Fixes problem reported by Klaus Ziegler
|
||||
<klausz@haus-gisela.de>
|
||||
|
||||
configure.ac
|
||||
- when checking for sys/resource.h, make sure to include <sys/time.h>
|
||||
for the benefit of both old systems that require it and new versions
|
||||
of autoconf that require a header file to compile to report its
|
||||
presence. Reported by Klaus Ziegler <klausz@haus-gisela.de>
|
||||
|
||||
10/26
|
||||
-----
|
||||
subst.h
|
||||
- SD_ARITHEXP: new flag value for skip_to_delim, supports parsing
|
||||
arithmetic expressions in parameter expansions
|
||||
|
||||
subst.c
|
||||
- skip_to_delim: handle SD_ARITHEXP flag by skipping parentheses for
|
||||
subexpressions and allowing ?: expression to not terminate an
|
||||
arithmetic expression delimited by `:'
|
||||
- skiparith: just call skip_to_delim with the SD_ARITHEXP option and
|
||||
the right delimiter string and return the right result. Fixes bug
|
||||
reported by <grishalevit@gmail.com>
|
||||
|
||||
include/shmbchar.h
|
||||
- strip out everything except what is needed to support is_basic and
|
||||
similar functions, since the mbchar_t typedef apparently conflicts
|
||||
with some AIX-specific type definition. Problem reported by
|
||||
Michael Felt <aixtools@gmail.com>
|
||||
|
||||
10/27
|
||||
-----
|
||||
builtins/{set,ulimit}.def
|
||||
- {set,ulimit}_builtin: make sure that --help is treated the same as
|
||||
-? and prints a message and returns. Fixes bug reported by ziyunfei
|
||||
<446240525@qq.com>
|
||||
|
||||
builtins/*.def
|
||||
- make sure to consistently use builtin_help() instead of mix of that
|
||||
function and builtin_usage()
|
||||
|
||||
@@ -820,6 +820,7 @@ tests/arith3.sub f
|
||||
tests/arith4.sub f
|
||||
tests/arith5.sub f
|
||||
tests/arith6.sub f
|
||||
tests/arith7.sub f
|
||||
tests/array.tests f
|
||||
tests/array.right f
|
||||
tests/array1.sub f
|
||||
|
||||
+6
-1
@@ -1,4 +1,4 @@
|
||||
# Makefile for bash-4.4, version 4.17
|
||||
# Makefile for bash-4.4, version 4.18
|
||||
#
|
||||
# Copyright (C) 1996-2015 Free Software Foundation, Inc.
|
||||
|
||||
@@ -1077,6 +1077,7 @@ print_cmd.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h comman
|
||||
print_cmd.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
|
||||
print_cmd.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
|
||||
print_cmd.o: make_cmd.h subst.h sig.h pathnames.h externs.h
|
||||
print_cmd.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
print_cmd.o: ${GRAM_H} $(DEFSRC)/common.h
|
||||
redir.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/filecntl.h
|
||||
redir.o: ${BASHINCDIR}/memalloc.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
|
||||
@@ -1205,6 +1206,7 @@ pcomplete.o: ${BASHINCDIR}/stdc.h hashlib.h pcomplete.h shell.h syntax.h
|
||||
pcomplete.o: bashjmp.h command.h general.h xmalloc.h error.h variables.h arrayfunc.h conftypes.h quit.h
|
||||
pcomplete.o: unwind_prot.h dispose_cmd.h make_cmd.h subst.h sig.h pathnames.h
|
||||
pcomplete.o: externs.h ${BASHINCDIR}/maxpath.h execute_cmd.h
|
||||
pcomplete.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
pcomplete.o: ${DEFDIR}/builtext.h
|
||||
|
||||
# library support files
|
||||
@@ -1233,6 +1235,7 @@ bracecomp.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h
|
||||
bracecomp.o: array.h hashlib.h alias.h builtins.h
|
||||
bracecomp.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
|
||||
bracecomp.o: make_cmd.h subst.h sig.h pathnames.h externs.h
|
||||
bracecomp.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
|
||||
# library dependencies
|
||||
|
||||
@@ -1439,6 +1442,7 @@ builtins/printf.o: config.h ${BASHINCDIR}/memalloc.h bashjmp.h command.h error.h
|
||||
builtins/printf.o: general.h xmalloc.h quit.h dispose_cmd.h make_cmd.h subst.h
|
||||
builtins/printf.o: externs.h sig.h pathnames.h shell.h syntax.h unwind_prot.h
|
||||
builtins/printf.o: variables.h arrayfunc.h conftypes.h ${BASHINCDIR}/stdc.h $(DEFSRC)/bashgetopt.h
|
||||
builtins/printf.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
builtins/printf.o: ${BASHINCDIR}/chartypes.h
|
||||
builtins/pushd.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
|
||||
builtins/pushd.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
|
||||
@@ -1447,6 +1451,7 @@ builtins/pushd.o: $(DEFSRC)/common.h pathnames.h
|
||||
builtins/read.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
|
||||
builtins/read.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
|
||||
builtins/read.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h
|
||||
builtins/read.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
builtins/read.o: pathnames.h
|
||||
builtins/return.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
|
||||
builtins/return.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
|
||||
|
||||
@@ -531,6 +531,7 @@ printf.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/sig.h
|
||||
printf.o: ../pathnames.h $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h
|
||||
printf.o: $(topdir)/variables.h $(topdir)/conftypes.h $(BASHINCDIR)/stdc.h $(srcdir)/bashgetopt.h
|
||||
printf.o: $(topdir)/bashtypes.h ${srcdir}/common.h $(BASHINCDIR)/chartypes.h
|
||||
printf.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
printf.o: ../pathnames.h
|
||||
pushd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
pushd.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
@@ -545,6 +546,7 @@ read.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
read.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
read.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
read.o: $(BASHINCDIR)/shtty.h $(topdir)/sig.h
|
||||
read.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
read.o: $(topdir)/arrayfunc.h ../pathnames.h
|
||||
return.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
return.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
|
||||
@@ -183,6 +183,7 @@ unalias_builtin (list)
|
||||
case 'a':
|
||||
aflag = 1;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -298,6 +298,7 @@ cd_builtin (list)
|
||||
xattrflag = 1;
|
||||
break;
|
||||
#endif
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
@@ -487,6 +488,7 @@ pwd_builtin (list)
|
||||
case 'L':
|
||||
verbatim_pwd = 0;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -325,6 +325,7 @@ build_actions (list, flagp, actp, optp)
|
||||
case 'X':
|
||||
Xarg = list_optarg;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -224,6 +224,7 @@ declare_internal (list, local_var)
|
||||
flags_off |= att_capcase|att_lowercase;
|
||||
break;
|
||||
#endif /* CASEMOD_ATTRS */
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -151,6 +151,7 @@ enable_builtin (list)
|
||||
builtin_error (_("dynamic loading not available"));
|
||||
return (EX_USAGE);
|
||||
#endif /* HAVE_DLCLOSE */
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -119,6 +119,7 @@ exec_builtin (list)
|
||||
case 'a':
|
||||
argv0 = list_optarg;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -218,6 +218,7 @@ fc_builtin (list)
|
||||
ename = list_optarg;
|
||||
break;
|
||||
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -316,9 +316,12 @@ getopts_builtin (list)
|
||||
}
|
||||
|
||||
reset_internal_getopt ();
|
||||
if (internal_getopt (list, "") != -1)
|
||||
if ((ret = internal_getopt (list, "")) != -1)
|
||||
{
|
||||
builtin_usage ();
|
||||
if (ret == GETOPT_HELP)
|
||||
builtin_help ();
|
||||
else
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
@@ -115,6 +115,7 @@ hash_builtin (list)
|
||||
case 't':
|
||||
list_targets = 1;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -113,6 +113,7 @@ help_builtin (list)
|
||||
case 's':
|
||||
sflag = 1;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -141,6 +141,7 @@ history_builtin (list)
|
||||
flags |= PFLAG;
|
||||
#endif
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -118,6 +118,7 @@ jobs_builtin (list)
|
||||
state = JSTATE_STOPPED;
|
||||
break;
|
||||
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -330,6 +330,7 @@ mapfile_builtin (list)
|
||||
else
|
||||
nskip = intval;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -273,6 +273,7 @@ printf_builtin (list)
|
||||
return (EX_USAGE);
|
||||
}
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -317,6 +317,7 @@ read_builtin (list)
|
||||
case 'd':
|
||||
delim = *list_optarg;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -660,6 +660,7 @@ set_builtin (list)
|
||||
sh_invalidopt (s);
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
CASE_HELPOPT;
|
||||
case '?':
|
||||
builtin_usage ();
|
||||
return (list_optopt == '?' ? EXECUTION_SUCCESS : EX_USAGE);
|
||||
@@ -816,6 +817,7 @@ unset_builtin (list)
|
||||
case 'n':
|
||||
nameref = 1;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -160,6 +160,7 @@ set_or_show_attributes (list, attribute, nodefs)
|
||||
#endif
|
||||
case 'p':
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -90,6 +90,7 @@ extern int autocd;
|
||||
extern int glob_star;
|
||||
extern int glob_asciirange;
|
||||
extern int lastpipe_opt;
|
||||
extern int inherit_errexit;
|
||||
|
||||
#if defined (EXTENDED_GLOB)
|
||||
extern int extended_glob;
|
||||
@@ -196,6 +197,7 @@ static struct {
|
||||
{ "hostcomplete", &perform_hostname_completion, shopt_enable_hostname_completion },
|
||||
#endif
|
||||
{ "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL },
|
||||
{ "inherit_errexit", &inherit_errexit, (shopt_set_func_t *)NULL },
|
||||
{ "interactive_comments", &interactive_comments, set_shellopts_after_change },
|
||||
{ "lastpipe", &lastpipe_opt, (shopt_set_func_t *)NULL },
|
||||
#if defined (HISTORY)
|
||||
@@ -271,6 +273,7 @@ shopt_builtin (list)
|
||||
case 'p':
|
||||
flags |= PFLAG;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -89,6 +89,7 @@ suspend_builtin (list)
|
||||
case 'f':
|
||||
force++;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -119,6 +119,7 @@ trap_builtin (list)
|
||||
case 'p':
|
||||
display++;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -168,6 +168,7 @@ type_builtin (list)
|
||||
dflags |= (CDESC_PATH_ONLY|CDESC_FORCE_PATH);
|
||||
dflags &= ~(CDESC_TYPE|CDESC_SHORTDESC);
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -373,6 +373,7 @@ ulimit_builtin (list)
|
||||
mode |= LIMIT_HARD;
|
||||
break;
|
||||
|
||||
CASE_HELPOPT;
|
||||
case '?':
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -91,6 +91,7 @@ umask_builtin (list)
|
||||
case 'p':
|
||||
pflag++;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -113,6 +113,7 @@ wait_builtin (list)
|
||||
nflag = 1;
|
||||
break;
|
||||
#endif
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# From configure.ac for Bash 4.4, version 4.073.
|
||||
# From configure.ac for Bash 4.4, version 4.074.
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for bash 4.4-beta.
|
||||
#
|
||||
@@ -9301,7 +9301,7 @@ fi
|
||||
done
|
||||
|
||||
for ac_header in sys/pte.h sys/stream.h sys/select.h sys/file.h sys/ioctl.h \
|
||||
sys/resource.h sys/param.h sys/socket.h sys/stat.h \
|
||||
sys/param.h sys/socket.h sys/stat.h \
|
||||
sys/time.h sys/times.h sys/types.h sys/wait.h
|
||||
do :
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
@@ -9341,6 +9341,19 @@ fi
|
||||
|
||||
|
||||
|
||||
ac_fn_c_check_header_compile "$LINENO" "sys/resource.h" "ac_cv_header_sys_resource_h" "
|
||||
#if HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
"
|
||||
if test "x$ac_cv_header_sys_resource_h" = xyes; then :
|
||||
$as_echo "#define HAVE_SYS_RESOURCE_H 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
|
||||
# for constant arguments. Useless!
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
|
||||
|
||||
+10
-2
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AC_REVISION([for Bash 4.4, version 4.073])dnl
|
||||
AC_REVISION([for Bash 4.4, version 4.074])dnl
|
||||
|
||||
define(bashvers, 4.4)
|
||||
define(relstatus, beta)
|
||||
@@ -717,7 +717,7 @@ AC_CHECK_HEADERS(unistd.h stdlib.h stdarg.h varargs.h limits.h string.h \
|
||||
stdbool.h stddef.h stdint.h netdb.h pwd.h grp.h strings.h \
|
||||
regex.h syslog.h ulimit.h)
|
||||
AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h sys/ioctl.h \
|
||||
sys/resource.h sys/param.h sys/socket.h sys/stat.h \
|
||||
sys/param.h sys/socket.h sys/stat.h \
|
||||
sys/time.h sys/times.h sys/types.h sys/wait.h)
|
||||
AC_CHECK_HEADERS(netinet/in.h arpa/inet.h)
|
||||
|
||||
@@ -729,6 +729,14 @@ AC_CHECK_HEADER(sys/ptem.h, , ,[[
|
||||
#endif
|
||||
]])
|
||||
|
||||
dnl SunOS 4 needs to include <sys/time.h> before <sys/resource.h> to compile
|
||||
dnl autoconf complains about presence but inability to compile
|
||||
AC_CHECK_HEADER(sys/resource.h, AC_DEFINE(HAVE_SYS_RESOURCE_H), [], [[
|
||||
#if HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
]])
|
||||
|
||||
dnl special checks for libc functions
|
||||
AC_FUNC_ALLOCA
|
||||
AC_FUNC_CHOWN
|
||||
|
||||
+1760
-1759
File diff suppressed because it is too large
Load Diff
+16
-11
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet.ramey@case.edu
|
||||
.\"
|
||||
.\" Last Change: Tue Oct 13 17:03:11 EDT 2015
|
||||
.\" Last Change: Tue Oct 20 10:48:01 EDT 2015
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2015 October 11" "GNU Bash 4.4"
|
||||
.TH BASH 1 "2015 October 20" "GNU Bash 4.4"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -3217,8 +3217,8 @@ or
|
||||
.RE
|
||||
.PP
|
||||
.B Bash
|
||||
performs the expansion by executing \fIcommand\fP and
|
||||
replacing the command substitution with the standard output of the
|
||||
performs the expansion by executing \fIcommand\fP in a subshell environment
|
||||
and replacing the command substitution with the standard output of the
|
||||
command, with any trailing newlines deleted.
|
||||
Embedded newlines are not deleted, but they may be removed during
|
||||
word splitting.
|
||||
@@ -3269,19 +3269,23 @@ is invalid,
|
||||
prints a message indicating failure and no substitution occurs.
|
||||
.SS Process Substitution
|
||||
.PP
|
||||
\fIProcess substitution\fP is supported on systems that support named
|
||||
pipes (\fIFIFOs\fP) or the \fB/dev/fd\fP method of naming open files.
|
||||
\fIProcess substitution\fP allows a process's input or output to be
|
||||
referred to using a filename.
|
||||
It takes the form of
|
||||
\fB<(\fP\fIlist\^\fP\fB)\fP
|
||||
or
|
||||
\fB>(\fP\fIlist\^\fP\fB)\fP.
|
||||
The process \fIlist\fP is run with its input or output connected to a
|
||||
\fIFIFO\fP or some file in \fB/dev/fd\fP. The name of this file is
|
||||
The process \fIlist\fP is run asynchronously, and its input or output
|
||||
appears as a filename.
|
||||
This filename is
|
||||
passed as an argument to the current command as the result of the
|
||||
expansion. If the \fB>(\fP\fIlist\^\fP\fB)\fP form is used, writing to
|
||||
expansion.
|
||||
If the \fB>(\fP\fIlist\^\fP\fB)\fP form is used, writing to
|
||||
the file will provide input for \fIlist\fP. If the
|
||||
\fB<(\fP\fIlist\^\fP\fB)\fP form is used, the file passed as an
|
||||
argument should be read to obtain the output of \fIlist\fP.
|
||||
Process substitution is supported on systems that support named
|
||||
pipes (\fIFIFOs\fP) or the \fB/dev/fd\fP method of naming open files.
|
||||
.PP
|
||||
When available, process substitution is performed
|
||||
simultaneously with parameter and variable expansion,
|
||||
@@ -3325,9 +3329,10 @@ If
|
||||
.B IFS
|
||||
has a value other than the default, then sequences of
|
||||
the whitespace characters
|
||||
.B space
|
||||
.BR space ,
|
||||
.BR tab ,
|
||||
and
|
||||
.B tab
|
||||
.B newline
|
||||
are ignored at the beginning and end of the
|
||||
word, as long as the whitespace character is in the
|
||||
value of
|
||||
|
||||
+13
-9
@@ -14,7 +14,7 @@ This is Edition @value{EDITION}, last updated @value{UPDATED},
|
||||
of @cite{The GNU Bash Reference Manual},
|
||||
for @code{Bash}, Version @value{VERSION}.
|
||||
|
||||
Copyright @copyright{} 1988--2014 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1988--2015 Free Software Foundation, Inc.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
@@ -2246,8 +2246,8 @@ or
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
Bash performs the expansion by executing @var{command} and
|
||||
replacing the command substitution with the standard output of the
|
||||
Bash performs the expansion by executing @var{command} in a subshell environment
|
||||
and replacing the command substitution with the standard output of the
|
||||
command, with any trailing newlines deleted.
|
||||
Embedded newlines are not deleted, but they may be removed during
|
||||
word splitting.
|
||||
@@ -2296,8 +2296,8 @@ failure to the standard error and no substitution occurs.
|
||||
@subsection Process Substitution
|
||||
@cindex process substitution
|
||||
|
||||
Process substitution is supported on systems that support named
|
||||
pipes (@sc{fifo}s) or the @file{/dev/fd} method of naming open files.
|
||||
Process substitution allows a process's input or output to be
|
||||
referred to using a filename.
|
||||
It takes the form of
|
||||
@example
|
||||
<(@var{list})
|
||||
@@ -2308,16 +2308,20 @@ or
|
||||
>(@var{list})
|
||||
@end example
|
||||
@noindent
|
||||
The process @var{list} is run with its input or output connected to a
|
||||
@sc{fifo} or some file in @file{/dev/fd}. The name of this file is
|
||||
The process @var{list} is run asynchronously, and its input or output
|
||||
appears as a filename.
|
||||
This filename is
|
||||
passed as an argument to the current command as the result of the
|
||||
expansion. If the @code{>(@var{list})} form is used, writing to
|
||||
expansion.
|
||||
If the @code{>(@var{list})} form is used, writing to
|
||||
the file will provide input for @var{list}. If the
|
||||
@code{<(@var{list})} form is used, the file passed as an
|
||||
argument should be read to obtain the output of @var{list}.
|
||||
Note that no space may appear between the @code{<} or @code{>}
|
||||
and the left parenthesis, otherwise the construct would be interpreted
|
||||
as a redirection.
|
||||
Process substitution is supported on systems that support named
|
||||
pipes (@sc{fifo}s) or the @file{/dev/fd} method of naming open files.
|
||||
|
||||
When available, process substitution is performed simultaneously with
|
||||
parameter and variable expansion, command substitution, and arithmetic
|
||||
@@ -2341,7 +2345,7 @@ at the beginning and end of the results of the previous
|
||||
expansions are ignored, and any sequence of @env{IFS}
|
||||
characters not at the beginning or end serves to delimit words.
|
||||
If @env{IFS} has a value other than the default, then sequences of
|
||||
the whitespace characters @code{space} and @code{tab}
|
||||
the whitespace characters @code{space}, @code{tab}, and @code{newline}
|
||||
are ignored at the beginning and end of the
|
||||
word, as long as the whitespace character is in the
|
||||
value of @env{IFS} (an @env{IFS} whitespace character).
|
||||
|
||||
+2
-2
@@ -2,10 +2,10 @@
|
||||
Copyright (C) 1988-2015 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Tue Oct 13 17:03:11 EDT 2015
|
||||
@set LASTCHANGE Tue Oct 20 10:48:33 EDT 2015
|
||||
|
||||
@set EDITION 4.4
|
||||
@set VERSION 4.4
|
||||
|
||||
@set UPDATED 13 October 2015
|
||||
@set UPDATED 20 October 2015
|
||||
@set UPDATED-MONTH October 2015
|
||||
|
||||
@@ -284,6 +284,7 @@ internal_inform (format, va_alist)
|
||||
va_list args;
|
||||
|
||||
error_prolog (1);
|
||||
/* TRANSLATORS: this is a prefix for informational messages. */
|
||||
fprintf (stderr, _("INFORM: "));
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
@@ -58,6 +58,7 @@ extern int errno;
|
||||
#endif
|
||||
|
||||
#define NEED_FPURGE_DECL
|
||||
#define NEED_SH_SETLINEBUF_DECL
|
||||
|
||||
#include "bashansi.h"
|
||||
#include "bashintl.h"
|
||||
|
||||
@@ -58,6 +58,7 @@ extern int check_hashed_filenames;
|
||||
extern int source_uses_path;
|
||||
extern int source_searches_cwd;
|
||||
extern int posixly_correct;
|
||||
extern int inherit_errexit;
|
||||
|
||||
static char *bash_special_tilde_expansions __P((char *));
|
||||
static int unquoted_tilde_word __P((const char *));
|
||||
@@ -75,6 +76,7 @@ posix_initialize (on)
|
||||
if (on != 0)
|
||||
{
|
||||
interactive_comments = source_uses_path = expand_aliases = 1;
|
||||
inherit_errexit = 1;
|
||||
source_searches_cwd = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,132 +16,6 @@
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>. */
|
||||
|
||||
/* A multibyte character is a short subsequence of a char* string,
|
||||
representing a single wide character.
|
||||
|
||||
We use multibyte characters instead of wide characters because of
|
||||
the following goals:
|
||||
1) correct multibyte handling, i.e. operate according to the LC_CTYPE
|
||||
locale,
|
||||
2) ease of maintenance, i.e. the maintainer needs not know all details
|
||||
of the ISO C 99 standard,
|
||||
3) don't fail grossly if the input is not in the encoding set by the
|
||||
locale, because often different encodings are in use in the same
|
||||
countries (ISO-8859-1/UTF-8, EUC-JP/Shift_JIS, ...),
|
||||
4) fast in the case of ASCII characters,
|
||||
5) portability, i.e. don't make unportable assumptions about wchar_t.
|
||||
|
||||
Multibyte characters are only accessed through the mb* macros.
|
||||
|
||||
mb_ptr (mbc)
|
||||
return a pointer to the beginning of the multibyte sequence.
|
||||
|
||||
mb_len (mbc)
|
||||
returns the number of bytes occupied by the multibyte sequence.
|
||||
Always > 0.
|
||||
|
||||
mb_iseq (mbc, sc)
|
||||
returns true if mbc is the standard ASCII character sc.
|
||||
|
||||
mb_isnul (mbc)
|
||||
returns true if mbc is the nul character.
|
||||
|
||||
mb_cmp (mbc1, mbc2)
|
||||
returns a positive, zero, or negative value depending on whether mbc1
|
||||
sorts after, same or before mbc2.
|
||||
|
||||
mb_casecmp (mbc1, mbc2)
|
||||
returns a positive, zero, or negative value depending on whether mbc1
|
||||
sorts after, same or before mbc2, modulo upper/lowercase conversion.
|
||||
|
||||
mb_equal (mbc1, mbc2)
|
||||
returns true if mbc1 and mbc2 are equal.
|
||||
|
||||
mb_caseequal (mbc1, mbc2)
|
||||
returns true if mbc1 and mbc2 are equal modulo upper/lowercase conversion.
|
||||
|
||||
mb_isalnum (mbc)
|
||||
returns true if mbc is alphanumeric.
|
||||
|
||||
mb_isalpha (mbc)
|
||||
returns true if mbc is alphabetic.
|
||||
|
||||
mb_isascii(mbc)
|
||||
returns true if mbc is plain ASCII.
|
||||
|
||||
mb_isblank (mbc)
|
||||
returns true if mbc is a blank.
|
||||
|
||||
mb_iscntrl (mbc)
|
||||
returns true if mbc is a control character.
|
||||
|
||||
mb_isdigit (mbc)
|
||||
returns true if mbc is a decimal digit.
|
||||
|
||||
mb_isgraph (mbc)
|
||||
returns true if mbc is a graphic character.
|
||||
|
||||
mb_islower (mbc)
|
||||
returns true if mbc is lowercase.
|
||||
|
||||
mb_isprint (mbc)
|
||||
returns true if mbc is a printable character.
|
||||
|
||||
mb_ispunct (mbc)
|
||||
returns true if mbc is a punctuation character.
|
||||
|
||||
mb_isspace (mbc)
|
||||
returns true if mbc is a space character.
|
||||
|
||||
mb_isupper (mbc)
|
||||
returns true if mbc is uppercase.
|
||||
|
||||
mb_isxdigit (mbc)
|
||||
returns true if mbc is a hexadecimal digit.
|
||||
|
||||
mb_width (mbc)
|
||||
returns the number of columns on the output device occupied by mbc.
|
||||
Always >= 0.
|
||||
|
||||
mb_putc (mbc, stream)
|
||||
outputs mbc on stream, a byte oriented FILE stream opened for output.
|
||||
|
||||
mb_setascii (&mbc, sc)
|
||||
assigns the standard ASCII character sc to mbc.
|
||||
|
||||
mb_copy (&destmbc, &srcmbc)
|
||||
copies srcmbc to destmbc.
|
||||
|
||||
Here are the function prototypes of the macros.
|
||||
|
||||
typedef int bool;
|
||||
extern const char * mb_ptr (const mbchar_t mbc);
|
||||
extern size_t mb_len (const mbchar_t mbc);
|
||||
extern bool mb_iseq (const mbchar_t mbc, char sc);
|
||||
extern bool mb_isnul (const mbchar_t mbc);
|
||||
extern int mb_cmp (const mbchar_t mbc1, const mbchar_t mbc2);
|
||||
extern int mb_casecmp (const mbchar_t mbc1, const mbchar_t mbc2);
|
||||
extern bool mb_equal (const mbchar_t mbc1, const mbchar_t mbc2);
|
||||
extern bool mb_caseequal (const mbchar_t mbc1, const mbchar_t mbc2);
|
||||
extern bool mb_isalnum (const mbchar_t mbc);
|
||||
extern bool mb_isalpha (const mbchar_t mbc);
|
||||
extern bool mb_isascii (const mbchar_t mbc);
|
||||
extern bool mb_isblank (const mbchar_t mbc);
|
||||
extern bool mb_iscntrl (const mbchar_t mbc);
|
||||
extern bool mb_isdigit (const mbchar_t mbc);
|
||||
extern bool mb_isgraph (const mbchar_t mbc);
|
||||
extern bool mb_islower (const mbchar_t mbc);
|
||||
extern bool mb_isprint (const mbchar_t mbc);
|
||||
extern bool mb_ispunct (const mbchar_t mbc);
|
||||
extern bool mb_isspace (const mbchar_t mbc);
|
||||
extern bool mb_isupper (const mbchar_t mbc);
|
||||
extern bool mb_isxdigit (const mbchar_t mbc);
|
||||
extern int mb_width (const mbchar_t mbc);
|
||||
extern void mb_putc (const mbchar_t mbc, FILE *stream);
|
||||
extern void mb_setascii (mbchar_t *new, char sc);
|
||||
extern void mb_copy (mbchar_t *new, const mbchar_t *old);
|
||||
*/
|
||||
|
||||
#ifndef _SHMBCHAR_H
|
||||
#define _SHMBCHAR_H 1
|
||||
|
||||
@@ -158,121 +32,6 @@
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#define MBCHAR_BUF_SIZE 24
|
||||
|
||||
struct mbchar
|
||||
{
|
||||
const char *ptr; /* pointer to current character */
|
||||
size_t bytes; /* number of bytes of current character, > 0 */
|
||||
int wc_valid; /* true if wc is a valid wide character */
|
||||
wchar_t wc; /* if wc_valid: the current character */
|
||||
char buf[MBCHAR_BUF_SIZE]; /* room for the bytes, used for file input only */
|
||||
};
|
||||
|
||||
/* EOF (not a real character) is represented with bytes = 0 and
|
||||
wc_valid = false. */
|
||||
|
||||
typedef struct mbchar mbchar_t;
|
||||
|
||||
/* Access the current character. */
|
||||
#define mb_ptr(mbc) ((mbc).ptr)
|
||||
#define mb_len(mbc) ((mbc).bytes)
|
||||
|
||||
/* Comparison of characters. */
|
||||
#define mb_iseq(mbc, sc) ((mbc).wc_valid && (mbc).wc == (sc))
|
||||
#define mb_isnul(mbc) ((mbc).wc_valid && (mbc).wc == 0)
|
||||
#define mb_cmp(mbc1, mbc2) \
|
||||
((mbc1).wc_valid \
|
||||
? ((mbc2).wc_valid \
|
||||
? (int) (mbc1).wc - (int) (mbc2).wc \
|
||||
: -1) \
|
||||
: ((mbc2).wc_valid \
|
||||
? 1 \
|
||||
: (mbc1).bytes == (mbc2).bytes \
|
||||
? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \
|
||||
: (mbc1).bytes < (mbc2).bytes \
|
||||
? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \
|
||||
: (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1)))
|
||||
#define mb_casecmp(mbc1, mbc2) \
|
||||
((mbc1).wc_valid \
|
||||
? ((mbc2).wc_valid \
|
||||
? (int) towlower ((mbc1).wc) - (int) towlower ((mbc2).wc) \
|
||||
: -1) \
|
||||
: ((mbc2).wc_valid \
|
||||
? 1 \
|
||||
: (mbc1).bytes == (mbc2).bytes \
|
||||
? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \
|
||||
: (mbc1).bytes < (mbc2).bytes \
|
||||
? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \
|
||||
: (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1)))
|
||||
#define mb_equal(mbc1, mbc2) \
|
||||
((mbc1).wc_valid && (mbc2).wc_valid \
|
||||
? (mbc1).wc == (mbc2).wc \
|
||||
: (mbc1).bytes == (mbc2).bytes \
|
||||
&& memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0)
|
||||
#define mb_caseequal(mbc1, mbc2) \
|
||||
((mbc1).wc_valid && (mbc2).wc_valid \
|
||||
? towlower ((mbc1).wc) == towlower ((mbc2).wc) \
|
||||
: (mbc1).bytes == (mbc2).bytes \
|
||||
&& memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0)
|
||||
|
||||
/* <ctype.h>, <wctype.h> classification. */
|
||||
#define mb_isascii(mbc) \
|
||||
((mbc).wc_valid && (mbc).wc >= 0 && (mbc).wc <= 127)
|
||||
#define mb_isalnum(mbc) ((mbc).wc_valid && iswalnum ((mbc).wc))
|
||||
#define mb_isalpha(mbc) ((mbc).wc_valid && iswalpha ((mbc).wc))
|
||||
#define mb_isblank(mbc) ((mbc).wc_valid && iswblank ((mbc).wc))
|
||||
#define mb_iscntrl(mbc) ((mbc).wc_valid && iswcntrl ((mbc).wc))
|
||||
#define mb_isdigit(mbc) ((mbc).wc_valid && iswdigit ((mbc).wc))
|
||||
#define mb_isgraph(mbc) ((mbc).wc_valid && iswgraph ((mbc).wc))
|
||||
#define mb_islower(mbc) ((mbc).wc_valid && iswlower ((mbc).wc))
|
||||
#define mb_isprint(mbc) ((mbc).wc_valid && iswprint ((mbc).wc))
|
||||
#define mb_ispunct(mbc) ((mbc).wc_valid && iswpunct ((mbc).wc))
|
||||
#define mb_isspace(mbc) ((mbc).wc_valid && iswspace ((mbc).wc))
|
||||
#define mb_isupper(mbc) ((mbc).wc_valid && iswupper ((mbc).wc))
|
||||
#define mb_isxdigit(mbc) ((mbc).wc_valid && iswxdigit ((mbc).wc))
|
||||
|
||||
/* Extra <wchar.h> function. */
|
||||
|
||||
/* Unprintable characters appear as a small box of width 1. */
|
||||
#define MB_UNPRINTABLE_WIDTH 1
|
||||
|
||||
static inline int
|
||||
mb_width_aux (wint_t wc)
|
||||
{
|
||||
int w = wcwidth (wc);
|
||||
/* For unprintable characters, arbitrarily return 0 for control characters
|
||||
and MB_UNPRINTABLE_WIDTH otherwise. */
|
||||
return (w >= 0 ? w : iswcntrl (wc) ? 0 : MB_UNPRINTABLE_WIDTH);
|
||||
}
|
||||
|
||||
#define mb_width(mbc) \
|
||||
((mbc).wc_valid ? mb_width_aux ((mbc).wc) : MB_UNPRINTABLE_WIDTH)
|
||||
|
||||
/* Output. */
|
||||
#define mb_putc(mbc, stream) fwrite ((mbc).ptr, 1, (mbc).bytes, (stream))
|
||||
|
||||
/* Assignment. */
|
||||
#define mb_setascii(mbc, sc) \
|
||||
((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \
|
||||
(mbc)->wc = (mbc)->buf[0] = (sc))
|
||||
|
||||
/* Copying a character. */
|
||||
static inline void
|
||||
mb_copy (mbchar_t *new_mbc, const mbchar_t *old_mbc)
|
||||
{
|
||||
if (old_mbc->ptr == &old_mbc->buf[0])
|
||||
{
|
||||
memcpy (&new_mbc->buf[0], &old_mbc->buf[0], old_mbc->bytes);
|
||||
new_mbc->ptr = &new_mbc->buf[0];
|
||||
}
|
||||
else
|
||||
new_mbc->ptr = old_mbc->ptr;
|
||||
new_mbc->bytes = old_mbc->bytes;
|
||||
if ((new_mbc->wc_valid = old_mbc->wc_valid))
|
||||
new_mbc->wc = old_mbc->wc;
|
||||
}
|
||||
|
||||
|
||||
/* is_basic(c) tests whether the single-byte character c is in the
|
||||
ISO C "basic character set".
|
||||
|
||||
@@ -97,6 +97,10 @@ extern int killpg __P((pid_t, int));
|
||||
#define MAX_JOBS_IN_ARRAY 128 /* testing */
|
||||
#endif
|
||||
|
||||
/* XXX for now */
|
||||
#define PIDSTAT_TABLE_SZ 4096
|
||||
#define BGPIDS_TABLE_SZ 512
|
||||
|
||||
/* Flag values for second argument to delete_job */
|
||||
#define DEL_WARNSTOPPED 1 /* warn about deleting stopped jobs */
|
||||
#define DEL_NOBGPID 2 /* don't add pgrp leader to bgpids */
|
||||
@@ -174,6 +178,7 @@ extern SigHandler **original_signals;
|
||||
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 };
|
||||
|
||||
/* The array of known jobs. */
|
||||
@@ -293,12 +298,19 @@ static void restore_sigint_handler __P((void));
|
||||
static void pipe_read __P((int *));
|
||||
#endif
|
||||
|
||||
static struct pidstat *bgp_alloc __P((pid_t, int));
|
||||
/* Hash table manipulation */
|
||||
|
||||
static ps_index_t *pshash_getbucket __P((pid_t));
|
||||
static void pshash_delindex __P((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 void bgp_prune __P((void));
|
||||
|
||||
static ps_index_t bgp_getindex __P((void));
|
||||
static void bgp_resize __P((void)); /* XXX */
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
static int *pstatuses; /* list of pipeline statuses */
|
||||
@@ -693,20 +705,82 @@ stop_pipeline (async, deferred)
|
||||
}
|
||||
|
||||
/* Functions to manage the list of exited background pids whose status has
|
||||
been saved. */
|
||||
been saved.
|
||||
|
||||
static struct pidstat *
|
||||
bgp_alloc (pid, status)
|
||||
pid_t pid;
|
||||
int status;
|
||||
pidstat_table:
|
||||
|
||||
The current implementation is a hash table using a single (separate) arena
|
||||
for storage that can be allocated and freed as a unit. The size of the hash
|
||||
table is a multiple of PIDSTAT_TABLE_SZ (4096) and multiple PIDs that hash
|
||||
to the same value are chained through the bucket_next and bucket_prev
|
||||
pointers (basically coalesced hashing for collision resolution).
|
||||
|
||||
bgpids.storage:
|
||||
|
||||
All pid/status storage is done using the circular buffer bgpids.storage.
|
||||
This must contain at least js.c_childmax entries. The circular buffer is
|
||||
used to supply the ordered list Posix requires ("the last CHILD_MAX
|
||||
processes"). To avoid searching the entire storage table for a given PID,
|
||||
the hash table (pidstat_table) holds pointers into the storage arena and
|
||||
uses a doubly-linked list of cells (bucket_next/bucket_prev, also pointers
|
||||
into the arena) to implement collision resolution. */
|
||||
|
||||
/* The number of elements in bgpids.storage always has to be > js.c_childmax for
|
||||
the circular buffer to work right. */
|
||||
static void
|
||||
bgp_resize ()
|
||||
{
|
||||
struct pidstat *ps;
|
||||
ps_index_t nsize;
|
||||
ps_index_t psi;
|
||||
|
||||
ps = (struct pidstat *)xmalloc (sizeof (struct pidstat));
|
||||
ps->pid = pid;
|
||||
ps->status = status;
|
||||
ps->next = (struct pidstat *)0;
|
||||
return ps;
|
||||
if (bgpids.nalloc == 0)
|
||||
{
|
||||
/* invalidate hash table when bgpids table is reallocated */
|
||||
for (psi = 0; psi < PIDSTAT_TABLE_SZ; psi++)
|
||||
pidstat_table[psi] = NO_PIDSTAT;
|
||||
nsize = BGPIDS_TABLE_SZ; /* should be power of 2 */
|
||||
bgpids.head = 0;
|
||||
}
|
||||
else
|
||||
nsize = bgpids.nalloc;
|
||||
|
||||
while (nsize < js.c_childmax)
|
||||
nsize *= 2;
|
||||
|
||||
if (bgpids.nalloc < js.c_childmax)
|
||||
{
|
||||
bgpids.storage = (struct pidstat *)xrealloc (bgpids.storage, nsize * sizeof (struct pidstat));
|
||||
|
||||
for (psi = bgpids.nalloc; psi < nsize; psi++)
|
||||
bgpids.storage[psi].pid = NO_PID;
|
||||
|
||||
bgpids.nalloc = nsize;
|
||||
|
||||
}
|
||||
else if (bgpids.head >= bgpids.nalloc) /* wrap around */
|
||||
bgpids.head = 0;
|
||||
}
|
||||
|
||||
static ps_index_t
|
||||
bgp_getindex ()
|
||||
{
|
||||
ps_index_t psi;
|
||||
|
||||
if (bgpids.nalloc < js.c_childmax || bgpids.head >= bgpids.nalloc)
|
||||
bgp_resize ();
|
||||
|
||||
pshash_delindex (bgpids.head); /* XXX - clear before reusing */
|
||||
return bgpids.head++;
|
||||
}
|
||||
|
||||
static ps_index_t *
|
||||
pshash_getbucket (pid)
|
||||
pid_t pid;
|
||||
{
|
||||
unsigned long hash; /* XXX - u_bits32_t */
|
||||
|
||||
hash = pid * 0x9e370001UL;
|
||||
return (&pidstat_table[hash % PIDSTAT_TABLE_SZ]);
|
||||
}
|
||||
|
||||
static struct pidstat *
|
||||
@@ -714,61 +788,75 @@ bgp_add (pid, status)
|
||||
pid_t pid;
|
||||
int status;
|
||||
{
|
||||
ps_index_t *bucket, psi;
|
||||
struct pidstat *ps;
|
||||
|
||||
ps = bgp_alloc (pid, status);
|
||||
bucket = pshash_getbucket (pid);
|
||||
psi = bgp_getindex ();
|
||||
ps = &bgpids.storage[psi];
|
||||
|
||||
ps->pid = pid;
|
||||
ps->status = status;
|
||||
ps->bucket_next = *bucket;
|
||||
ps->bucket_prev = NO_PIDSTAT;
|
||||
|
||||
if (bgpids.list == 0)
|
||||
{
|
||||
bgpids.list = bgpids.end = ps;
|
||||
bgpids.npid = 0; /* just to make sure */
|
||||
}
|
||||
else
|
||||
{
|
||||
bgpids.end->next = ps;
|
||||
bgpids.end = ps;
|
||||
}
|
||||
bgpids.npid++;
|
||||
|
||||
#if 0
|
||||
if (bgpids.npid > js.c_childmax)
|
||||
bgp_prune ();
|
||||
#endif
|
||||
|
||||
if (ps->bucket_next != NO_PIDSTAT)
|
||||
bgpids.storage[ps->bucket_next].bucket_prev = psi;
|
||||
|
||||
*bucket = psi; /* set chain head in hash table */
|
||||
|
||||
return ps;
|
||||
}
|
||||
|
||||
static void
|
||||
pshash_delindex (psi)
|
||||
ps_index_t psi;
|
||||
{
|
||||
struct pidstat *ps;
|
||||
|
||||
ps = &bgpids.storage[psi];
|
||||
if (ps->pid == NO_PID)
|
||||
return;
|
||||
|
||||
if (ps->bucket_next != NO_PID)
|
||||
bgpids.storage[ps->bucket_next].bucket_prev = ps->bucket_prev;
|
||||
if (ps->bucket_prev != NO_PID)
|
||||
bgpids.storage[ps->bucket_prev].bucket_next = ps->bucket_next;
|
||||
else
|
||||
*(pshash_getbucket (ps->pid)) = ps->bucket_next;
|
||||
}
|
||||
|
||||
static int
|
||||
bgp_delete (pid)
|
||||
pid_t pid;
|
||||
{
|
||||
struct pidstat *prev, *p;
|
||||
ps_index_t psi;
|
||||
|
||||
for (prev = p = bgpids.list; p; prev = p, p = p->next)
|
||||
if (p->pid == pid)
|
||||
{
|
||||
prev->next = p->next; /* remove from list */
|
||||
break;
|
||||
}
|
||||
if (bgpids.storage == 0 || bgpids.nalloc == 0 || bgpids.npid == 0)
|
||||
return 0;
|
||||
|
||||
if (p == 0)
|
||||
/* Search chain using hash to find bucket in pidstat_table */
|
||||
for (psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next)
|
||||
if (bgpids.storage[psi].pid == pid)
|
||||
break;
|
||||
|
||||
if (psi == NO_PIDSTAT)
|
||||
return 0; /* not found */
|
||||
|
||||
#if defined (DEBUG)
|
||||
itrace("bgp_delete: deleting %d", pid);
|
||||
#endif
|
||||
|
||||
/* Housekeeping in the border cases. */
|
||||
if (p == bgpids.list)
|
||||
bgpids.list = bgpids.list->next;
|
||||
else if (p == bgpids.end)
|
||||
bgpids.end = prev;
|
||||
pshash_delindex (psi); /* hash table management */
|
||||
|
||||
bgpids.npid--;
|
||||
if (bgpids.npid == 0)
|
||||
bgpids.list = bgpids.end = 0;
|
||||
else if (bgpids.npid == 1)
|
||||
bgpids.end = bgpids.list; /* just to make sure */
|
||||
|
||||
free (p);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -776,48 +864,45 @@ bgp_delete (pid)
|
||||
static void
|
||||
bgp_clear ()
|
||||
{
|
||||
struct pidstat *ps, *p;
|
||||
if (bgpids.storage == 0 || bgpids.nalloc == 0)
|
||||
return;
|
||||
|
||||
free (bgpids.storage);
|
||||
|
||||
bgpids.storage = 0;
|
||||
bgpids.nalloc = 0;
|
||||
bgpids.head = 0;
|
||||
|
||||
for (ps = bgpids.list; ps; )
|
||||
{
|
||||
p = ps;
|
||||
ps = ps->next;
|
||||
free (p);
|
||||
}
|
||||
bgpids.list = bgpids.end = 0;
|
||||
bgpids.npid = 0;
|
||||
}
|
||||
|
||||
/* Search for PID in the list of saved background pids; return its status if
|
||||
found. If not found, return -1. */
|
||||
found. If not found, return -1. We hash to the right spot in pidstat_table
|
||||
and follow the bucket chain to the end. */
|
||||
static int
|
||||
bgp_search (pid)
|
||||
pid_t pid;
|
||||
{
|
||||
struct pidstat *ps;
|
||||
ps_index_t psi;
|
||||
|
||||
if (bgpids.storage == 0 || bgpids.nalloc == 0 || bgpids.npid == 0)
|
||||
return -1;
|
||||
|
||||
/* Search chain using hash to find bucket in pidstat_table */
|
||||
for (psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next)
|
||||
if (bgpids.storage[psi].pid == pid)
|
||||
return (bgpids.storage[psi].status);
|
||||
|
||||
for (ps = bgpids.list ; ps; ps = ps->next)
|
||||
if (ps->pid == pid)
|
||||
return ps->status;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
bgp_prune ()
|
||||
{
|
||||
struct pidstat *ps;
|
||||
|
||||
if (bgpids.npid == 0 || bgpids.list == 0)
|
||||
return; /* just paranoia */
|
||||
|
||||
while (bgpids.npid > js.c_childmax)
|
||||
{
|
||||
ps = bgpids.list;
|
||||
bgpids.list = bgpids.list->next;
|
||||
free (ps);
|
||||
bgpids.npid--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#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
|
||||
@@ -3641,7 +3726,6 @@ set_job_status_and_cleanup (job)
|
||||
{
|
||||
int old_frozen;
|
||||
|
||||
itrace("waitchld: special handling for SIGINT");
|
||||
wait_sigint_received = 0;
|
||||
|
||||
/* If SIGINT is trapped, set the exit status so that the trap
|
||||
@@ -4051,6 +4135,11 @@ initialize_job_control (force)
|
||||
if (js.c_childmax < 0)
|
||||
js.c_childmax = DEFAULT_CHILD_MAX;
|
||||
|
||||
#if 0
|
||||
if (js.c_childmax > MAX_CHILD_MAX)
|
||||
js.c_childmax = MAX_CHILD_MAX;
|
||||
#endif
|
||||
|
||||
return job_control;
|
||||
}
|
||||
|
||||
@@ -4271,7 +4360,12 @@ delete_all_jobs (running_only)
|
||||
itrace("delete_all_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
|
||||
#endif
|
||||
if (jobs[i] && (running_only == 0 || (running_only && RUNNING(i))))
|
||||
delete_job (i, DEL_WARNSTOPPED);
|
||||
/* We don't want to add any of these pids to bgpids. If running_only
|
||||
is non-zero, we don't want to add running jobs to the list.
|
||||
If we are interested in all jobs, not just running jobs, and
|
||||
we are going to clear the bgpids list below (bgp_clear()), we
|
||||
don't need to bother. */
|
||||
delete_job (i, DEL_WARNSTOPPED|DEL_NOBGPID);
|
||||
}
|
||||
if (running_only == 0)
|
||||
{
|
||||
@@ -4422,6 +4516,11 @@ mark_dead_jobs_as_notified (force)
|
||||
if (js.c_childmax < 0)
|
||||
js.c_childmax = DEFAULT_CHILD_MAX;
|
||||
|
||||
#if 0
|
||||
if (js.c_childmax > MAX_CHILD_MAX)
|
||||
js.c_childmax = MAX_CHILD_MAX;
|
||||
#endif
|
||||
|
||||
/* Don't do anything if the number of dead processes is less than CHILD_MAX
|
||||
and we're not forcing a cleanup. */
|
||||
if (ndeadproc <= js.c_childmax)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* jobs.h -- structures and definitions used by the jobs.c file. */
|
||||
|
||||
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993-2015 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -142,18 +142,28 @@ struct jobstats {
|
||||
JOB *j_lastasync; /* last async job allocated by stop_pipeline */
|
||||
};
|
||||
|
||||
/* Revised to accommodate new hash table bgpids implementation. */
|
||||
typedef pid_t ps_index_t;
|
||||
|
||||
struct pidstat {
|
||||
struct pidstat *next;
|
||||
pid_t pid;
|
||||
int status;
|
||||
ps_index_t bucket_next;
|
||||
ps_index_t bucket_prev;
|
||||
|
||||
pid_t pid;
|
||||
bits16_t status; /* only 8 bits really needed */
|
||||
};
|
||||
|
||||
struct bgpids {
|
||||
struct pidstat *list;
|
||||
struct pidstat *end;
|
||||
struct pidstat *storage; /* storage arena */
|
||||
|
||||
ps_index_t head;
|
||||
ps_index_t nalloc;
|
||||
|
||||
int npid;
|
||||
};
|
||||
|
||||
#define NO_PIDSTAT (ps_index_t)-1
|
||||
|
||||
#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. */
|
||||
|
||||
@@ -613,10 +613,11 @@ history_do_write (filename, nelements, overwrite)
|
||||
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
|
||||
#endif
|
||||
histname = history_filename (filename);
|
||||
tempname = (overwrite && histname) ? history_tempfile (histname) : 0;
|
||||
output = tempname ? tempname : histname;
|
||||
exists = histname ? (stat (histname, &finfo) == 0) : 0;
|
||||
|
||||
tempname = (overwrite && exists && S_ISREG (finfo.st_mode)) ? history_tempfile (histname) : 0;
|
||||
output = tempname ? tempname : histname;
|
||||
|
||||
file = output ? open (output, mode, 0600) : -1;
|
||||
rv = 0;
|
||||
|
||||
|
||||
@@ -409,12 +409,14 @@ shmatch.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h
|
||||
|
||||
shquote.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h
|
||||
shquote.o: ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h
|
||||
shquote.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
|
||||
shtty.o: ${BASHINCDIR}/shtty.h
|
||||
shtty.o: ${BASHINCDIR}/stdc.h
|
||||
|
||||
snprintf.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h ${topdir}/xmalloc.h
|
||||
snprintf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
|
||||
snprintf.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
snprintf.o: ${BASHINCDIR}/typemax.h
|
||||
|
||||
spell.o: ${topdir}/bashtypes.h
|
||||
@@ -493,6 +495,7 @@ strtrans.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
|
||||
strtrans.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
|
||||
strtrans.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
|
||||
strtrans.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h
|
||||
strtrans.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
#strtrans.o: ${BUILD_DIR}/version.h
|
||||
|
||||
times.o: ${BASHINCDIR}/systimes.h
|
||||
@@ -603,6 +606,7 @@ fnxform.o: ${topdir}/bashtypes.h
|
||||
fnxform.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
|
||||
|
||||
shmbchar.o: ${BASHINCDIR}/shmbchar.h
|
||||
shmbchar.o: ${BASHINCDIR}/shmbutil.h
|
||||
|
||||
unicode.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
|
||||
unicode.o: ${BASHINCDIR}/stdc.h
|
||||
|
||||
+388
-596
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,9 @@
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include "filecntl.h"
|
||||
#include <pwd.h>
|
||||
#if defined (HAVE_PWD_H)
|
||||
# include <pwd.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
|
||||
@@ -149,6 +149,9 @@ size_t ifs_firstc_len;
|
||||
unsigned char ifs_firstc;
|
||||
#endif
|
||||
|
||||
/* If non-zero, command substitution inherits the value of errexit option */
|
||||
int inherit_errexit = 0;
|
||||
|
||||
/* Sentinel to tell when we are performing variable assignments preceding a
|
||||
command name and putting them into the environment. Used to make sure
|
||||
we use the temporary environment when looking up variable values. */
|
||||
@@ -1761,6 +1764,7 @@ skip_to_delim (string, start, delims, flags)
|
||||
{
|
||||
int i, pass_next, backq, dquote, si, c, oldjmp;
|
||||
int invert, skipquote, skipcmd, noprocsub, completeflag, histexp;
|
||||
int arithexp, skipcol;
|
||||
size_t slen;
|
||||
char *temp, open[3];
|
||||
DECLARE_MBSTATE;
|
||||
@@ -1775,6 +1779,9 @@ skip_to_delim (string, start, delims, flags)
|
||||
histexp = (flags & SD_HISTEXP);
|
||||
completeflag = (flags & SD_COMPLETE) ? SX_COMPLETE : 0;
|
||||
|
||||
arithexp = (flags & SD_ARITHEXP);
|
||||
skipcol = 0;
|
||||
|
||||
i = start;
|
||||
pass_next = backq = dquote = 0;
|
||||
while (c = string[i])
|
||||
@@ -1811,6 +1818,18 @@ skip_to_delim (string, start, delims, flags)
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if (arithexp && skipcol && c == ':')
|
||||
{
|
||||
skipcol--;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if (arithexp && c == '?')
|
||||
{
|
||||
skipcol++;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if (skipquote == 0 && invert == 0 && member (c, delims))
|
||||
break;
|
||||
/* the usual case is to use skip_xxx_quoted, but we don't skip over double
|
||||
@@ -1836,6 +1855,19 @@ skip_to_delim (string, start, delims, flags)
|
||||
}
|
||||
else if (c == '"')
|
||||
i = skip_double_quoted (string, slen, ++i, completeflag);
|
||||
else if (c == LPAREN && arithexp)
|
||||
{
|
||||
si = i + 1;
|
||||
if (string[si] == '\0')
|
||||
CQ_RETURN(si);
|
||||
|
||||
temp = extract_delimited_string (string, &si, "(", "(", ")", SX_NOALLOC); /* ) */
|
||||
i = si;
|
||||
if (string[i] == '\0') /* don't increment i past EOS in loop */
|
||||
break;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if (c == '$' && ((skipcmd && string[i+1] == LPAREN) || string[i+1] == LBRACE))
|
||||
{
|
||||
si = i + 2;
|
||||
@@ -5900,9 +5932,9 @@ command_substitute (string, quoted)
|
||||
substitutions. */
|
||||
change_flag ('v', FLAG_OFF);
|
||||
|
||||
/* When not in POSIX mode, command substitution does not inherit
|
||||
the -e flag. */
|
||||
if (posixly_correct == 0)
|
||||
/* When inherit_errexit option is not enabled, command substitution does
|
||||
not inherit the -e flag. It is enabled when Posix mode is enabled */
|
||||
if (inherit_errexit == 0)
|
||||
{
|
||||
builtin_ignoring_errexit = 0;
|
||||
change_flag ('e', FLAG_OFF);
|
||||
@@ -6657,6 +6689,7 @@ parameter_brace_expand_length (name)
|
||||
the first DELIM, instead of using strchr(3). Two rules:
|
||||
1. If the substring contains a `(', read until closing `)'.
|
||||
2. If the substring contains a `?', read past one `:' for each `?'.
|
||||
The SD_ARITHEXP flag to skip_to_delim takes care of doing this.
|
||||
*/
|
||||
|
||||
static char *
|
||||
@@ -6664,51 +6697,13 @@ skiparith (substr, delim)
|
||||
char *substr;
|
||||
int delim;
|
||||
{
|
||||
size_t sublen;
|
||||
int skipcol, pcount, i;
|
||||
DECLARE_MBSTATE;
|
||||
int i;
|
||||
char delims[2];
|
||||
|
||||
sublen = strlen (substr);
|
||||
i = skipcol = pcount = 0;
|
||||
while (substr[i])
|
||||
{
|
||||
/* Balance parens */
|
||||
if (substr[i] == LPAREN)
|
||||
{
|
||||
pcount++;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (substr[i] == RPAREN && pcount)
|
||||
{
|
||||
pcount--;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (pcount)
|
||||
{
|
||||
ADVANCE_CHAR (substr, sublen, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip one `:' for each `?' */
|
||||
if (substr[i] == ':' && skipcol)
|
||||
{
|
||||
skipcol--;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (substr[i] == delim)
|
||||
break;
|
||||
if (substr[i] == '?')
|
||||
{
|
||||
skipcol++;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
ADVANCE_CHAR (substr, sublen, i);
|
||||
}
|
||||
delims[0] = delim;
|
||||
delims[1] = '\0';
|
||||
|
||||
i = skip_to_delim (substr, 0, delims, SD_ARITHEXP);
|
||||
return (substr + i);
|
||||
}
|
||||
|
||||
|
||||
@@ -293,6 +293,7 @@ extern char *cond_expand_word __P((WORD_DESC *, int));
|
||||
#define SD_NOPROCSUB 0x080 /* don't parse process substitutions as commands */
|
||||
#define SD_COMPLETE 0x100 /* skip_to_delim during completion */
|
||||
#define SD_HISTEXP 0x200 /* skip_to_delim during history expansion */
|
||||
#define SD_ARITHEXP 0x400 /* skip_to_delim during arithmetic expansion */
|
||||
|
||||
extern int skip_to_delim __P((char *, int, char *, int));
|
||||
|
||||
|
||||
+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
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
+10
-4
@@ -236,14 +236,20 @@ ok
|
||||
0
|
||||
0, 0
|
||||
0, 1
|
||||
efg
|
||||
e
|
||||
efg
|
||||
e
|
||||
abcdefg
|
||||
efg
|
||||
8 12
|
||||
./arith.tests: line 290: ((: x=9 y=41 : syntax error in expression (error token is "y=41 ")
|
||||
./arith.tests: line 294: a b: syntax error in expression (error token is "b")
|
||||
./arith.tests: line 295: ((: a b: syntax error in expression (error token is "b")
|
||||
./arith.tests: line 294: ((: x=9 y=41 : syntax error in expression (error token is "y=41 ")
|
||||
./arith.tests: line 298: a b: syntax error in expression (error token is "b")
|
||||
./arith.tests: line 299: ((: a b: syntax error in expression (error token is "b")
|
||||
42
|
||||
42
|
||||
42
|
||||
42
|
||||
42
|
||||
42
|
||||
./arith.tests: line 306: b[c]d: syntax error in expression (error token is "d")
|
||||
./arith.tests: line 310: b[c]d: syntax error in expression (error token is "d")
|
||||
|
||||
@@ -279,6 +279,10 @@ ${THIS_SH} ./arith5.sub
|
||||
# problems with suppressing evaluation present through bash-4.2
|
||||
${THIS_SH} ./arith6.sub
|
||||
|
||||
# problems with parsing arithmetic expressions containing colons that are
|
||||
# part of word expansions such as substring extraction
|
||||
${THIS_SH} ./arith7.sub
|
||||
|
||||
x=4
|
||||
y=7
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
PARAM=abcdefg
|
||||
|
||||
echo ${PARAM:1 ? 4 : 2}
|
||||
echo ${PARAM:1 ? 4 : 2:1}
|
||||
|
||||
echo ${PARAM: 4<5 ? 4 : 2}
|
||||
echo ${PARAM: 5>4 ? 4 : 2:1}
|
||||
|
||||
echo ${PARAM:${OFFSET:-0}}
|
||||
OFFSET=4
|
||||
echo ${PARAM:${OFFSET:-0}}
|
||||
@@ -33,6 +33,7 @@ shopt -u histreedit
|
||||
shopt -u histverify
|
||||
shopt -s hostcomplete
|
||||
shopt -u huponexit
|
||||
shopt -u inherit_errexit
|
||||
shopt -s interactive_comments
|
||||
shopt -u lastpipe
|
||||
shopt -u lithist
|
||||
@@ -90,6 +91,7 @@ shopt -u histappend
|
||||
shopt -u histreedit
|
||||
shopt -u histverify
|
||||
shopt -u huponexit
|
||||
shopt -u inherit_errexit
|
||||
shopt -u lastpipe
|
||||
shopt -u lithist
|
||||
shopt -u login_shell
|
||||
@@ -127,6 +129,7 @@ histappend off
|
||||
histreedit off
|
||||
histverify off
|
||||
huponexit off
|
||||
inherit_errexit off
|
||||
lastpipe off
|
||||
lithist off
|
||||
login_shell off
|
||||
|
||||
+4
-1
@@ -4452,7 +4452,10 @@ push_func_var (data)
|
||||
if (array_p (var) || assoc_p (var))
|
||||
{
|
||||
FREE (value_cell (v));
|
||||
var_setvalue (v, array_p (var) ? array_copy (array_cell (var)) : assoc_copy (assoc_cell (var)));
|
||||
if (array_p (var))
|
||||
var_setarray (v, array_copy (array_cell (var)));
|
||||
else
|
||||
var_setassoc (v, assoc_copy (assoc_cell (var)));
|
||||
}
|
||||
#endif
|
||||
if (shell_variables == global_variables)
|
||||
|
||||
@@ -64,13 +64,13 @@ shell_version_string ()
|
||||
if (tt[0] == '\0')
|
||||
{
|
||||
if (release_status)
|
||||
#if defined (HAVE_SNPRINTF)
|
||||
#if HAVE_SNPRINTF
|
||||
snprintf (tt, sizeof (tt), "%s.%d(%d)-%s", dist_version, patch_level, build_version, release_status);
|
||||
#else
|
||||
sprintf (tt, "%s.%d(%d)-%s", dist_version, patch_level, build_version, release_status);
|
||||
#endif
|
||||
else
|
||||
#if defined (HAVE_SNPRINTF)
|
||||
#if HAVE_SNPRINTF
|
||||
snprintf (tt, sizeof (tt), "%s.%d(%d)", dist_version, patch_level, build_version);
|
||||
#else
|
||||
sprintf (tt, "%s.%d(%d)", dist_version, patch_level, build_version);
|
||||
|
||||
+2
-2
@@ -64,13 +64,13 @@ shell_version_string ()
|
||||
if (tt[0] == '\0')
|
||||
{
|
||||
if (release_status)
|
||||
#if defined (HAVE_SNPRINTF)
|
||||
#if HAVE_SNPRINTF
|
||||
snprintf (tt, sizeof (tt), "%s.%d(%d)-%s", dist_version, patch_level, build_version, release_status);
|
||||
#else
|
||||
sprintf (tt, "%s.%d(%d)-%s", dist_version, patch_level, build_version, release_status);
|
||||
#endif
|
||||
else
|
||||
#if defined (HAVE_SNPRINTF)
|
||||
#if HAVE_SNPRINTF
|
||||
snprintf (tt, sizeof (tt), "%s.%d(%d)", dist_version, patch_level, build_version);
|
||||
#else
|
||||
sprintf (tt, "%s.%d(%d)", dist_version, patch_level, build_version);
|
||||
|
||||
Reference in New Issue
Block a user