1
0
Fork 0
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:
Peter Stephenson 2014-10-02 16:15:10 +01:00
parent dad5063a7c
commit f16813792e
3 changed files with 81 additions and 19 deletions

View file

@ -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

View file

@ -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,10 +3322,18 @@ 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;
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) { } else if (is_builtin || is_shfunc) {
LinkList restorelist = 0, removelist = 0; LinkList restorelist = 0, removelist = 0;
/* builtin or shell function */ /* builtin or shell function */
@ -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)

View file

@ -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