mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-18 03:11:15 +02:00
33325: fix ksh autoloads with redirections on function definitions
This commit is contained in:
parent
dad5063a7c
commit
f16813792e
3 changed files with 81 additions and 19 deletions
|
@ -1,3 +1,8 @@
|
|||
2014-10-02 Peter Stephenson <p.stephenson@samsung.com>
|
||||
|
||||
* 33325: Src/exec.c, Test/A05execution.ztst: fix ksh autoloads
|
||||
with redirections on functiond definitions.
|
||||
|
||||
2014-10-01 Barton E. Schaefer <schaefer@zsh.org>
|
||||
|
||||
* 33319: Doc/Zsh/grammar.yo: fix parens in example from 33312
|
||||
|
|
82
Src/exec.c
82
Src/exec.c
|
@ -2789,13 +2789,6 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
|||
errflag = 1;
|
||||
}
|
||||
|
||||
if (errflag) {
|
||||
lastval = 1;
|
||||
if (oautocont >= 0)
|
||||
opts[AUTOCONTINUE] = oautocont;
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == WC_FUNCDEF) {
|
||||
/*
|
||||
* The first word of a function definition is a list of
|
||||
|
@ -2809,8 +2802,24 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
|||
/* Nonymous, don't do redirections here */
|
||||
redir = NULL;
|
||||
}
|
||||
} else if (is_shfunc) {
|
||||
Shfunc shf = (Shfunc)hn;
|
||||
} else if (is_shfunc || type == WC_AUTOFN) {
|
||||
Shfunc shf;
|
||||
if (is_shfunc)
|
||||
shf = (Shfunc)hn;
|
||||
else {
|
||||
shf = loadautofn(state->prog->shf, 1, 0);
|
||||
if (shf)
|
||||
state->prog->shf = shf;
|
||||
else {
|
||||
/*
|
||||
* This doesn't set errflag, so just return now.
|
||||
*/
|
||||
lastval = 1;
|
||||
if (oautocont >= 0)
|
||||
opts[AUTOCONTINUE] = oautocont;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* A function definition may have a list of additional
|
||||
* redirections to apply, so retrieve it.
|
||||
|
@ -2832,6 +2841,13 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
|||
}
|
||||
}
|
||||
|
||||
if (errflag) {
|
||||
lastval = 1;
|
||||
if (oautocont >= 0)
|
||||
opts[AUTOCONTINUE] = oautocont;
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == WC_SIMPLE && !nullexec) {
|
||||
char *s;
|
||||
char trycd = (isset(AUTOCD) && isset(SHINSTDIN) &&
|
||||
|
@ -3306,10 +3322,18 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
|||
redir_prog = NULL;
|
||||
|
||||
lastval = execfuncdef(state, redir_prog);
|
||||
} else if (type >= WC_CURSH) {
|
||||
}
|
||||
else if (type >= WC_CURSH) {
|
||||
if (last1 == 1)
|
||||
do_exec = 1;
|
||||
lastval = (execfuncs[type - WC_CURSH])(state, do_exec);
|
||||
if (type == WC_AUTOFN) {
|
||||
/*
|
||||
* We pre-loaded this to get any redirs.
|
||||
* So we execuate a simplified function here.
|
||||
*/
|
||||
lastval = execautofn_basic(state, do_exec);
|
||||
} else
|
||||
lastval = (execfuncs[type - WC_CURSH])(state, do_exec);
|
||||
} else if (is_builtin || is_shfunc) {
|
||||
LinkList restorelist = 0, removelist = 0;
|
||||
/* builtin or shell function */
|
||||
|
@ -4540,21 +4564,28 @@ execshfunc(Shfunc shf, LinkList args)
|
|||
deletefilelist(last_file_list, 0);
|
||||
}
|
||||
|
||||
/* Function to execute the special type of command that represents an *
|
||||
* autoloaded shell function. The command structure tells us which *
|
||||
* function it is. This function is actually called as part of the *
|
||||
* execution of the autoloaded function itself, so when the function *
|
||||
* has been autoloaded, its list is just run with no frills. */
|
||||
/*
|
||||
* Function to execute the special type of command that represents an
|
||||
* autoloaded shell function. The command structure tells us which
|
||||
* function it is. This function is actually called as part of the
|
||||
* execution of the autoloaded function itself, so when the function
|
||||
* has been autoloaded, its list is just run with no frills.
|
||||
*
|
||||
* There are two cases because if we are doing all-singing, all-dancing
|
||||
* non-simple code we load the shell function early in execcmd() (the
|
||||
* action also present in the non-basic version) to check if
|
||||
* there are redirections that need to be handled at that point.
|
||||
* Then we call execautofn_basic() to do the rest.
|
||||
*/
|
||||
|
||||
/**/
|
||||
static int
|
||||
execautofn(Estate state, UNUSED(int do_exec))
|
||||
execautofn_basic(Estate state, UNUSED(int do_exec))
|
||||
{
|
||||
Shfunc shf;
|
||||
char *oldscriptname, *oldscriptfilename;
|
||||
|
||||
if (!(shf = loadautofn(state->prog->shf, 1, 0)))
|
||||
return 1;
|
||||
shf = state->prog->shf;
|
||||
|
||||
/*
|
||||
* Probably we didn't know the filename where this function was
|
||||
|
@ -4573,6 +4604,19 @@ execautofn(Estate state, UNUSED(int do_exec))
|
|||
return lastval;
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
execautofn(Estate state, UNUSED(int do_exec))
|
||||
{
|
||||
Shfunc shf;
|
||||
|
||||
if (!(shf = loadautofn(state->prog->shf, 1, 0)))
|
||||
return 1;
|
||||
|
||||
state->prog->shf = shf;
|
||||
return execautofn_basic(state, 0);
|
||||
}
|
||||
|
||||
/**/
|
||||
Shfunc
|
||||
loadautofn(Shfunc shf, int fksh, int autol)
|
||||
|
|
|
@ -216,3 +216,16 @@ F:This similar test was triggering a reproducible failure with pipestatus.
|
|||
>done
|
||||
F:This test checks for a file descriptor leak that could cause the left
|
||||
F:side of a pipe to block on write after the right side has exited
|
||||
|
||||
print "autoload_redir() { print Autoloaded ksh style; } >autoload.log" >autoload_redir
|
||||
autoload -Uk autoload_redir
|
||||
autoload_redir
|
||||
print No output yet
|
||||
cat autoload.log
|
||||
functions autoload_redir
|
||||
0:
|
||||
>No output yet
|
||||
>Autoloaded ksh style
|
||||
>autoload_redir () {
|
||||
> print Autoloaded ksh style
|
||||
>} > autoload.log
|
||||
|
|
Loading…
Reference in a new issue