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
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
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
/* 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
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;
{
t = find_alias (name);
if (t)
- print_alias (t, dflags);
+ {
+ if (print_alias (t, dflags) != EXECUTION_SUCCESS)
+ return (EXECUTION_FAILURE);
+ }
else
{
sh_notfound (name);
}
/* 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;
printf ("%s=%s\n", alias->name, value);
free (value);
- fflush (stdout);
+ return (sh_chkwrite (EXECUTION_SUCCESS));
}
#endif /* ALIAS */
/* 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)
#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 ();
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)
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);
}
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';
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 --
${THIS_SH} ./printf2.sub
${THIS_SH} ./printf3.sub
${THIS_SH} ./printf4.sub
+${THIS_SH} ./printf5.sub
--- /dev/null
+# 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
# 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
--- /dev/null
+# 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