commit bash-20190220 snapshot

This commit is contained in:
Chet Ramey
2019-02-22 09:14:00 -05:00
parent be4078d25f
commit 9e48f85654
13 changed files with 422 additions and 33 deletions
+41
View File
@@ -5317,3 +5317,44 @@ jobs.c
an interactive shell reported by Grisha Levit
<grishalevit@gmail.com>
2/19
----
jobs.c
- end_job_control: if the setpgid(0, ...) succeeds, reset the value of
shell_pgrp. Fixes pgrp mismatch after failed exec in an interactive
login shell reported by Grisha Levit <grishalevit@gmail.com>
2/20
----
bashhist.c
- pre_process_line: save history_length before calling history_expand,
and after possibly decrementing history_length, just restore the old
value instead of incrementing it. Fixes bug reported by
Michael Albinus <michael.albinus@gmx.de>
- bash_add_history: don't bother calling really_add_history if the
history is stifled and the max number of entries is 0
aclocal.m4,configure.ac,m4/*.m4
- replace the old set of gettext m4 macros with the latest m4 files
from the gnulib and gettext distributions
2/21
----
builtins/cd.def
- bindpwd: initialize canon_failed to 0 to prevent `cd -e' from always
failing
command.h
- W_EXPANDRHS: new flag, set when expanding WORD in ${paramOPword}
subst.c
- expand_string_for_rhs: set W_EXPANDRHS in word to be expanded
subst.c
- expand_word_internal: when encountering a single or double quoted
string that expands to nothing, add a CTLNUL if the W_EXPANDRHS
flag is set and the word isn't quoted, indicating that the word
will eventually be split and we need to preserve the null to
produce an empty word. From a discussion on bug-bash started by
sunnycemetery@gmail.com
+1
View File
@@ -502,6 +502,7 @@ m4/nls.m4 f
m4/po.m4 f
m4/printf-posix.m4 f
m4/progtest.m4 f
m4/pthread_rwlock_rdlock.m4 f
m4/size_max.m4 f
m4/stdint_h.m4 f
m4/threadlib.m4 f
+7 -1
View File
@@ -560,15 +560,18 @@ pre_process_line (line, print_changes, addit)
add that line to the history if ADDIT is non-zero. */
if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
{
int old_len;
/* If we are expanding the second or later line of a multi-line
command, decrease history_length so references to history expansions
in these lines refer to the previous history entry and not the
current command. */
old_len = history_length;
if (history_length > 0 && command_oriented_history && current_command_first_line_saved && current_command_line_count > 1)
history_length--;
expanded = history_expand (line, &history_value);
if (history_length >= 0 && command_oriented_history && current_command_first_line_saved && current_command_line_count > 1)
history_length++;
history_length = old_len;
if (expanded)
{
@@ -908,6 +911,9 @@ bash_add_history (line)
}
}
if (add_it && history_is_stifled() && history_length == 0 && history_length == history_max_entries)
add_it = 0;
if (add_it)
really_add_history (line);
+1
View File
@@ -149,6 +149,7 @@ bindpwd (no_symlinks)
#undef tcwd
/* If canonicalization fails, reset dirname to the_current_working_directory */
canon_failed = 0;
if (dirname == 0)
{
canon_failed = 1;
+2 -1
View File
@@ -87,7 +87,7 @@ enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
#define W_ASSIGNRHS 0x000800 /* Word is rhs of an assignment statement */
#define W_NOTILDE 0x001000 /* Don't perform tilde expansion on this word */
#define W_ITILDE 0x002000 /* Internal flag for word expansion */
#define W_NOEXPAND 0x004000 /* Don't expand at all -- do quote removal */
#define W_EXPANDRHS 0x004000 /* Expanding word in ${paramOPword} */
#define W_COMPASSIGN 0x008000 /* Compound assignment */
#define W_ASSNBLTIN 0x010000 /* word is a builtin command that takes assignments */
#define W_ASSIGNARG 0x020000 /* word is assignment argument to command */
@@ -111,6 +111,7 @@ enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
#define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */
#define PF_ASSIGNRHS 0x08 /* same as W_ASSIGNRHS */
#define PF_COMPLETE 0x10 /* same as W_COMPLETE, sets SX_COMPLETE */
#define PF_EXPANDRHS 0x20 /* same as W_EXPANDRHS */
/* Possible values for subshell_environment */
#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */
Vendored
+155 -2
View File
@@ -1,5 +1,5 @@
#! /bin/sh
# From configure.ac for Bash 5.0, version 5.007.
# From configure.ac for Bash 5.0, version 5.008.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for bash 5.0-maint.
#
@@ -6242,6 +6242,11 @@ fi
# pthread_rwlock_rdlock.m4 serial 2
# size_max.m4 serial 11
@@ -9642,7 +9647,155 @@ $as_echo "#define HAVE_PTHREAD_RWLOCK 1" >>confdefs.h
fi
if $has_rwlock; then
gl_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthread_rwlock_rdlock prefers a writer to a reader" >&5
$as_echo_n "checking whether pthread_rwlock_rdlock prefers a writer to a reader... " >&6; }
if ${gl_cv_pthread_rwlock_rdlock_prefer_writer+:} false; then :
$as_echo_n "(cached) " >&6
else
save_LIBS="$LIBS"
LIBS="$LIBS $LIBMULTITHREAD"
if test "$cross_compiling" = yes; then :
gl_cv_pthread_rwlock_rdlock_prefer_writer="guessing yes"
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#define SUCCEED() exit (0)
#define FAILURE() exit (1)
#define UNEXPECTED(n) (exit (10 + (n)))
/* The main thread creates the waiting writer and the requesting reader threads
in the default way; this guarantees that they have the same priority.
We can reuse the main thread as first reader thread. */
static pthread_rwlock_t lock;
static pthread_t reader1;
static pthread_t writer;
static pthread_t reader2;
static pthread_t timer;
/* Used to pass control from writer to reader2 and from reader2 to timer,
as in a relay race.
Passing control from one running thread to another running thread
is most likely faster than to create the second thread. */
static pthread_mutex_t baton;
static void *
timer_func (void *ignored)
{
/* Step 13 (can be before or after step 12):
The timer thread takes the baton, then waits a moment to make sure
it can tell whether the second reader thread is blocked at step 12. */
if (pthread_mutex_lock (&baton))
UNEXPECTED (13);
usleep (100000);
/* By the time we get here, it's clear that the second reader thread is
blocked at step 12. This is the desired behaviour. */
SUCCEED ();
}
static void *
reader2_func (void *ignored)
{
int err;
/* Step 8 (can be before or after step 7):
The second reader thread takes the baton, then waits a moment to make sure
the writer thread has reached step 7. */
if (pthread_mutex_lock (&baton))
UNEXPECTED (8);
usleep (100000);
/* Step 9: The second reader thread requests the lock. */
err = pthread_rwlock_tryrdlock (&lock);
if (err == 0)
FAILURE ();
else if (err != EBUSY)
UNEXPECTED (9);
/* Step 10: Launch a timer, to test whether the next call blocks. */
if (pthread_create (&timer, NULL, timer_func, NULL))
UNEXPECTED (10);
/* Step 11: Release the baton. */
if (pthread_mutex_unlock (&baton))
UNEXPECTED (11);
/* Step 12: The second reader thread requests the lock. */
err = pthread_rwlock_rdlock (&lock);
if (err == 0)
FAILURE ();
else
UNEXPECTED (12);
}
static void *
writer_func (void *ignored)
{
/* Step 4: Take the baton, so that the second reader thread does not go ahead
too early. */
if (pthread_mutex_lock (&baton))
UNEXPECTED (4);
/* Step 5: Create the second reader thread. */
if (pthread_create (&reader2, NULL, reader2_func, NULL))
UNEXPECTED (5);
/* Step 6: Release the baton. */
if (pthread_mutex_unlock (&baton))
UNEXPECTED (6);
/* Step 7: The writer thread requests the lock. */
if (pthread_rwlock_wrlock (&lock))
UNEXPECTED (7);
return NULL;
}
int
main ()
{
reader1 = pthread_self ();
/* Step 1: The main thread initializes the lock and the baton. */
if (pthread_rwlock_init (&lock, NULL))
UNEXPECTED (1);
if (pthread_mutex_init (&baton, NULL))
UNEXPECTED (1);
/* Step 2: The main thread acquires the lock as a reader. */
if (pthread_rwlock_rdlock (&lock))
UNEXPECTED (2);
/* Step 3: Create the writer thread. */
if (pthread_create (&writer, NULL, writer_func, NULL))
UNEXPECTED (3);
/* Job done. Go to sleep. */
for (;;)
{
sleep (1);
}
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
gl_cv_pthread_rwlock_rdlock_prefer_writer=yes
else
gl_cv_pthread_rwlock_rdlock_prefer_writer=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
LIBS="$save_LIBS"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_pthread_rwlock_rdlock_prefer_writer" >&5
$as_echo "$gl_cv_pthread_rwlock_rdlock_prefer_writer" >&6; }
case "$gl_cv_pthread_rwlock_rdlock_prefer_writer" in
*yes)
$as_echo "#define HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER 1" >>confdefs.h
;;
esac
fi
# glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+2 -1
View File
@@ -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 5.0, version 5.007])dnl
AC_REVISION([for Bash 5.0, version 5.008])dnl
define(bashvers, 5.0)
define(relstatus, maint)
@@ -712,6 +712,7 @@ m4_include([m4/nls.m4])
m4_include([m4/po.m4])
m4_include([m4/printf-posix.m4])
m4_include([m4/progtest.m4])
m4_include([m4/pthread_rwlock_rdlock.m4])
m4_include([m4/size_max.m4])
m4_include([m4/stdint_h.m4])
m4_include([m4/threadlib.m4])
+1 -1
View File
@@ -7188,7 +7188,7 @@ is also accepted; the @var{subscript} is ignored.
@noindent
Associative arrays are created using
@example
declare -A @var{name}.
declare -A @var{name}
@end example
Attributes may be
+2 -2
View File
@@ -4844,8 +4844,8 @@ end_job_control ()
if (original_pgrp >= 0 && terminal_pgrp != original_pgrp)
give_terminal_to (original_pgrp, 1);
if (original_pgrp >= 0)
setpgid (0, original_pgrp);
if (original_pgrp >= 0 && setpgid (0, original_pgrp) == 0)
shell_pgrp = original_pgrp;
}
/* Restart job control by closing shell tty and reinitializing. This is
+165
View File
@@ -0,0 +1,165 @@
# pthread_rwlock_rdlock.m4 serial 2
dnl Copyright (C) 2017-2019 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
dnl Inspired by
dnl https://github.com/linux-test-project/ltp/blob/master/testcases/open_posix_testsuite/conformance/interfaces/pthread_rwlock_rdlock/2-2.c
dnl by Intel Corporation.
dnl Test whether in a situation where
dnl - an rwlock is taken by a reader and has a writer waiting,
dnl - an additional reader requests the lock,
dnl - the waiting writer and the requesting reader threads have the same
dnl priority,
dnl the requesting reader thread gets blocked, so that at some point the
dnl waiting writer can acquire the lock.
dnl Without such a guarantee, when there a N readers and each of the readers
dnl spends more than 1/Nth of the time with the lock held, there is a high
dnl probability that the waiting writer will not get the lock in a given finite
dnl time, a phenomenon called "writer starvation".
dnl Without such a guarantee, applications have a hard time avoiding writer
dnl starvation.
dnl
dnl POSIX:2017 makes this requirement only for implementations that support TPS
dnl (Thread Priority Scheduling) and only for the scheduling policies SCHED_FIFO
dnl and SCHED_RR, see
dnl http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_rdlock.html
dnl but this test verifies the guarantee regardless of TPS and regardless of
dnl scheduling policy.
dnl Glibc currently does not provide this guarantee, see
dnl https://sourceware.org/bugzilla/show_bug.cgi?id=13701
AC_DEFUN([gl_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER],
[
AC_REQUIRE([gl_THREADLIB_EARLY])
AC_CACHE_CHECK([whether pthread_rwlock_rdlock prefers a writer to a reader],
[gl_cv_pthread_rwlock_rdlock_prefer_writer],
[save_LIBS="$LIBS"
LIBS="$LIBS $LIBMULTITHREAD"
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#define SUCCEED() exit (0)
#define FAILURE() exit (1)
#define UNEXPECTED(n) (exit (10 + (n)))
/* The main thread creates the waiting writer and the requesting reader threads
in the default way; this guarantees that they have the same priority.
We can reuse the main thread as first reader thread. */
static pthread_rwlock_t lock;
static pthread_t reader1;
static pthread_t writer;
static pthread_t reader2;
static pthread_t timer;
/* Used to pass control from writer to reader2 and from reader2 to timer,
as in a relay race.
Passing control from one running thread to another running thread
is most likely faster than to create the second thread. */
static pthread_mutex_t baton;
static void *
timer_func (void *ignored)
{
/* Step 13 (can be before or after step 12):
The timer thread takes the baton, then waits a moment to make sure
it can tell whether the second reader thread is blocked at step 12. */
if (pthread_mutex_lock (&baton))
UNEXPECTED (13);
usleep (100000);
/* By the time we get here, it's clear that the second reader thread is
blocked at step 12. This is the desired behaviour. */
SUCCEED ();
}
static void *
reader2_func (void *ignored)
{
int err;
/* Step 8 (can be before or after step 7):
The second reader thread takes the baton, then waits a moment to make sure
the writer thread has reached step 7. */
if (pthread_mutex_lock (&baton))
UNEXPECTED (8);
usleep (100000);
/* Step 9: The second reader thread requests the lock. */
err = pthread_rwlock_tryrdlock (&lock);
if (err == 0)
FAILURE ();
else if (err != EBUSY)
UNEXPECTED (9);
/* Step 10: Launch a timer, to test whether the next call blocks. */
if (pthread_create (&timer, NULL, timer_func, NULL))
UNEXPECTED (10);
/* Step 11: Release the baton. */
if (pthread_mutex_unlock (&baton))
UNEXPECTED (11);
/* Step 12: The second reader thread requests the lock. */
err = pthread_rwlock_rdlock (&lock);
if (err == 0)
FAILURE ();
else
UNEXPECTED (12);
}
static void *
writer_func (void *ignored)
{
/* Step 4: Take the baton, so that the second reader thread does not go ahead
too early. */
if (pthread_mutex_lock (&baton))
UNEXPECTED (4);
/* Step 5: Create the second reader thread. */
if (pthread_create (&reader2, NULL, reader2_func, NULL))
UNEXPECTED (5);
/* Step 6: Release the baton. */
if (pthread_mutex_unlock (&baton))
UNEXPECTED (6);
/* Step 7: The writer thread requests the lock. */
if (pthread_rwlock_wrlock (&lock))
UNEXPECTED (7);
return NULL;
}
int
main ()
{
reader1 = pthread_self ();
/* Step 1: The main thread initializes the lock and the baton. */
if (pthread_rwlock_init (&lock, NULL))
UNEXPECTED (1);
if (pthread_mutex_init (&baton, NULL))
UNEXPECTED (1);
/* Step 2: The main thread acquires the lock as a reader. */
if (pthread_rwlock_rdlock (&lock))
UNEXPECTED (2);
/* Step 3: Create the writer thread. */
if (pthread_create (&writer, NULL, writer_func, NULL))
UNEXPECTED (3);
/* Job done. Go to sleep. */
for (;;)
{
sleep (1);
}
}
]])],
[gl_cv_pthread_rwlock_rdlock_prefer_writer=yes],
[gl_cv_pthread_rwlock_rdlock_prefer_writer=no],
[gl_cv_pthread_rwlock_rdlock_prefer_writer="guessing yes"])
LIBS="$save_LIBS"
])
case "$gl_cv_pthread_rwlock_rdlock_prefer_writer" in
*yes)
AC_DEFINE([HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER], [1],
[Define if the 'pthread_rwlock_rdlock' function prefers a writer to a reader.])
;;
esac
])
+20 -9
View File
@@ -428,10 +428,10 @@ dump_word_flags (flags)
f &= ~W_COMPASSIGN;
fprintf (stderr, "W_COMPASSIGN%s", f ? "|" : "");
}
if (f & W_NOEXPAND)
if (f & W_EXPANDRHS)
{
f &= ~W_NOEXPAND;
fprintf (stderr, "W_NOEXPAND%s", f ? "|" : "");
f &= ~W_EXPANDRHS;
fprintf (stderr, "W_EXPANDRHS%s", f ? "|" : "");
}
if (f & W_ITILDE)
{
@@ -3899,7 +3899,8 @@ expand_string_for_rhs (string, quoted, op, pflags, dollar_at_p, expanded_p)
in Posix bug 1129 */
old_nosplit = expand_no_split_dollar_star;
expand_no_split_dollar_star = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || op == '=' || ifs_is_null == 0; /* XXX - was 1 */
td.flags = W_NOSPLIT2; /* no splitting, remove "" and '' */
td.flags = W_EXPANDRHS; /* expanding RHS of ${paramOPword */
td.flags |= W_NOSPLIT2; /* no splitting, remove "" and '' */
if (pflags & PF_ASSIGNRHS) /* pass through */
td.flags |= W_ASSIGNRHS;
if (op == '=')
@@ -10296,6 +10297,13 @@ add_twochars:
this is when we are going to be performing word splitting,
since we have to preserve a null argument if the next character
will cause word splitting. */
if (temp == 0 && quoted_state == PARTIALLY_QUOTED && quoted == 0 && (word->flags & W_NOSPLIT) == 0 && (word->flags & W_EXPANDRHS))
{
c = CTLNUL;
sindex--;
had_quoted_null = 1;
goto add_character;
}
if (temp == 0 && quoted_state == PARTIALLY_QUOTED && (word->flags & (W_NOSPLIT|W_NOSPLIT2)))
continue;
@@ -10347,7 +10355,14 @@ add_twochars:
/* We do not want to add quoted nulls to strings that are only
partially quoted; such nulls are discarded. See above for the
exception, which is when the string is going to be split.
Posix interp 888 */
Posix interp 888/1129 */
if (temp == 0 && quoted_state == PARTIALLY_QUOTED && quoted == 0 && (word->flags & W_NOSPLIT) == 0 && (word->flags & W_EXPANDRHS))
{
c = CTLNUL;
sindex--;
goto add_character;
}
if (temp == 0 && (quoted_state == PARTIALLY_QUOTED) && (word->flags & (W_NOSPLIT|W_NOSPLIT2)))
continue;
@@ -10478,8 +10493,6 @@ finished_with_string:
tword->flags |= W_NOGLOB; /* XXX */
if (word->flags & W_NOBRACE)
tword->flags |= W_NOBRACE; /* XXX */
if (word->flags & W_NOEXPAND)
tword->flags |= W_NOEXPAND; /* XXX */
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
tword->flags |= W_QUOTED;
list = make_word_list (tword, (WORD_LIST *)NULL);
@@ -10577,8 +10590,6 @@ set_word_flags:
tword->flags |= W_NOGLOB;
if (word->flags & W_NOBRACE)
tword->flags |= W_NOBRACE;
if (word->flags & W_NOEXPAND)
tword->flags |= W_NOEXPAND;
list = make_word_list (tword, (WORD_LIST *)NULL);
}
}
+1
View File
@@ -226,6 +226,7 @@ null fields in rhs
null string with unquoted $@
argv[1] = <>
null string with quoted $@
argv[1] = <>
assignment
argv[1] = <>
variable
+24 -16
View File
@@ -94,7 +94,29 @@ argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[2] = <>
argv[1] = <>
argv[2] = <>
argv[1] = <>
=====
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[2] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[2] = <>
=====
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[2] = <>
argv[1] = <>
argv[2] = <>
argv[1] = <>
=====
argv[1] = <>
@@ -102,21 +124,7 @@ argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[2] = <>
argv[1] = <>
argv[1] = <>
=====
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
=====
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[2] = <>
argv[1] = <>