mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-28 07:59:50 +02:00
posix conformance fixes
This commit is contained in:
@@ -5534,3 +5534,40 @@ parse.y
|
||||
examples/loadables/kv.c
|
||||
- kv: new loadable builtin, reads key-value pairs from stdin and assigns
|
||||
them to an associative array
|
||||
|
||||
3/7
|
||||
---
|
||||
builtins/trap.def
|
||||
- trap_builtin: if trying to restore SIGQUIT to its default disposition,
|
||||
and the shell is in posix mode, set to SIG_DFL if the shell is
|
||||
running as an async command and signal_is_async_ignored (SIGQUIT) is
|
||||
true. Posix conformance issue 751
|
||||
|
||||
3/8
|
||||
---
|
||||
builtins/alias.def
|
||||
- print_alias: now returns int. Check for write errors using sh_chkwrite
|
||||
and return EXECUTION_FAILURE if it fails
|
||||
- alias_builtin: if print_alias returns EXECUTION_FAILURE, return
|
||||
EXECUTION_FAILURE immediately (write error). POSIX test conformance
|
||||
|
||||
3/9
|
||||
---
|
||||
builtins/cd.def
|
||||
- change_to_directory: if we're not in physical mode and are in posix
|
||||
mode, add step 9 of the posix cd algorithm, which essentially tries
|
||||
the pathname the user supplied if it's shorter than PATH_MAX and the
|
||||
length of the canonicalized pathname is longer than PATH_MAX. This
|
||||
is basically what default bash mode does without the length checks.
|
||||
POSIX test conformance.
|
||||
|
||||
subst.c
|
||||
- strip_trailing_ifs_whitespace: use ifs_whitespace(*s) instead of
|
||||
spctabnl(*s) like word splitting and get_word_from_string. POSIX
|
||||
test conformance
|
||||
|
||||
jobs.c
|
||||
- wait_for: tweak change from 1/18 to make sure a J_ASYNC job isn't in
|
||||
the foreground (J_FOREGROUND) as it would be if it had been continued
|
||||
in the foreground with `fg'; if it is, we want to give the terminal
|
||||
back to shell_pgrp
|
||||
|
||||
@@ -1339,6 +1339,7 @@ tests/printf1.sub f
|
||||
tests/printf2.sub f
|
||||
tests/printf3.sub f
|
||||
tests/printf4.sub f
|
||||
tests/printf5.sub f
|
||||
tests/procsub.tests f
|
||||
tests/procsub.right f
|
||||
tests/procsub1.sub f
|
||||
@@ -1366,6 +1367,7 @@ tests/read5.sub f
|
||||
tests/read6.sub f
|
||||
tests/read7.sub f
|
||||
tests/read8.sub f
|
||||
tests/read9.sub f
|
||||
tests/redir.tests f
|
||||
tests/redir.right f
|
||||
tests/redir1.sub f
|
||||
|
||||
+11
-7
@@ -63,7 +63,7 @@ $END
|
||||
/* Flags for print_alias */
|
||||
#define AL_REUSABLE 0x01
|
||||
|
||||
static void print_alias (alias_t *, int);
|
||||
static int print_alias (alias_t *, int);
|
||||
|
||||
/* Hack the alias command in a Korn shell way. */
|
||||
int
|
||||
@@ -103,13 +103,14 @@ alias_builtin (WORD_LIST *list)
|
||||
if (alias_list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
any_failed = EXECUTION_SUCCESS;
|
||||
for (offset = 0; alias_list[offset]; offset++)
|
||||
print_alias (alias_list[offset], dflags);
|
||||
if (any_failed = print_alias (alias_list[offset], dflags) != EXECUTION_SUCCESS)
|
||||
break;
|
||||
|
||||
free (alias_list); /* XXX - Do not free the strings. */
|
||||
|
||||
if (list == 0)
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
return (any_failed != EXECUTION_SUCCESS ? EXECUTION_FAILURE : sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
any_failed = 0;
|
||||
@@ -137,7 +138,10 @@ alias_builtin (WORD_LIST *list)
|
||||
{
|
||||
t = find_alias (name);
|
||||
if (t)
|
||||
print_alias (t, dflags);
|
||||
{
|
||||
if (print_alias (t, dflags) != EXECUTION_SUCCESS)
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_notfound (name);
|
||||
@@ -221,7 +225,7 @@ unalias_builtin (WORD_LIST *list)
|
||||
}
|
||||
|
||||
/* Output ALIAS in such a way as to allow it to be read back in. */
|
||||
static void
|
||||
static int
|
||||
print_alias (alias_t *alias, int flags)
|
||||
{
|
||||
char *value;
|
||||
@@ -232,6 +236,6 @@ print_alias (alias_t *alias, int flags)
|
||||
printf ("%s=%s\n", alias->name, value);
|
||||
free (value);
|
||||
|
||||
fflush (stdout);
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
#endif /* ALIAS */
|
||||
|
||||
+11
-3
@@ -654,9 +654,17 @@ change_to_directory (char *newdir, int nolinks, int xattr)
|
||||
|
||||
/* We're not in physical mode (nolinks == 0), but we failed to change to
|
||||
the canonicalized directory name (TDIR). Try what the user passed
|
||||
verbatim. If we succeed, reinitialize the_current_working_directory.
|
||||
POSIX requires that we just fail here, so we do in posix mode. */
|
||||
if (posixly_correct == 0 && chdir (newdir) == 0)
|
||||
verbatim. If we succeed, reinitialize the_current_working_directory. */
|
||||
|
||||
/* The first block is step 9 in the POSIX cd algorithm. */
|
||||
if (posixly_correct && ndlen < PATH_MAX && strlen (tdir) >= PATH_MAX)
|
||||
r = chdir (newdir);
|
||||
else if (posixly_correct == 0)
|
||||
r = chdir (newdir);
|
||||
else
|
||||
r = -1;
|
||||
|
||||
if (r == 0)
|
||||
{
|
||||
t = resetpwd ("cd");
|
||||
if (t == 0)
|
||||
|
||||
@@ -123,8 +123,6 @@ command_builtin (WORD_LIST *list)
|
||||
|
||||
#define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN | (use_standard_path ? CMD_STDPATH : 0))
|
||||
|
||||
INTERNAL_DEBUG (("command_builtin: running execute_command for `%s'", list->word->word));
|
||||
|
||||
/* We don't want this to be reparsed (consider command echo 'foo &'), so
|
||||
just make a simple_command structure and call execute_command with it. */
|
||||
command = make_bare_simple_command ();
|
||||
|
||||
+7
-2
@@ -251,8 +251,13 @@ trap_builtin (WORD_LIST *list)
|
||||
break;
|
||||
|
||||
case SIGQUIT:
|
||||
/* Always ignore SIGQUIT. */
|
||||
set_signal_handler (SIGQUIT, SIG_IGN);
|
||||
/* Always ignore SIGQUIT, but allow a posix-mode shell
|
||||
that is running asynchronously and has ignored
|
||||
SIGQUIT to reset it to the default. POSIX interp 751. */
|
||||
if (posixly_correct && signal_is_async_ignored (SIGQUIT))
|
||||
set_signal_handler (SIGQUIT, termsig_sighandler);
|
||||
else
|
||||
set_signal_handler (SIGQUIT, SIG_IGN);
|
||||
break;
|
||||
case SIGTERM:
|
||||
#if defined (JOB_CONTROL)
|
||||
|
||||
@@ -3011,10 +3011,12 @@ if (job == NO_JOB)
|
||||
subshell. Make sure subst.c:command_substitute uses the same
|
||||
conditions to determine whether or not it should undo this and
|
||||
give the terminal to pipeline_pgrp. We don't give the terminal
|
||||
back to shell_pgrp if an async job exits because we never gave it
|
||||
to that job in the first place. */
|
||||
back to shell_pgrp if an async job in the background exits because
|
||||
we never gave it to that job in the first place. An async job in
|
||||
the foreground is one we started in the background and foregrounded
|
||||
with `fg', and gave it the terminal. */
|
||||
if ((flags & JWAIT_NOTERM) == 0 && running_in_background == 0 &&
|
||||
(job == NO_JOB || IS_ASYNC (job) == 0) &&
|
||||
(job == NO_JOB || IS_ASYNC (job) == 0 || IS_FOREGROUND (job)) &&
|
||||
(subshell_environment & (SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0)
|
||||
give_terminal_to (shell_pgrp, 0);
|
||||
}
|
||||
|
||||
@@ -3299,7 +3299,7 @@ strip_trailing_ifs_whitespace (char *string, char *separators, int saw_escape)
|
||||
char *s;
|
||||
|
||||
s = string + STRLEN (string) - 1;
|
||||
while (s > string && ((spctabnl (*s) && isifs (*s)) ||
|
||||
while (s > string && ((ifs_whitespace (*s) && isifs (*s)) ||
|
||||
(saw_escape && *s == CTLESC && spctabnl (s[1]))))
|
||||
s--;
|
||||
*++s = '\0';
|
||||
|
||||
@@ -296,3 +296,23 @@ x +123x
|
||||
x +123x
|
||||
x +123x
|
||||
x +123x
|
||||
abcd
|
||||
ab
|
||||
123
|
||||
123
|
||||
173
|
||||
7b
|
||||
7B
|
||||
hello
|
||||
hello
|
||||
123
|
||||
6
|
||||
123 --
|
||||
123 --
|
||||
173 --
|
||||
7b --
|
||||
7B --
|
||||
hello --
|
||||
hello --
|
||||
123 --
|
||||
6 --
|
||||
|
||||
@@ -329,3 +329,4 @@ ${THIS_SH} ./printf1.sub
|
||||
${THIS_SH} ./printf2.sub
|
||||
${THIS_SH} ./printf3.sub
|
||||
${THIS_SH} ./printf4.sub
|
||||
${THIS_SH} ./printf5.sub
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
printf "%.4s\n" abcde
|
||||
printf "%.2b\n" abcde
|
||||
|
||||
printf "%4d\n" 123
|
||||
printf "%5i\n" 123
|
||||
printf "%4o\n" 123
|
||||
printf "%4x\n" 123
|
||||
printf "%4X\n" 123
|
||||
printf "%7b\n" hello
|
||||
printf "%6s\n" hello
|
||||
printf "%4u\n" 123
|
||||
printf "%2c\n" 65
|
||||
|
||||
printf "%-4d--\n" 123
|
||||
printf "%-5i--\n" 123
|
||||
printf "%-4o--\n" 123
|
||||
printf "%-4x--\n" 123
|
||||
printf "%-4X--\n" 123
|
||||
printf "%-7b--\n" hello
|
||||
printf "%-6s--\n" hello
|
||||
printf "%-4u--\n" 123
|
||||
printf "%-2c--\n" 65
|
||||
@@ -115,3 +115,6 @@ ${THIS_SH} ./read7.sub
|
||||
|
||||
# test behavior of read -n and read -d on regular files
|
||||
${THIS_SH} ./read8.sub
|
||||
|
||||
# test behavior of trailing IFS whitespace - POSIX conformance
|
||||
${THIS_SH} ./read9.sub
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
: ${TMPDIR:=/var/tmp}
|
||||
|
||||
TESTDIR=${TMPDIR}/read9-test-$$
|
||||
mkdir ${TESTDIR}
|
||||
cd $TESTDIR || {
|
||||
echo "$TESTDIR: cannot cd" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
printf ' line\tb \t\r\f\v\n' > read9.stdin || exit 1
|
||||
printf 'var1=" line", var2="b "\n' > read9.expout || exit 1
|
||||
|
||||
IFS=$'\t\r\f\v'
|
||||
|
||||
{
|
||||
# line 2
|
||||
unset var1 var2
|
||||
read var1 var2 &&
|
||||
printf 'var1="%s", var2="%s"\n' "$var1" "$var2"
|
||||
} < read9.stdin > read9.stdout 2>&1
|
||||
|
||||
cmp read9.expout read9.stdout || {
|
||||
echo "read9.sub: expected output and actual output differ"
|
||||
diff read9.expout read9.stdout
|
||||
}
|
||||
|
||||
cd $OLDPWD
|
||||
rm -rf $TESTDIR
|
||||
Reference in New Issue
Block a user