mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-23 17:01:05 +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>
|
2014-10-01 Barton E. Schaefer <schaefer@zsh.org>
|
||||||
|
|
||||||
* 33319: Doc/Zsh/grammar.yo: fix parens in example from 33312
|
* 33319: Doc/Zsh/grammar.yo: fix parens in example from 33312
|
||||||
|
|
80
Src/exec.c
80
Src/exec.c
|
@ -2789,13 +2789,6 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
errflag = 1;
|
errflag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errflag) {
|
|
||||||
lastval = 1;
|
|
||||||
if (oautocont >= 0)
|
|
||||||
opts[AUTOCONTINUE] = oautocont;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == WC_FUNCDEF) {
|
if (type == WC_FUNCDEF) {
|
||||||
/*
|
/*
|
||||||
* The first word of a function definition is a list of
|
* 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 */
|
/* Nonymous, don't do redirections here */
|
||||||
redir = NULL;
|
redir = NULL;
|
||||||
}
|
}
|
||||||
} else if (is_shfunc) {
|
} else if (is_shfunc || type == WC_AUTOFN) {
|
||||||
Shfunc shf = (Shfunc)hn;
|
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
|
* A function definition may have a list of additional
|
||||||
* redirections to apply, so retrieve it.
|
* 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) {
|
if (type == WC_SIMPLE && !nullexec) {
|
||||||
char *s;
|
char *s;
|
||||||
char trycd = (isset(AUTOCD) && isset(SHINSTDIN) &&
|
char trycd = (isset(AUTOCD) && isset(SHINSTDIN) &&
|
||||||
|
@ -3306,9 +3322,17 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
redir_prog = NULL;
|
redir_prog = NULL;
|
||||||
|
|
||||||
lastval = execfuncdef(state, redir_prog);
|
lastval = execfuncdef(state, redir_prog);
|
||||||
} else if (type >= WC_CURSH) {
|
}
|
||||||
|
else if (type >= WC_CURSH) {
|
||||||
if (last1 == 1)
|
if (last1 == 1)
|
||||||
do_exec = 1;
|
do_exec = 1;
|
||||||
|
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);
|
lastval = (execfuncs[type - WC_CURSH])(state, do_exec);
|
||||||
} else if (is_builtin || is_shfunc) {
|
} else if (is_builtin || is_shfunc) {
|
||||||
LinkList restorelist = 0, removelist = 0;
|
LinkList restorelist = 0, removelist = 0;
|
||||||
|
@ -4540,21 +4564,28 @@ execshfunc(Shfunc shf, LinkList args)
|
||||||
deletefilelist(last_file_list, 0);
|
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 to execute the special type of command that represents an
|
||||||
* function it is. This function is actually called as part of the *
|
* autoloaded shell function. The command structure tells us which
|
||||||
* execution of the autoloaded function itself, so when the function *
|
* function it is. This function is actually called as part of the
|
||||||
* has been autoloaded, its list is just run with no frills. */
|
* 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
|
static int
|
||||||
execautofn(Estate state, UNUSED(int do_exec))
|
execautofn_basic(Estate state, UNUSED(int do_exec))
|
||||||
{
|
{
|
||||||
Shfunc shf;
|
Shfunc shf;
|
||||||
char *oldscriptname, *oldscriptfilename;
|
char *oldscriptname, *oldscriptfilename;
|
||||||
|
|
||||||
if (!(shf = loadautofn(state->prog->shf, 1, 0)))
|
shf = state->prog->shf;
|
||||||
return 1;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Probably we didn't know the filename where this function was
|
* Probably we didn't know the filename where this function was
|
||||||
|
@ -4573,6 +4604,19 @@ execautofn(Estate state, UNUSED(int do_exec))
|
||||||
return lastval;
|
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
|
Shfunc
|
||||||
loadautofn(Shfunc shf, int fksh, int autol)
|
loadautofn(Shfunc shf, int fksh, int autol)
|
||||||
|
|
|
@ -216,3 +216,16 @@ F:This similar test was triggering a reproducible failure with pipestatus.
|
||||||
>done
|
>done
|
||||||
F:This test checks for a file descriptor leak that could cause the left
|
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
|
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