commit bash-20060606 snapshot

This commit is contained in:
Chet Ramey
2011-12-03 22:49:22 -05:00
parent c05b8e9913
commit 2872b01afc
17 changed files with 487 additions and 37 deletions
+6
View File
@@ -114,6 +114,12 @@ ii. Fixed a bug that could cause file descriptors > 10 to not be closed even
jj. Fixed a bug that caused single quotes to be stripped from ANSI-C quoting
inside double-quoted command substitutions.
kk. Fixed a bug that could cause core dumps when `return' was executed as the
last element of a pipeline inside a shell function.
ll. Fixed a bug that caused DEBUG trap strings to overwrite commands stored in
the jobs list.
2. Changes to Readline
a. Fixed a problem that caused segmentation faults when using readline in
+6
View File
@@ -111,6 +111,9 @@ hh. Fixed a bug that caused `unset LANG' to not properly reset the locale
ii. Fixed a bug that could cause file descriptors > 10 to not be closed even
when closed explicitly by a script.
jj. Fixed a bug that caused single quotes to be stripped from ANSI-C quoting
inside double-quoted command substitutions.
2. Changes to Readline
a. Fixed a problem that caused segmentation faults when using readline in
@@ -156,6 +159,9 @@ l. Fixed a problem with the callback interface that caused it to fail when
m. Fixed a bug that could cause a core dump when an edited history entry was
re-executed under certain conditions.
n. Fixed a bug that caused readline to reference freed memory when attmpting
to display a portion of the prompt.
3. New Features in Bash
a. Changed the parameter pattern replacement functions to not anchor the
+18 -1
View File
@@ -13438,4 +13438,21 @@ subst.c
- make sure that parameter_brace_substring leaves this_command_name
set to either NULL or its previous value after setting it so that
arithmetic evaluation errors while expanding substring values
contain meaningful informationn
contain meaningful information
6/9
---
execute_cmd.c
- make sure that SUBSHELL_ASYNC and SUBSHELL_PIPE are set as flag bits
in subshell_environment, rather than setting only a single value
- change execute_subshell_builtin_or_function to give the `return'
builtin a place to longjmp to when executed in a subshell or pipeline
(mostly as the last command in a pipeline). Bug reported by
Oleg Verych <olecom@gmail.com>
- in execute_simple_command, make sure to call execute_disk_command
with the_printed_command_except_trap to keep DEBUG trap command
strings from overwriting the command strings associated with jobs
and printed in job control messages. Bug reported by Daniel Kahn
Gillmor <dkg-debian.org@fifthhorseman.net>
[bash-3.2-alpha frozen]
+38 -1
View File
@@ -13414,6 +13414,43 @@ lib/readline/undo.c
- new function, alloc_undo_entry (enum undo_code what, int start, int end, char *text)
takes care of allocating and populating a struct for an individual
undo list entry
- new function: _rl_copy_undo_entry(UNDO_LIST *entry)
- new function: _rl_copy_undo_list(UNDO_LIST *head)
lib/readline/rlprivate.h
- new extern declarations for _rl_copy_undo_{entry,list}
execute_cmd.c
- change execute_cond_node so that quoting the rhs of the =~
operator forces string matching, like the == and != operators
5/23
----
redir.c
- add_undo_redirect now takes as an additional argument the type of
redirection we're trying to undo
- don't add a "preservation" redirection for fds > SHELL_FD_BASE if
the redirection is closing the fd
5/24
----
subst.c
- make sure that parameter_brace_substring leaves this_command_name
set to either NULL or its previous value after setting it so that
arithmetic evaluation errors while expanding substring values
contain meaningful information
6/9
---
execute_cmd.c
- make sure that SUBSHELL_ASYNC and SUBSHELL_PIPE are set as flag bits
in subshell_environment, rather than setting only a single value
- change execute_subshell_builtin_or_function to give the `return'
builtin a place to longjmp to when executed in a subshell or pipeline
(mostly as the last command in a pipeline). Bug reported by
Oleg Verych <olecom@gmail.com>
- in execute_simple_command, make sure to call execute_disk_command
with the_printed_command_except_trap to keep DEBUG trap command
strings from overwriting the command strings associated with jobs
and printed in job control messages. Bug reported by Daniel Kahn
Gillmor <dkg-debian.org@fifthhorseman.net>
+1 -1
View File
@@ -499,7 +499,7 @@ CREATED_SUPPORT = signames.h recho$(EXEEXT) zecho$(EXEEXT) printenv$(EXEEXT) \
tests/recho$(EXEEXT) tests/zecho$(EXEEXT) \
tests/printenv$(EXEEXT) mksignames$(EXEEXT) lsignames.h \
mksyntax${EXEEXT} syntax.c $(VERSPROG) $(VERSOBJ) \
buildversion.o mksignames.o signames.o
buildversion.o mksignames.o signames.o buildsignames.o
CREATED_CONFIGURE = config.h config.cache config.status config.log \
stamp-h po/POTFILES
CREATED_MAKEFILES = Makefile builtins/Makefile doc/Makefile \
+10 -10
View File
@@ -1,7 +1,7 @@
@%:@! /bin/sh
@%:@ From configure.in for Bash 3.2, version 3.188.
@%:@ Guess values for system-dependent variables and create Makefiles.
@%:@ Generated by GNU Autoconf 2.59 for bash 3.2-alpha.
@%:@ Generated by GNU Autoconf 2.59 for bash 3.2-devel.
@%:@
@%:@ Report bugs to <bug-bash@gnu.org>.
@%:@
@@ -270,8 +270,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='bash'
PACKAGE_TARNAME='bash'
PACKAGE_VERSION='3.2-alpha'
PACKAGE_STRING='bash 3.2-alpha'
PACKAGE_VERSION='3.2-devel'
PACKAGE_STRING='bash 3.2-devel'
PACKAGE_BUGREPORT='bug-bash@gnu.org'
ac_unique_file="shell.h"
@@ -785,7 +785,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures bash 3.2-alpha to adapt to many kinds of systems.
\`configure' configures bash 3.2-devel to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -846,7 +846,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of bash 3.2-alpha:";;
short | recursive ) echo "Configuration of bash 3.2-devel:";;
esac
cat <<\_ACEOF
@@ -1039,7 +1039,7 @@ fi
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
bash configure 3.2-alpha
bash configure 3.2-devel
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
@@ -1053,7 +1053,7 @@ cat >&5 <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by bash $as_me 3.2-alpha, which was
It was created by bash $as_me 3.2-devel, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
@@ -1422,7 +1422,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
BASHVERS=3.2
RELSTATUS=alpha
RELSTATUS=devel
case "$RELSTATUS" in
alp*|bet*|dev*|rc*) DEBUG='-DDEBUG' MALLOC_DEBUG='-DMALLOC_DEBUG' ;;
@@ -27484,7 +27484,7 @@ _ASBOX
} >&5
cat >&5 <<_CSEOF
This file was extended by bash $as_me 3.2-alpha, which was
This file was extended by bash $as_me 3.2-devel, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -27547,7 +27547,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
bash config.status 3.2-alpha
bash config.status 3.2-devel
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+1 -1
View File
@@ -1,4 +1,4 @@
m4trace:configure.in:30: -1- AC_INIT([bash], [3.2-alpha], [bug-bash@gnu.org])
m4trace:configure.in:30: -1- AC_INIT([bash], [3.2-devel], [bug-bash@gnu.org])
m4trace:configure.in:30: -1- m4_pattern_forbid([^_?A[CHUM]_])
m4trace:configure.in:30: -1- m4_pattern_forbid([_AC_])
m4trace:configure.in:30: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS'])
+1 -1
View File
@@ -25,7 +25,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_REVISION([for Bash 3.2, version 3.188])dnl
define(bashvers, 3.2)
define(relstatus, alpha)
define(relstatus, devel)
AC_INIT([bash], bashvers-relstatus, [bug-bash@gnu.org])
+29 -7
View File
@@ -1242,7 +1242,16 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
/* Subshells are neither login nor interactive. */
login_shell = interactive = 0;
subshell_environment = user_subshell ? SUBSHELL_PAREN : SUBSHELL_ASYNC;
if (user_subshell)
subshell_environment = SUBSHELL_PAREN;
else
{
subshell_environment = 0; /* XXX */
if (asynchronous)
subshell_environment |= SUBSHELL_ASYNC;
if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
subshell_environment |= SUBSHELL_PIPE;
}
reset_terminating_signals (); /* in sig.c */
/* Cancel traps, in trap.c. */
@@ -1330,8 +1339,7 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
if (function_value)
return_code = return_catch_value;
else
return_code = execute_command_internal
(tcom, asynchronous, NO_PIPE, NO_PIPE, fds_to_close);
return_code = execute_command_internal (tcom, asynchronous, NO_PIPE, NO_PIPE, fds_to_close);
/* If we are asked to, invert the return value. */
if (invert)
@@ -2641,7 +2649,10 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
do_piping (pipe_in, pipe_out);
subshell_environment = SUBSHELL_ASYNC;
if (async)
subshell_environment |= SUBSHELL_ASYNC;
if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
subshell_environment |= SUBSHELL_PIPE;
if (do_redirections (redirects, RX_ACTIVE) == 0)
exit (EXECUTION_SUCCESS);
@@ -3010,7 +3021,7 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
}
if (command_line == 0)
command_line = savestring (the_printed_command);
command_line = savestring (the_printed_command_except_trap);
execute_disk_command (words, simple_command->redirects, command_line,
pipe_in, pipe_out, async, fds_to_close,
@@ -3369,7 +3380,7 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var,
struct fd_bitmap *fds_to_close;
int flags;
{
int result, r;
int result, r, funcvalue;
#if defined (JOB_CONTROL)
int jobs_hack;
@@ -3380,7 +3391,10 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var,
/* A subshell is neither a login shell nor interactive. */
login_shell = interactive = 0;
subshell_environment = SUBSHELL_ASYNC;
if (async)
subshell_environment |= SUBSHELL_ASYNC;
if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
subshell_environment |= SUBSHELL_PIPE;
maybe_make_export_env (); /* XXX - is this needed? */
@@ -3414,10 +3428,18 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var,
so we don't go back up to main(). */
result = setjmp (top_level);
/* Give the return builtin a place to jump to when executed in a subshell
or pipeline */
funcvalue = 0;
if (return_catch_flag && builtin == return_builtin)
funcvalue = setjmp (return_catch);
if (result == EXITPROG)
exit (last_command_exit_value);
else if (result)
exit (EXECUTION_FAILURE);
else if (funcvalue)
exit (return_catch_value);
else
{
r = execute_builtin (builtin, words, flags, 1);
+34 -7
View File
@@ -1242,7 +1242,16 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
/* Subshells are neither login nor interactive. */
login_shell = interactive = 0;
subshell_environment = user_subshell ? SUBSHELL_PAREN : SUBSHELL_ASYNC;
if (user_subshell)
subshell_environment = SUBSHELL_PAREN;
else
{
subshell_environment = 0; /* XXX */
if (asynchronous)
subshell_environment |= SUBSHELL_ASYNC;
if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
subshell_environment |= SUBSHELL_PIPE;
}
reset_terminating_signals (); /* in sig.c */
/* Cancel traps, in trap.c. */
@@ -1330,8 +1339,7 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
if (function_value)
return_code = return_catch_value;
else
return_code = execute_command_internal
(tcom, asynchronous, NO_PIPE, NO_PIPE, fds_to_close);
return_code = execute_command_internal (tcom, asynchronous, NO_PIPE, NO_PIPE, fds_to_close);
/* If we are asked to, invert the return value. */
if (invert)
@@ -2503,6 +2511,7 @@ execute_cond_node (cond)
}
else if (cond->type == COND_BINARY)
{
rmatch = 0;
patmatch = ((cond->op->word[1] == '=') && (cond->op->word[2] == '\0') &&
(cond->op->word[0] == '!' || cond->op->word[0] == '=') ||
(cond->op->word[0] == '=' && cond->op->word[1] == '\0'));
@@ -2514,7 +2523,7 @@ execute_cond_node (cond)
arg1 = cond_expand_word (cond->left->op, 0);
if (arg1 == 0)
arg1 = nullstr;
arg2 = cond_expand_word (cond->right->op, patmatch);
arg2 = cond_expand_word (cond->right->op, patmatch||rmatch);
if (arg2 == 0)
arg2 = nullstr;
@@ -2640,7 +2649,10 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
do_piping (pipe_in, pipe_out);
subshell_environment = SUBSHELL_ASYNC;
if (async)
subshell_environment |= SUBSHELL_ASYNC;
if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
subshell_environment |= SUBSHELL_PIPE;
if (do_redirections (redirects, RX_ACTIVE) == 0)
exit (EXECUTION_SUCCESS);
@@ -3009,7 +3021,11 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
}
if (command_line == 0)
#if 0
command_line = savestring (the_printed_command);
#else
command_line = savestring (the_printed_command_except_trap);
#endif
execute_disk_command (words, simple_command->redirects, command_line,
pipe_in, pipe_out, async, fds_to_close,
@@ -3368,7 +3384,7 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var,
struct fd_bitmap *fds_to_close;
int flags;
{
int result, r;
int result, r, funcvalue;
#if defined (JOB_CONTROL)
int jobs_hack;
@@ -3379,7 +3395,10 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var,
/* A subshell is neither a login shell nor interactive. */
login_shell = interactive = 0;
subshell_environment = SUBSHELL_ASYNC;
if (async)
subshell_environment |= SUBSHELL_ASYNC;
if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
subshell_environment |= SUBSHELL_PIPE;
maybe_make_export_env (); /* XXX - is this needed? */
@@ -3413,10 +3432,18 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var,
so we don't go back up to main(). */
result = setjmp (top_level);
/* Give the return builtin a place to jump to when executed in a subshell
or pipeline */
funcvalue = 0;
if (return_catch_flag && builtin == return_builtin)
funcvalue = setjmp (return_catch);
if (result == EXITPROG)
exit (last_command_exit_value);
else if (result)
exit (EXECUTION_FAILURE);
else if (funcvalue)
exit (return_catch_value);
else
{
r = execute_builtin (builtin, words, flags, 1);
+1
View File
@@ -146,6 +146,7 @@ extern int interrupt_immediately;
extern int last_command_exit_value, last_command_exit_signal;
extern int loop_level, breaking;
extern int sourcelevel;
extern int running_trap;
extern sh_builtin_func_t *this_shell_builtin;
extern char *shell_name, *this_command_name;
extern sigset_t top_level_mask;
+14 -7
View File
@@ -77,8 +77,8 @@ extern int errno;
#endif /* !errno */
#define DEFAULT_CHILD_MAX 32
#if 1
#define MAX_JOBS_IN_ARRAY 4096 /* production*/
#if !defined (DEBUG)
#define MAX_JOBS_IN_ARRAY 4096 /* production */
#else
#define MAX_JOBS_IN_ARRAY 128 /* testing */
#endif
@@ -146,6 +146,7 @@ extern int interrupt_immediately;
extern int last_command_exit_value, last_command_exit_signal;
extern int loop_level, breaking;
extern int sourcelevel;
extern int running_trap;
extern sh_builtin_func_t *this_shell_builtin;
extern char *shell_name, *this_command_name;
extern sigset_t top_level_mask;
@@ -962,7 +963,7 @@ compact_jobs_list (flags)
reap_dead_jobs ();
realloc_jobs_list ();
return (js.j_lastj);
}
@@ -1078,6 +1079,7 @@ add_process (name, pid)
{
PROCESS *t, *p;
itrace("add_process: name = %s running_trap = %d", name, running_trap);
#if defined (RECYCLES_PIDS)
int j;
p = find_process (pid, 0, &j);
@@ -1230,8 +1232,9 @@ hangup_all_jobs ()
{
if (jobs[i])
{
if ((jobs[i]->flags & J_NOHUP) == 0)
killpg (jobs[i]->pgrp, SIGHUP);
if (jobs[i]->flags & J_NOHUP)
continue;
killpg (jobs[i]->pgrp, SIGHUP);
if (STOPPED (i))
killpg (jobs[i]->pgrp, SIGCONT);
}
@@ -1667,6 +1670,7 @@ make_child (command, async_p)
sigemptyset (&oset);
sigprocmask (SIG_BLOCK, &set, &oset);
itrace("make_child: command = %s", command ? command : "");
making_children ();
#if defined (BUFFERED_INPUT)
@@ -2968,6 +2972,7 @@ waitchld (wpid, block)
: 0;
if (sigchld || block == 0)
waitpid_flags |= WNOHANG;
CHECK_TERMSIG;
pid = WAITPID (-1, &status, waitpid_flags);
/* WCONTINUED may be rejected by waitpid as invalid even when defined */
@@ -2994,6 +2999,7 @@ waitchld (wpid, block)
/* If waitpid returns 0, there are running children. If it returns -1,
the only other error POSIX says it can return is EINTR. */
CHECK_TERMSIG;
if (pid <= 0)
continue; /* jumps right to the test */
@@ -3228,7 +3234,7 @@ set_job_status_and_cleanup (job)
temp_handler = trap_to_sighandler (SIGINT);
restore_sigint_handler ();
if (temp_handler == SIG_DFL)
termination_unwind_protect (SIGINT);
termsig_handler (SIGINT);
else if (temp_handler != SIG_IGN)
(*temp_handler) (SIGINT);
}
@@ -3430,6 +3436,7 @@ notify_of_job_status ()
fprintf (stderr, "\n");
if (dir == 0)
dir = current_working_directory ();
itrace("calling pretty_print_job for job %d", job);
pretty_print_job (job, JLIST_STANDARD, stderr);
if (dir && (strcmp (dir, jobs[job]->wd) != 0))
fprintf (stderr,
@@ -3704,7 +3711,7 @@ give_terminal_to (pgrp, force)
if (tcsetpgrp (shell_tty, pgrp) < 0)
{
/* Maybe we should print an error message? */
#ifdef DEBUG
#if 0
sys_error ("tcsetpgrp(%d) failed: pid %ld to pgrp %ld",
shell_tty, (long)getpid(), (long)pgrp);
#endif
+1 -1
View File
@@ -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
+1
View File
@@ -148,3 +148,4 @@ expect 2 40
2 40
expect 5 20
5 20
5
+150
View File
@@ -0,0 +1,150 @@
a returns 5
b returns 4
c returns 3
d returns 2
in e
e returned 25
x is 25
ZZ
abcde
defghi
ZZ
5
0
AVAR
AVAR
foo
foo
AVAR
5
5
f1
f1 ()
{
( return 5 );
status=$?;
echo $status;
return $status
}
before: try to assign to FUNCNAME
outside: FUNCNAME =
before: FUNCNAME = func
FUNCNAME = func2
after: FUNCNAME = func
outside2: FUNCNAME =
function
zf is a function
zf ()
{
echo this is zf
}
f is a function
f ()
{
echo f-x;
echo f-y
} 1>&2
subshell
f is a function
f ()
{
echo f-x;
echo f-y
} 1>&2
f2 is a function
f2 ()
{
echo f2-a;
function f3 ()
{
echo f3-a;
echo f3-b
} 1>&2;
f3
}
subshell
f2 is a function
f2 ()
{
echo f2-a;
function f3 ()
{
echo f3-a;
echo f3-b
} 1>&2;
f3
}
f4 is a function
f4 ()
{
echo f4-a;
function f5 ()
{
echo f5-a;
echo f5-b
} 1>&2;
f5
} 2>&1
subshell
f4 is a function
f4 ()
{
echo f4-a;
function f5 ()
{
echo f5-a;
echo f5-b
} 1>&2;
f5
} 2>&1
testgrp is a function
testgrp ()
{
echo testgrp-a;
{
echo tg-x;
echo tg-y
} 1>&2;
echo testgrp-b
}
subshell
testgrp is a function
testgrp ()
{
echo testgrp-a;
{
echo tg-x;
echo tg-y
} 1>&2;
echo testgrp-b
}
funca is a function
funca ()
{
( echo func-a )
}
funcb is a function
funcb ()
{
( echo func-b )
}
funcc is a function
funcc ()
{
( echo func-c ) 2>&1
}
func-a
func-b
func-c
expect 5 10
5 10
expect 20
20
expect 5 20
5 20
expect 5 30
5 30
expect 2 40
2 40
expect 5 20
5 20
+8
View File
@@ -165,4 +165,12 @@ myfunction() {
myfunction
myfunction | cat
segv()
{
echo foo | return 5
}
segv
echo $?
exit 0
+168
View File
@@ -0,0 +1,168 @@
a()
{
x=$((x - 1))
return 5
}
b()
{
x=$((x - 1))
a
echo a returns $?
return 4
}
c()
{
x=$((x - 1))
b
echo b returns $?
return 3
}
d()
{
x=$((x - 1))
c
echo c returns $?
return 2
}
e()
{
d
echo d returns $?
echo in e
x=$((x - 1))
return $x
}
f()
{
e
echo e returned $?
echo x is $x
return 0
}
x=30
f
# make sure unsetting a local variable preserves the `local' attribute
f1()
{
local zz
zz=abcde
echo $zz
unset zz
zz=defghi
echo $zz
}
zz=ZZ
echo $zz
f1
echo $zz
unset -f f1
f1()
{
return 5
}
( f1 )
echo $?
unset -f f1
f1()
{
sleep 5
return 5
}
f1 &
wait
echo $?
unset -f f1
f1()
{
echo $AVAR
printenv AVAR
}
AVAR=AVAR
echo $AVAR
f1
AVAR=foo f1
echo $AVAR
unset -f f1
# make sure subshells can do a `return' if we're executing in a function
f1()
{
( return 5 )
status=$?
echo $status
return $status
}
f1
echo $?
declare -F f1 # should print just the name
declare -f f1 # should print the definition, too
# no functions should be exported, right?
declare -xF
declare -xf
# FUNCNAME tests
func2()
{
echo FUNCNAME = $FUNCNAME
}
func()
{
echo before: FUNCNAME = $FUNCNAME
func2
echo after: FUNCNAME = $FUNCNAME
}
echo before: try to assign to FUNCNAME
FUCNAME=7
echo outside: FUNCNAME = $FUNCNAME
func
echo outside2: FUNCNAME = $FUNCNAME
# test exported functions (and cached exportstr)
zf()
{
echo this is zf
}
export -f zf
${THIS_SH} -c 'type -t zf'
${THIS_SH} -c 'type zf'
${THIS_SH} ./func1.sub
# tests for functions whose bodies are not group commands, with and without
# attached redirections
${THIS_SH} ./func2.sub
# test for some posix-specific function behavior
${THIS_SH} ./func3.sub
unset -f myfunction
myfunction() {
echo "bad shell function redirection"
} >> /dev/null
myfunction
myfunction | cat
exit 0