mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-11 13:01:28 +02:00
33876: etc.: Separate errors and keyboards interrupts
Combination of 12 commits from interrupt_abort branch. Basic strategy is to introduce bits to errflag and to set and reset them separately. Remove interrupt status on return to main keymap. Turn off ERRFLAG_INT for always block. Restore bit thereafter: we probably need a new variable in order to allow user interrupts to be reset in the always block. Add TRY_BLOCK_INTERRUPT This works the same as TRY_BLOCK_ERROR, but for a SIGINT, too. Ensure propagation of SIGINT from exited job. If received by foreground job, shell uses ERRFLAG_INT, not ERRFLAG_ERROR, to set the new state. Reset errflag before precmd() Add always block in _main_completion to fix ZLS_COLORS Ensures we get the right state of $ZLS_COLORS at the end of _main_complete even if there's an interrupt. However, the "right state" is a bit messy as it depends on styles.
This commit is contained in:
parent
247f7548dc
commit
d067ebcacd
31 changed files with 315 additions and 134 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
||||||
|
2014-12-11 Peter Stephenson <p.stephenson@samsung.com>
|
||||||
|
|
||||||
|
* 33876: etc.: Completion/Base/Core/_main_complete,
|
||||||
|
Doc/Zsh/params.yo, Src/Modules/zpty.c, Src/Modules/zutil.c,
|
||||||
|
Src/Zle/compcore.c, Src/Zle/compctl.c, Src/Zle/compresult.c,
|
||||||
|
Src/Zle/textobjects.c, Src/Zle/zle_hist.c, Src/Zle/zle_keymap.c,
|
||||||
|
Src/Zle/zle_main.c, Src/Zle/zle_misc.c, Src/Zle/zle_tricky.c,
|
||||||
|
Src/Zle/zle_utils.c, Src/builtin.c, Src/exec.c, Src/glob.c,
|
||||||
|
Src/hist.c, Src/init.c, Src/input.c, Src/jobs.c, Src/lex.c,
|
||||||
|
Src/loop.c, Src/params.c, Src/parse.c, Src/prompt.c,
|
||||||
|
Src/signals.c, Src/subst.c, Src/utils.c, Src/zsh.h: Separate
|
||||||
|
shell errors and user interrupt flags into different bits of
|
||||||
|
errflag: ERRFLAG_ERROR and ERRFLAG_INT. Various
|
||||||
|
rationalisations to make keyboard interrupts work smoothly.
|
||||||
|
Work done on interrupt_abort branch.
|
||||||
|
|
||||||
2014-12-10 Mikael Magnusson <mikachu@gmail.com>
|
2014-12-10 Mikael Magnusson <mikachu@gmail.com>
|
||||||
|
|
||||||
* 33948: Completion/Unix/Command/_getent,
|
* 33948: Completion/Unix/Command/_getent,
|
||||||
|
|
|
@ -43,6 +43,8 @@ local -a precommands
|
||||||
|
|
||||||
typeset -U _lastdescr _comp_ignore _comp_colors
|
typeset -U _lastdescr _comp_ignore _comp_colors
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
[[ -z "$curcontext" ]] && curcontext=:::
|
[[ -z "$curcontext" ]] && curcontext=:::
|
||||||
|
|
||||||
zstyle -s ":completion:${curcontext}:" insert-tab tmp || tmp=yes
|
zstyle -s ":completion:${curcontext}:" insert-tab tmp || tmp=yes
|
||||||
|
@ -349,17 +351,20 @@ fi
|
||||||
( "$_comp_force_list" = ?* && nm -ge _comp_force_list ) ]] &&
|
( "$_comp_force_list" = ?* && nm -ge _comp_force_list ) ]] &&
|
||||||
compstate[list]="${compstate[list]//messages} force"
|
compstate[list]="${compstate[list]//messages} force"
|
||||||
|
|
||||||
if [[ "$compstate[old_list]" = keep ]]; then
|
} always {
|
||||||
if [[ $_saved_colors_set = 1 ]]; then
|
# Stuff we always do to clean up.
|
||||||
ZLS_COLORS="$_saved_colors"
|
if [[ "$compstate[old_list]" = keep ]]; then
|
||||||
|
if [[ $_saved_colors_set = 1 ]]; then
|
||||||
|
ZLS_COLORS="$_saved_colors"
|
||||||
|
else
|
||||||
|
unset ZLS_COLORS
|
||||||
|
fi
|
||||||
|
elif (( $#_comp_colors )); then
|
||||||
|
ZLS_COLORS="${(j.:.)_comp_colors}"
|
||||||
else
|
else
|
||||||
unset ZLS_COLORS
|
unset ZLS_COLORS
|
||||||
fi
|
fi
|
||||||
elif (( $#_comp_colors )); then
|
}
|
||||||
ZLS_COLORS="${(j.:.)_comp_colors}"
|
|
||||||
else
|
|
||||||
unset ZLS_COLORS
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Now call the post-functions.
|
# Now call the post-functions.
|
||||||
|
|
||||||
|
|
|
@ -754,6 +754,17 @@ It may be reset, clearing the error condition. See
|
||||||
ifzman(em(Complex Commands) in zmanref(zshmisc))\
|
ifzman(em(Complex Commands) in zmanref(zshmisc))\
|
||||||
ifnzman(noderef(Complex Commands))
|
ifnzman(noderef(Complex Commands))
|
||||||
)
|
)
|
||||||
|
vindex(TRY_BLOCK_INTERRUPT)
|
||||||
|
item(tt(TRY_BLOCK_INTERRUPT) <S>)(
|
||||||
|
This variable works in a similar way to tt(TRY_BLOCK_ERROR), but
|
||||||
|
represents the status of an interrupt from the signal SIGINT, which
|
||||||
|
typically comes from the keyboard when the user types tt(^C). If set to
|
||||||
|
0, any such interrupt will be reset; otherwise, the interrupt is
|
||||||
|
propagated after the tt(always) block.
|
||||||
|
|
||||||
|
Note that it is possible that an interrupt arrives during the execution
|
||||||
|
of the tt(always) block; this interrupt is also propagated.
|
||||||
|
)
|
||||||
vindex(TTY)
|
vindex(TTY)
|
||||||
item(tt(TTY))(
|
item(tt(TTY))(
|
||||||
The name of the tty associated with the shell, if any.
|
The name of the tty associated with the shell, if any.
|
||||||
|
|
|
@ -308,7 +308,7 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
|
||||||
|
|
||||||
prog = parse_string(zjoin(args, ' ', 1), 0);
|
prog = parse_string(zjoin(args, ' ', 1), 0);
|
||||||
if (!prog) {
|
if (!prog) {
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
scriptname = oscriptname;
|
scriptname = oscriptname;
|
||||||
ineval = oineval;
|
ineval = oineval;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -301,7 +301,8 @@ setstypat(Style s, char *pat, Patprog prog, char **vals, int eval)
|
||||||
int ef = errflag;
|
int ef = errflag;
|
||||||
|
|
||||||
eprog = parse_string(zjoin(vals, ' ', 1), 0);
|
eprog = parse_string(zjoin(vals, ' ', 1), 0);
|
||||||
errflag = ef;
|
/* Keep any user interrupt error status */
|
||||||
|
errflag = ef | (errflag & ERRFLAG_INT);
|
||||||
|
|
||||||
if (!eprog)
|
if (!eprog)
|
||||||
{
|
{
|
||||||
|
@ -394,10 +395,11 @@ evalstyle(Stypat p)
|
||||||
unsetparam("reply");
|
unsetparam("reply");
|
||||||
execode(p->eval, 1, 0, "style");
|
execode(p->eval, 1, 0, "style");
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
errflag = ef;
|
/* Keep any user interrupt error status */
|
||||||
|
errflag = ef | (errflag & ERRFLAG_INT);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
errflag = ef;
|
errflag = ef | (errflag & ERRFLAG_INT);
|
||||||
|
|
||||||
queue_signals();
|
queue_signals();
|
||||||
if ((ret = getaparam("reply")))
|
if ((ret = getaparam("reply")))
|
||||||
|
|
|
@ -1671,7 +1671,7 @@ set_comp_sep(void)
|
||||||
noaliases = ona;
|
noaliases = ona;
|
||||||
strinend();
|
strinend();
|
||||||
inpop();
|
inpop();
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
noerrs = ne;
|
noerrs = ne;
|
||||||
lexrestore();
|
lexrestore();
|
||||||
wb = owb;
|
wb = owb;
|
||||||
|
|
|
@ -1879,7 +1879,7 @@ ccmakehookfn(UNUSED(Hookdef dummy), struct ccmakedat *dat)
|
||||||
if (!m || !(m = m->next))
|
if (!m || !(m = m->next))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
}
|
}
|
||||||
redup(osi, 0);
|
redup(osi, 0);
|
||||||
dat->lst = 1;
|
dat->lst = 1;
|
||||||
|
@ -2121,7 +2121,7 @@ getreal(char *str)
|
||||||
if (!errflag && nonempty(l) &&
|
if (!errflag && nonempty(l) &&
|
||||||
((char *) peekfirst(l)) && ((char *) peekfirst(l))[0])
|
((char *) peekfirst(l)) && ((char *) peekfirst(l))[0])
|
||||||
return dupstring(peekfirst(l));
|
return dupstring(peekfirst(l));
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
|
|
||||||
return dupstring(str);
|
return dupstring(str);
|
||||||
}
|
}
|
||||||
|
@ -2599,7 +2599,7 @@ makecomplistlist(Compctl cc, char *s, int incmd, int compadd)
|
||||||
makecomplistflags(cc, s, incmd, compadd);
|
makecomplistflags(cc, s, incmd, compadd);
|
||||||
|
|
||||||
/* Reset some information variables for the next try. */
|
/* Reset some information variables for the next try. */
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
offs = oloffs;
|
offs = oloffs;
|
||||||
wb = owb;
|
wb = owb;
|
||||||
we = owe;
|
we = owe;
|
||||||
|
@ -2847,7 +2847,7 @@ sep_comp_string(char *ss, char *s, int noffs)
|
||||||
noaliases = ona;
|
noaliases = ona;
|
||||||
strinend();
|
strinend();
|
||||||
inpop();
|
inpop();
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
noerrs = ne;
|
noerrs = ne;
|
||||||
lexrestore();
|
lexrestore();
|
||||||
wb = owb;
|
wb = owb;
|
||||||
|
@ -3725,7 +3725,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
noaliases = ona;
|
noaliases = ona;
|
||||||
strinend();
|
strinend();
|
||||||
inpop();
|
inpop();
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
lexrestore();
|
lexrestore();
|
||||||
/* Fine, now do full expansion. */
|
/* Fine, now do full expansion. */
|
||||||
prefork(foo, 0);
|
prefork(foo, 0);
|
||||||
|
|
|
@ -1092,7 +1092,7 @@ do_single(Cmatch m)
|
||||||
noerrs = 1;
|
noerrs = 1;
|
||||||
parsestr(p);
|
parsestr(p);
|
||||||
singsub(&p);
|
singsub(&p);
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
noerrs = ne;
|
noerrs = ne;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -275,7 +275,7 @@ selectargument(UNUSED(char **args))
|
||||||
noaliases = ona;
|
noaliases = ona;
|
||||||
strinend();
|
strinend();
|
||||||
inpop();
|
inpop();
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
noerrs = ne;
|
noerrs = ne;
|
||||||
lexrestore();
|
lexrestore();
|
||||||
zlemetacs = ocs;
|
zlemetacs = ocs;
|
||||||
|
|
|
@ -853,8 +853,10 @@ pushlineoredit(char **args)
|
||||||
free(zhline);
|
free(zhline);
|
||||||
}
|
}
|
||||||
ret = pushline(args);
|
ret = pushline(args);
|
||||||
if (!isfirstln)
|
if (!isfirstln) {
|
||||||
errflag = done = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
clearlist = 1;
|
clearlist = 1;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -504,6 +504,16 @@ mod_export void
|
||||||
selectlocalmap(Keymap m)
|
selectlocalmap(Keymap m)
|
||||||
{
|
{
|
||||||
localkeymap = m;
|
localkeymap = m;
|
||||||
|
if (!m)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* No local keymap; so we are returning to the global map. If
|
||||||
|
* the user ^Ced in the local map, they probably just want to go
|
||||||
|
* back to normal editing. So remove the interrupt error
|
||||||
|
* status.
|
||||||
|
*/
|
||||||
|
errflag &= ~ERRFLAG_INT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reopen the currently selected keymap, in case it got deleted. This *
|
/* Reopen the currently selected keymap, in case it got deleted. This *
|
||||||
|
|
|
@ -744,7 +744,7 @@ raw_getbyte(long do_keytmout, char *cptr)
|
||||||
}
|
}
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
/* No sensible way of handling errors here */
|
/* No sensible way of handling errors here */
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
/*
|
/*
|
||||||
* Paranoia: don't run the hooks again this
|
* Paranoia: don't run the hooks again this
|
||||||
* time.
|
* time.
|
||||||
|
@ -882,7 +882,7 @@ getbyte(long do_keytmout, int *timeout)
|
||||||
die = 0;
|
die = 0;
|
||||||
if (!errflag && !retflag && !breaks && !exit_pending)
|
if (!errflag && !retflag && !breaks && !exit_pending)
|
||||||
continue;
|
continue;
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
breaks = obreaks;
|
breaks = obreaks;
|
||||||
errno = old_errno;
|
errno = old_errno;
|
||||||
return lastchar = EOF;
|
return lastchar = EOF;
|
||||||
|
@ -1075,7 +1075,7 @@ zlecore(void)
|
||||||
DECCS();
|
DECCS();
|
||||||
handleundo();
|
handleundo();
|
||||||
} else {
|
} else {
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
|
@ -1233,6 +1233,10 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish)
|
||||||
|
|
||||||
zleactive = 1;
|
zleactive = 1;
|
||||||
resetneeded = 1;
|
resetneeded = 1;
|
||||||
|
/*
|
||||||
|
* Start of the main zle read.
|
||||||
|
* Fully reset error conditions, including user interrupt.
|
||||||
|
*/
|
||||||
errflag = retflag = 0;
|
errflag = retflag = 0;
|
||||||
lastcol = -1;
|
lastcol = -1;
|
||||||
initmodifier(&zmod);
|
initmodifier(&zmod);
|
||||||
|
@ -1658,7 +1662,7 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
|
||||||
}
|
}
|
||||||
if (!t || errflag) {
|
if (!t || errflag) {
|
||||||
/* error in editing */
|
/* error in editing */
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
breaks = obreaks;
|
breaks = obreaks;
|
||||||
if (t)
|
if (t)
|
||||||
zsfree(t);
|
zsfree(t);
|
||||||
|
@ -1778,7 +1782,7 @@ recursiveedit(UNUSED(char **args))
|
||||||
zrefresh();
|
zrefresh();
|
||||||
zlecore();
|
zlecore();
|
||||||
|
|
||||||
locerror = errflag;
|
locerror = errflag ? 1 : 0;
|
||||||
errflag = done = eofsent = 0;
|
errflag = done = eofsent = 0;
|
||||||
|
|
||||||
return locerror;
|
return locerror;
|
||||||
|
|
|
@ -1041,7 +1041,7 @@ copyprevshellword(UNUSED(char **args))
|
||||||
int
|
int
|
||||||
sendbreak(UNUSED(char **args))
|
sendbreak(UNUSED(char **args))
|
||||||
{
|
{
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -829,7 +829,7 @@ docomplete(int lst)
|
||||||
if (olst == COMP_EXPAND_COMPLETE &&
|
if (olst == COMP_EXPAND_COMPLETE &&
|
||||||
!strcmp(ol, zlemetaline)) {
|
!strcmp(ol, zlemetaline)) {
|
||||||
zlemetacs = ocs;
|
zlemetacs = ocs;
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
|
|
||||||
if (!compfunc) {
|
if (!compfunc) {
|
||||||
char *p;
|
char *p;
|
||||||
|
@ -877,6 +877,19 @@ docomplete(int lst)
|
||||||
|
|
||||||
active = 0;
|
active = 0;
|
||||||
makecommaspecial(0);
|
makecommaspecial(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As a special case, we reset user interrupts here.
|
||||||
|
* That's because completion is an intensive piece of
|
||||||
|
* computation that the user might want to interrupt separately
|
||||||
|
* from anything else going on. If they do, they probably
|
||||||
|
* want to keep the line edit buffer intact.
|
||||||
|
*
|
||||||
|
* There's a race here that the user might hit ^C just
|
||||||
|
* after completion exited anyway, but that's inevitable.
|
||||||
|
*/
|
||||||
|
errflag &= ~ERRFLAG_INT;
|
||||||
|
|
||||||
return dat[1];
|
return dat[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1394,7 +1407,8 @@ get_comp_string(void)
|
||||||
}
|
}
|
||||||
strinend();
|
strinend();
|
||||||
inpop();
|
inpop();
|
||||||
errflag = lexflags = 0;
|
lexflags = 0;
|
||||||
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
if (parbegin != -1) {
|
if (parbegin != -1) {
|
||||||
/* We are in command or process substitution if we are not in
|
/* We are in command or process substitution if we are not in
|
||||||
* a $((...)). */
|
* a $((...)). */
|
||||||
|
@ -2917,7 +2931,7 @@ getcurcmd(void)
|
||||||
popheap();
|
popheap();
|
||||||
strinend();
|
strinend();
|
||||||
inpop();
|
inpop();
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
unmetafy_line();
|
unmetafy_line();
|
||||||
lexrestore();
|
lexrestore();
|
||||||
|
|
||||||
|
|
|
@ -1715,7 +1715,8 @@ zlecallhook(char *name, char *arg)
|
||||||
execzlefunc(thingy, args, 1);
|
execzlefunc(thingy, args, 1);
|
||||||
unrefthingy(thingy);
|
unrefthingy(thingy);
|
||||||
|
|
||||||
errflag = saverrflag;
|
/* Retain any user interrupt error status */
|
||||||
|
errflag = saverrflag | (errflag & ERRFLAG_INT);
|
||||||
retflag = savretflag;
|
retflag = savretflag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -422,7 +422,7 @@ execbuiltin(LinkList args, Builtin bn)
|
||||||
argc -= argv - argarr;
|
argc -= argv - argarr;
|
||||||
|
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3136,7 +3136,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
returnval = errflag;
|
returnval = errflag;
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
} else {
|
} else {
|
||||||
zerrnam(name, "%s: invalid element for unset", s);
|
zerrnam(name, "%s: invalid element for unset", s);
|
||||||
returnval = 1;
|
returnval = 1;
|
||||||
|
@ -4242,7 +4242,7 @@ bin_print(char *name, char **args, Options ops, int func)
|
||||||
if (*argp) {
|
if (*argp) {
|
||||||
width = (int)mathevali(*argp++);
|
width = (int)mathevali(*argp++);
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4272,7 +4272,7 @@ bin_print(char *name, char **args, Options ops, int func)
|
||||||
if (*argp) {
|
if (*argp) {
|
||||||
prec = (int)mathevali(*argp++);
|
prec = (int)mathevali(*argp++);
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4452,7 +4452,7 @@ bin_print(char *name, char **args, Options ops, int func)
|
||||||
zlongval = (curarg) ? mathevali(curarg) : 0;
|
zlongval = (curarg) ? mathevali(curarg) : 0;
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
zlongval = 0;
|
zlongval = 0;
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
print_val(zlongval)
|
print_val(zlongval)
|
||||||
|
@ -4481,7 +4481,7 @@ bin_print(char *name, char **args, Options ops, int func)
|
||||||
} else doubleval = 0;
|
} else doubleval = 0;
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
doubleval = 0;
|
doubleval = 0;
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
print_val(doubleval)
|
print_val(doubleval)
|
||||||
|
@ -4494,7 +4494,7 @@ bin_print(char *name, char **args, Options ops, int func)
|
||||||
zulongval = (curarg) ? mathevali(curarg) : 0;
|
zulongval = (curarg) ? mathevali(curarg) : 0;
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
zulongval = 0;
|
zulongval = 0;
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
print_val(zulongval)
|
print_val(zulongval)
|
||||||
|
@ -4871,7 +4871,7 @@ zexit(int val, int from_where)
|
||||||
in_exit = -1;
|
in_exit = -1;
|
||||||
/*
|
/*
|
||||||
* We want to do all remaining processing regardless of preceding
|
* We want to do all remaining processing regardless of preceding
|
||||||
* errors.
|
* errors, even user interrupts.
|
||||||
*/
|
*/
|
||||||
errflag = 0;
|
errflag = 0;
|
||||||
|
|
||||||
|
@ -5074,7 +5074,7 @@ eval(char **argv)
|
||||||
if (fpushed)
|
if (fpushed)
|
||||||
funcstack = funcstack->prev;
|
funcstack = funcstack->prev;
|
||||||
|
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
scriptname = oscriptname;
|
scriptname = oscriptname;
|
||||||
ineval = oineval;
|
ineval = oineval;
|
||||||
|
|
||||||
|
@ -6101,7 +6101,7 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func)
|
||||||
condlex = zshlex;
|
condlex = zshlex;
|
||||||
|
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
lexrestore();
|
lexrestore();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -6278,7 +6278,7 @@ bin_let(UNUSED(char *name), char **argv, UNUSED(Options ops), UNUSED(int func))
|
||||||
while (*argv)
|
while (*argv)
|
||||||
val = matheval(*argv++);
|
val = matheval(*argv++);
|
||||||
/* Errors in math evaluation in let are non-fatal. */
|
/* Errors in math evaluation in let are non-fatal. */
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
/* should test for fabs(val.u.d) < epsilon? */
|
/* should test for fabs(val.u.d) < epsilon? */
|
||||||
return (val.type == MN_INTEGER) ? val.u.l == 0 : val.u.d == 0.0;
|
return (val.type == MN_INTEGER) ? val.u.l == 0 : val.u.d == 0.0;
|
||||||
}
|
}
|
||||||
|
|
56
Src/exec.c
56
Src/exec.c
|
@ -59,7 +59,7 @@ mod_export int noerrs;
|
||||||
/**/
|
/**/
|
||||||
int nohistsave;
|
int nohistsave;
|
||||||
|
|
||||||
/* error/break flag */
|
/* error flag: bits from enum errflag_bits */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
mod_export int errflag;
|
mod_export int errflag;
|
||||||
|
@ -1601,7 +1601,8 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
||||||
(killpg(jobtab[list_pipe_job].gleader, 0) == -1 ? 2 : 1);
|
(killpg(jobtab[list_pipe_job].gleader, 0) == -1 ? 2 : 1);
|
||||||
list_pipe_pid = pid;
|
list_pipe_pid = pid;
|
||||||
list_pipe_start = bgtime;
|
list_pipe_start = bgtime;
|
||||||
nowait = errflag = 1;
|
nowait = 1;
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
breaks = loops;
|
breaks = loops;
|
||||||
close(synch[1]);
|
close(synch[1]);
|
||||||
read_loop(synch[0], &dummy, 1);
|
read_loop(synch[0], &dummy, 1);
|
||||||
|
@ -1634,7 +1635,10 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
||||||
list_pipe_child = 1;
|
list_pipe_child = 1;
|
||||||
opts[INTERACTIVE] = 0;
|
opts[INTERACTIVE] = 0;
|
||||||
if (errbrk_saved) {
|
if (errbrk_saved) {
|
||||||
errflag = prev_errflag;
|
/*
|
||||||
|
* Keep any user interrupt bit in errflag.
|
||||||
|
*/
|
||||||
|
errflag = prev_errflag | (errflag & ERRFLAG_INT);
|
||||||
breaks = prev_breaks;
|
breaks = prev_breaks;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1719,12 +1723,14 @@ execpline2(Estate state, wordcode pcode,
|
||||||
|
|
||||||
if (pipe(synch) < 0) {
|
if (pipe(synch) < 0) {
|
||||||
zerr("pipe failed: %e", errno);
|
zerr("pipe failed: %e", errno);
|
||||||
lastval = errflag = 1;
|
lastval = 1;
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
return;
|
return;
|
||||||
} else if ((pid = zfork(&bgtime)) == -1) {
|
} else if ((pid = zfork(&bgtime)) == -1) {
|
||||||
close(synch[0]);
|
close(synch[0]);
|
||||||
close(synch[1]);
|
close(synch[1]);
|
||||||
lastval = errflag = 1;
|
lastval = 1;
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
return;
|
return;
|
||||||
} else if (pid) {
|
} else if (pid) {
|
||||||
char dummy, *text;
|
char dummy, *text;
|
||||||
|
@ -2560,7 +2566,8 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
while (next && *next == '-' && strlen(next) >= 2) {
|
while (next && *next == '-' && strlen(next) >= 2) {
|
||||||
if (!firstnode(args)) {
|
if (!firstnode(args)) {
|
||||||
zerr("exec requires a command to execute");
|
zerr("exec requires a command to execute");
|
||||||
errflag = lastval = 1;
|
lastval = 1;
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
uremnode(args, firstnode(args));
|
uremnode(args, firstnode(args));
|
||||||
|
@ -2577,12 +2584,14 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
} else {
|
} else {
|
||||||
if (!firstnode(args)) {
|
if (!firstnode(args)) {
|
||||||
zerr("exec requires a command to execute");
|
zerr("exec requires a command to execute");
|
||||||
errflag = lastval = 1;
|
lastval = 1;
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (!nextnode(firstnode(args))) {
|
if (!nextnode(firstnode(args))) {
|
||||||
zerr("exec flag -a requires a parameter");
|
zerr("exec flag -a requires a parameter");
|
||||||
errflag = lastval = 1;
|
lastval = 1;
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
exec_argv0 = (char *)
|
exec_argv0 = (char *)
|
||||||
|
@ -2598,7 +2607,8 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
zerr("unknown exec flag -%c", *cmdopt);
|
zerr("unknown exec flag -%c", *cmdopt);
|
||||||
errflag = lastval = 1;
|
lastval = 1;
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2661,7 +2671,8 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
} else if (!nullcmd || !*nullcmd || opts[CSHNULLCMD] ||
|
} else if (!nullcmd || !*nullcmd || opts[CSHNULLCMD] ||
|
||||||
(cflags & BINF_PREFIX)) {
|
(cflags & BINF_PREFIX)) {
|
||||||
zerr("redirection with no command");
|
zerr("redirection with no command");
|
||||||
errflag = lastval = 1;
|
lastval = 1;
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
return;
|
return;
|
||||||
} else if (!nullcmd || !*nullcmd || opts[SHNULLCMD]) {
|
} else if (!nullcmd || !*nullcmd || opts[SHNULLCMD]) {
|
||||||
if (!args)
|
if (!args)
|
||||||
|
@ -2691,7 +2702,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
if (varspc)
|
if (varspc)
|
||||||
addvars(state, varspc, 0);
|
addvars(state, varspc, 0);
|
||||||
if (errflag)
|
if (errflag)
|
||||||
lastval = errflag;
|
lastval = 1;
|
||||||
else
|
else
|
||||||
lastval = cmdoutval;
|
lastval = cmdoutval;
|
||||||
if (isset(XTRACE)) {
|
if (isset(XTRACE)) {
|
||||||
|
@ -2795,7 +2806,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!nextnode(firstnode(args)))
|
if (!nextnode(firstnode(args)))
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == WC_FUNCDEF) {
|
if (type == WC_FUNCDEF) {
|
||||||
|
@ -2940,7 +2951,8 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
} else if ((pid = zfork(&bgtime)) == -1) {
|
} else if ((pid = zfork(&bgtime)) == -1) {
|
||||||
close(synch[0]);
|
close(synch[0]);
|
||||||
close(synch[1]);
|
close(synch[1]);
|
||||||
lastval = errflag = 1;
|
lastval = 1;
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
goto fatal;
|
goto fatal;
|
||||||
}
|
}
|
||||||
if (pid) {
|
if (pid) {
|
||||||
|
@ -3529,7 +3541,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
else
|
else
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newxtrerr) {
|
if (newxtrerr) {
|
||||||
|
@ -3759,8 +3771,10 @@ gethere(char **strp, int typ)
|
||||||
|
|
||||||
parsestr(buf);
|
parsestr(buf);
|
||||||
|
|
||||||
if (!errflag)
|
if (!errflag) {
|
||||||
errflag = ef;
|
/* Retain any user interrupt error */
|
||||||
|
errflag = ef | (errflag & ERRFLAG_INT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s = dupstring(buf);
|
s = dupstring(buf);
|
||||||
zfree(buf, bsiz);
|
zfree(buf, bsiz);
|
||||||
|
@ -3854,7 +3868,7 @@ getoutput(char *cmd, int qt)
|
||||||
return readoutput(stream, qt);
|
return readoutput(stream, qt);
|
||||||
}
|
}
|
||||||
if (mpipe(pipes) < 0) {
|
if (mpipe(pipes) < 0) {
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
cmdoutpid = 0;
|
cmdoutpid = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -3864,7 +3878,7 @@ getoutput(char *cmd, int qt)
|
||||||
/* fork error */
|
/* fork error */
|
||||||
zclose(pipes[0]);
|
zclose(pipes[0]);
|
||||||
zclose(pipes[1]);
|
zclose(pipes[1]);
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
cmdoutpid = 0;
|
cmdoutpid = 0;
|
||||||
child_unblock();
|
child_unblock();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -4274,7 +4288,7 @@ execcond(Estate state, UNUSED(int do_exec))
|
||||||
* into a shell error.
|
* into a shell error.
|
||||||
*/
|
*/
|
||||||
if (stat == 2)
|
if (stat == 2)
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
cmdpop();
|
cmdpop();
|
||||||
if (isset(XTRACE)) {
|
if (isset(XTRACE)) {
|
||||||
fprintf(xtrerr, " ]]\n");
|
fprintf(xtrerr, " ]]\n");
|
||||||
|
@ -4314,7 +4328,7 @@ execarith(Estate state, UNUSED(int do_exec))
|
||||||
fflush(xtrerr);
|
fflush(xtrerr);
|
||||||
}
|
}
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
/* should test for fabs(val.u.d) < epsilon? */
|
/* should test for fabs(val.u.d) < epsilon? */
|
||||||
|
@ -4932,7 +4946,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
|
||||||
(name = fname)))) {
|
(name = fname)))) {
|
||||||
zwarn("%s: function not defined by file", name);
|
zwarn("%s: function not defined by file", name);
|
||||||
if (noreturnval)
|
if (noreturnval)
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
else
|
else
|
||||||
lastval = 1;
|
lastval = 1;
|
||||||
goto doneshfunc;
|
goto doneshfunc;
|
||||||
|
|
12
Src/glob.c
12
Src/glob.c
|
@ -682,7 +682,7 @@ parsecomplist(char *instr)
|
||||||
/* Now get the next path component if there is one. */
|
/* Now get the next path component if there is one. */
|
||||||
l1 = (Complist) zhalloc(sizeof *l1);
|
l1 = (Complist) zhalloc(sizeof *l1);
|
||||||
if ((l1->next = parsecomplist(instr)) == NULL) {
|
if ((l1->next = parsecomplist(instr)) == NULL) {
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
l1->pat = patcompile(NULL, compflags | PAT_ANY, NULL);
|
l1->pat = patcompile(NULL, compflags | PAT_ANY, NULL);
|
||||||
|
@ -728,7 +728,7 @@ parsecomplist(char *instr)
|
||||||
return (ef && !l1->next) ? NULL : l1;
|
return (ef && !l1->next) ? NULL : l1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1790,7 +1790,7 @@ zglob(LinkList list, LinkNode np, int nountok)
|
||||||
insertlinknode(list, node, ostr);
|
insertlinknode(list, node, ostr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
zerr("bad pattern: %s", ostr);
|
zerr("bad pattern: %s", ostr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1873,7 +1873,8 @@ zglob(LinkList list, LinkNode np, int nountok)
|
||||||
tmpptr->sortstrs[iexec] = tmpptr->name;
|
tmpptr->sortstrs[iexec] = tmpptr->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
errflag = ef;
|
/* Retain any user interrupt error status */
|
||||||
|
errflag = ef | (errflag & ERRFLAG_INT);
|
||||||
lastval = lv;
|
lastval = lv;
|
||||||
} else {
|
} else {
|
||||||
/* Failed, let's be safe */
|
/* Failed, let's be safe */
|
||||||
|
@ -3733,7 +3734,8 @@ qualsheval(char *name, UNUSED(struct stat *buf), UNUSED(off_t days), char *str)
|
||||||
execode(prog, 1, 0, "globqual");
|
execode(prog, 1, 0, "globqual");
|
||||||
|
|
||||||
ret = lastval;
|
ret = lastval;
|
||||||
errflag = ef;
|
/* Retain any user interrupt error status */
|
||||||
|
errflag = ef | (errflag & ERRFLAG_INT);
|
||||||
lastval = lv;
|
lastval = lv;
|
||||||
|
|
||||||
if (!(inserts = getaparam("reply")) &&
|
if (!(inserts = getaparam("reply")) &&
|
||||||
|
|
10
Src/hist.c
10
Src/hist.c
|
@ -287,7 +287,8 @@ ihgetc(void)
|
||||||
c = histsubchar(c);
|
c = histsubchar(c);
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
/* bad expansion */
|
/* bad expansion */
|
||||||
errflag = lexstop = 1;
|
lexstop = 1;
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
return ' ';
|
return ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -721,7 +722,7 @@ histsubchar(int c)
|
||||||
noerrs = 1;
|
noerrs = 1;
|
||||||
parse_subst_string(sline);
|
parse_subst_string(sline);
|
||||||
noerrs = one;
|
noerrs = one;
|
||||||
errflag = oef;
|
errflag = oef | (errflag & ERRFLAG_INT);
|
||||||
remnulargs(sline);
|
remnulargs(sline);
|
||||||
untokenize(sline);
|
untokenize(sline);
|
||||||
}
|
}
|
||||||
|
@ -880,7 +881,8 @@ hbegin(int dohist)
|
||||||
char *hf;
|
char *hf;
|
||||||
|
|
||||||
isfirstln = isfirstch = 1;
|
isfirstln = isfirstch = 1;
|
||||||
errflag = histdone = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
|
histdone = 0;
|
||||||
if (!dohist)
|
if (!dohist)
|
||||||
stophist = 2;
|
stophist = 2;
|
||||||
else if (dohist != 2)
|
else if (dohist != 2)
|
||||||
|
@ -3182,7 +3184,7 @@ bufferwords(LinkList list, char *buf, int *index, int flags)
|
||||||
noaliases = ona;
|
noaliases = ona;
|
||||||
strinend();
|
strinend();
|
||||||
inpop();
|
inpop();
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
nocomments = onc;
|
nocomments = onc;
|
||||||
noerrs = ne;
|
noerrs = ne;
|
||||||
lexrestore();
|
lexrestore();
|
||||||
|
|
29
Src/init.c
29
Src/init.c
|
@ -118,11 +118,24 @@ loop(int toplevel, int justonce)
|
||||||
if (interact && toplevel) {
|
if (interact && toplevel) {
|
||||||
int hstop = stophist;
|
int hstop = stophist;
|
||||||
stophist = 3;
|
stophist = 3;
|
||||||
|
/*
|
||||||
|
* Reset all errors including the interrupt error status
|
||||||
|
* immediately, so preprompt runs regardless of what
|
||||||
|
* just happened. We'll reset again below as a
|
||||||
|
* precaution to ensure we get back to the command line
|
||||||
|
* no matter what.
|
||||||
|
*/
|
||||||
|
errflag = 0;
|
||||||
preprompt();
|
preprompt();
|
||||||
if (stophist != 3)
|
if (stophist != 3)
|
||||||
hbegin(1);
|
hbegin(1);
|
||||||
else
|
else
|
||||||
stophist = hstop;
|
stophist = hstop;
|
||||||
|
/*
|
||||||
|
* Reset all errors, including user interupts.
|
||||||
|
* This is what allows ^C in an interactive shell
|
||||||
|
* to return us to the command line.
|
||||||
|
*/
|
||||||
errflag = 0;
|
errflag = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +191,15 @@ loop(int toplevel, int justonce)
|
||||||
|
|
||||||
/* The only permanent storage is from getpermtext() */
|
/* The only permanent storage is from getpermtext() */
|
||||||
zsfree(cmdstr);
|
zsfree(cmdstr);
|
||||||
errflag = 0;
|
/*
|
||||||
|
* Note this does *not* remove a user interrupt error
|
||||||
|
* condition, even though we're at the top level loop:
|
||||||
|
* that would be inconsistent with the case where
|
||||||
|
* we didn't execute a preexec function. This is
|
||||||
|
* an implementation detail that an interrupting user
|
||||||
|
* does't care about.
|
||||||
|
*/
|
||||||
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
}
|
}
|
||||||
if (stopmsg) /* unset 'you have stopped jobs' flag */
|
if (stopmsg) /* unset 'you have stopped jobs' flag */
|
||||||
stopmsg--;
|
stopmsg--;
|
||||||
|
@ -689,7 +710,7 @@ init_term(void)
|
||||||
{
|
{
|
||||||
if (isset(INTERACTIVE))
|
if (isset(INTERACTIVE))
|
||||||
zerr("can't find terminal definition for %s", term);
|
zerr("can't find terminal definition for %s", term);
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
termflags |= TERM_BAD;
|
termflags |= TERM_BAD;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1336,7 +1357,7 @@ source(char *s)
|
||||||
|
|
||||||
if (prog) {
|
if (prog) {
|
||||||
pushheap();
|
pushheap();
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
execode(prog, 1, 0, "filecode");
|
execode(prog, 1, 0, "filecode");
|
||||||
popheap();
|
popheap();
|
||||||
if (errflag)
|
if (errflag)
|
||||||
|
@ -1379,7 +1400,7 @@ source(char *s)
|
||||||
lineno = oldlineno; /* our current lineno */
|
lineno = oldlineno; /* our current lineno */
|
||||||
loops = oloops; /* the # of nested loops we are in */
|
loops = oloops; /* the # of nested loops we are in */
|
||||||
dosetopt(SHINSTDIN, oldshst, 1, opts); /* SHINSTDIN option */
|
dosetopt(SHINSTDIN, oldshst, 1, opts); /* SHINSTDIN option */
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
if (!exit_pending)
|
if (!exit_pending)
|
||||||
retflag = 0;
|
retflag = 0;
|
||||||
scriptname = old_scriptname;
|
scriptname = old_scriptname;
|
||||||
|
|
|
@ -291,7 +291,8 @@ inputline(void)
|
||||||
}
|
}
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
free(ingetcline);
|
free(ingetcline);
|
||||||
return lexstop = errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
|
return lexstop = 1;
|
||||||
}
|
}
|
||||||
if (isset(VERBOSE)) {
|
if (isset(VERBOSE)) {
|
||||||
/* Output the whole line read so far. */
|
/* Output the whole line read so far. */
|
||||||
|
|
23
Src/jobs.c
23
Src/jobs.c
|
@ -509,7 +509,7 @@ update_job(Job jn)
|
||||||
prev_errflag = errflag;
|
prev_errflag = errflag;
|
||||||
}
|
}
|
||||||
breaks = loops;
|
breaks = loops;
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_INT;
|
||||||
inerrflush();
|
inerrflush();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -526,7 +526,7 @@ update_job(Job jn)
|
||||||
prev_errflag = errflag;
|
prev_errflag = errflag;
|
||||||
}
|
}
|
||||||
breaks = loops;
|
breaks = loops;
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_INT;
|
||||||
inerrflush();
|
inerrflush();
|
||||||
}
|
}
|
||||||
if (somestopped && jn->stat & STAT_SUPERJOB)
|
if (somestopped && jn->stat & STAT_SUPERJOB)
|
||||||
|
@ -581,7 +581,7 @@ update_job(Job jn)
|
||||||
breaks = loops;
|
breaks = loops;
|
||||||
} else {
|
} else {
|
||||||
breaks = loops;
|
breaks = loops;
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_INT;
|
||||||
}
|
}
|
||||||
check_cursh_sig(sig);
|
check_cursh_sig(sig);
|
||||||
}
|
}
|
||||||
|
@ -1444,12 +1444,19 @@ zwaitjob(int job, int wait_cmd)
|
||||||
restore_queue_signals(q);
|
restore_queue_signals(q);
|
||||||
return 128 + last_signal;
|
return 128 + last_signal;
|
||||||
}
|
}
|
||||||
/* Commenting this out makes ^C-ing a job started by a function
|
/* Commenting this out makes ^C-ing a job started by a function
|
||||||
stop the whole function again. But I guess it will stop
|
stop the whole function again. But I guess it will stop
|
||||||
something else from working properly, we have to find out
|
something else from working properly, we have to find out
|
||||||
what this might be. --oberon
|
what this might be. --oberon
|
||||||
|
|
||||||
|
When attempting to separate errors and interrupts, we
|
||||||
|
assumed because of the previous comment it would be OK
|
||||||
|
to remove ERRFLAG_ERROR and leave ERRFLAG_INT set, since
|
||||||
|
that's the one related to ^C. But that doesn't work.
|
||||||
|
There's something more here we don't understand. --pws
|
||||||
|
|
||||||
|
errflag = 0; */
|
||||||
|
|
||||||
errflag = 0; */
|
|
||||||
if (subsh) {
|
if (subsh) {
|
||||||
killjb(jn, SIGCONT);
|
killjb(jn, SIGCONT);
|
||||||
jn->stat &= ~STAT_STOPPED;
|
jn->stat &= ~STAT_STOPPED;
|
||||||
|
|
|
@ -385,7 +385,7 @@ lexrestore(void)
|
||||||
ecnfunc = ln->ecnfunc;
|
ecnfunc = ln->ecnfunc;
|
||||||
hlinesz = ln->hlinesz;
|
hlinesz = ln->hlinesz;
|
||||||
toklineno = ln->toklineno;
|
toklineno = ln->toklineno;
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
free(ln);
|
free(ln);
|
||||||
|
|
||||||
unqueue_signals();
|
unqueue_signals();
|
||||||
|
@ -1737,7 +1737,8 @@ parse_subst_string(char *s)
|
||||||
inpop();
|
inpop();
|
||||||
DPUTS(cmdsp, "BUG: parse_subst_string: cmdstack not empty.");
|
DPUTS(cmdsp, "BUG: parse_subst_string: cmdstack not empty.");
|
||||||
lexrestore();
|
lexrestore();
|
||||||
errflag = err;
|
/* Keep any interrupt error status */
|
||||||
|
errflag = err | (errflag & ERRFLAG_INT);
|
||||||
if (ctok == LEXERR) {
|
if (ctok == LEXERR) {
|
||||||
untokenize(s);
|
untokenize(s);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
28
Src/loop.c
28
Src/loop.c
|
@ -259,7 +259,8 @@ execselect(Estate state, UNUSED(int do_exec))
|
||||||
0, ZLCON_SELECT);
|
0, ZLCON_SELECT);
|
||||||
if (errflag)
|
if (errflag)
|
||||||
str = NULL;
|
str = NULL;
|
||||||
errflag = oef;
|
/* Keep any user interrupt error status */
|
||||||
|
errflag = oef | (errflag & ERRFLAG_INT);
|
||||||
} else {
|
} else {
|
||||||
str = promptexpand(prompt3, 0, NULL, NULL, NULL);
|
str = promptexpand(prompt3, 0, NULL, NULL, NULL);
|
||||||
zputs(str, stderr);
|
zputs(str, stderr);
|
||||||
|
@ -632,6 +633,14 @@ execcase(Estate state, int do_exec)
|
||||||
zlong
|
zlong
|
||||||
try_errflag = -1;
|
try_errflag = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Corresponding interrupt error status form `try' block.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**/
|
||||||
|
zlong
|
||||||
|
try_interrupt = -1;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
zlong
|
zlong
|
||||||
try_tryflag = 0;
|
try_tryflag = 0;
|
||||||
|
@ -643,7 +652,7 @@ exectry(Estate state, int do_exec)
|
||||||
Wordcode end, always;
|
Wordcode end, always;
|
||||||
int endval;
|
int endval;
|
||||||
int save_retflag, save_breaks, save_contflag;
|
int save_retflag, save_breaks, save_contflag;
|
||||||
zlong save_try_errflag, save_try_tryflag;
|
zlong save_try_errflag, save_try_tryflag, save_try_interrupt;
|
||||||
|
|
||||||
end = state->pc + WC_TRY_SKIP(state->pc[-1]);
|
end = state->pc + WC_TRY_SKIP(state->pc[-1]);
|
||||||
always = state->pc + 1 + WC_TRY_SKIP(*state->pc);
|
always = state->pc + 1 + WC_TRY_SKIP(*state->pc);
|
||||||
|
@ -670,7 +679,10 @@ exectry(Estate state, int do_exec)
|
||||||
|
|
||||||
/* The always clause. */
|
/* The always clause. */
|
||||||
save_try_errflag = try_errflag;
|
save_try_errflag = try_errflag;
|
||||||
try_errflag = (zlong)errflag;
|
save_try_interrupt = try_interrupt;
|
||||||
|
try_errflag = (zlong)(errflag & ERRFLAG_ERROR);
|
||||||
|
try_interrupt = (zlong)((errflag & ERRFLAG_INT) ? 1 : 0);
|
||||||
|
/* We need to reset all errors to allow the block to execute */
|
||||||
errflag = 0;
|
errflag = 0;
|
||||||
save_retflag = retflag;
|
save_retflag = retflag;
|
||||||
retflag = 0;
|
retflag = 0;
|
||||||
|
@ -682,8 +694,16 @@ exectry(Estate state, int do_exec)
|
||||||
state->pc = always;
|
state->pc = always;
|
||||||
execlist(state, 1, do_exec);
|
execlist(state, 1, do_exec);
|
||||||
|
|
||||||
errflag = try_errflag ? 1 : 0;
|
if (try_errflag)
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
|
else
|
||||||
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
|
if (try_interrupt)
|
||||||
|
errflag |= ERRFLAG_INT;
|
||||||
|
else
|
||||||
|
errflag &= ~ERRFLAG_INT;
|
||||||
try_errflag = save_try_errflag;
|
try_errflag = save_try_errflag;
|
||||||
|
try_interrupt = save_try_interrupt;
|
||||||
if (!retflag)
|
if (!retflag)
|
||||||
retflag = save_retflag;
|
retflag = save_retflag;
|
||||||
if (!breaks)
|
if (!breaks)
|
||||||
|
|
13
Src/params.c
13
Src/params.c
|
@ -331,6 +331,7 @@ IPDEF5("SHLVL", &shlvl, varinteger_gsu),
|
||||||
#define IPDEF6(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL|PM_DONTIMPORT},BR((void *)B),GSU(F),10,0,NULL,NULL,NULL,0}
|
#define IPDEF6(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL|PM_DONTIMPORT},BR((void *)B),GSU(F),10,0,NULL,NULL,NULL,0}
|
||||||
IPDEF6("OPTIND", &zoptind, varinteger_gsu),
|
IPDEF6("OPTIND", &zoptind, varinteger_gsu),
|
||||||
IPDEF6("TRY_BLOCK_ERROR", &try_errflag, varinteger_gsu),
|
IPDEF6("TRY_BLOCK_ERROR", &try_errflag, varinteger_gsu),
|
||||||
|
IPDEF6("TRY_BLOCK_INTERRUPT", &try_interrupt, varinteger_gsu),
|
||||||
|
|
||||||
#define IPDEF7(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL},BR((void *)B),GSU(varscalar_gsu),0,0,NULL,NULL,NULL,0}
|
#define IPDEF7(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL},BR((void *)B),GSU(varscalar_gsu),0,0,NULL,NULL,NULL,0}
|
||||||
#define IPDEF7U(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL|PM_UNSET},BR((void *)B),GSU(varscalar_gsu),0,0,NULL,NULL,NULL,0}
|
#define IPDEF7U(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL|PM_UNSET},BR((void *)B),GSU(varscalar_gsu),0,0,NULL,NULL,NULL,0}
|
||||||
|
@ -2654,7 +2655,7 @@ assignsparam(char *s, char *val, int flags)
|
||||||
if (!isident(s)) {
|
if (!isident(s)) {
|
||||||
zerr("not an identifier: %s", s);
|
zerr("not an identifier: %s", s);
|
||||||
zsfree(val);
|
zsfree(val);
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
queue_signals();
|
queue_signals();
|
||||||
|
@ -2783,7 +2784,7 @@ assignaparam(char *s, char **val, int flags)
|
||||||
if (!isident(s)) {
|
if (!isident(s)) {
|
||||||
zerr("not an identifier: %s", s);
|
zerr("not an identifier: %s", s);
|
||||||
freearray(val);
|
freearray(val);
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
queue_signals();
|
queue_signals();
|
||||||
|
@ -2799,7 +2800,7 @@ assignaparam(char *s, char **val, int flags)
|
||||||
zerr("%s: attempt to set slice of associative array",
|
zerr("%s: attempt to set slice of associative array",
|
||||||
v->pm->node.nam);
|
v->pm->node.nam);
|
||||||
freearray(val);
|
freearray(val);
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
v = NULL;
|
v = NULL;
|
||||||
|
@ -2870,13 +2871,13 @@ sethparam(char *s, char **val)
|
||||||
if (!isident(s)) {
|
if (!isident(s)) {
|
||||||
zerr("not an identifier: %s", s);
|
zerr("not an identifier: %s", s);
|
||||||
freearray(val);
|
freearray(val);
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (strchr(s, '[')) {
|
if (strchr(s, '[')) {
|
||||||
freearray(val);
|
freearray(val);
|
||||||
zerr("nested associative arrays not yet supported");
|
zerr("nested associative arrays not yet supported");
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (unset(EXECOPT))
|
if (unset(EXECOPT))
|
||||||
|
@ -2916,7 +2917,7 @@ setnparam(char *s, mnumber val)
|
||||||
|
|
||||||
if (!isident(s)) {
|
if (!isident(s)) {
|
||||||
zerr("not an identifier: %s", s);
|
zerr("not an identifier: %s", s);
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (unset(EXECOPT))
|
if (unset(EXECOPT))
|
||||||
|
|
31
Src/parse.c
31
Src/parse.c
|
@ -71,13 +71,14 @@ struct heredocs *hdocs;
|
||||||
|
|
||||||
#define YYERROR(O) { tok = LEXERR; ecused = (O); return 0; }
|
#define YYERROR(O) { tok = LEXERR; ecused = (O); return 0; }
|
||||||
#define YYERRORV(O) { tok = LEXERR; ecused = (O); return; }
|
#define YYERRORV(O) { tok = LEXERR; ecused = (O); return; }
|
||||||
#define COND_ERROR(X,Y) do { \
|
#define COND_ERROR(X,Y) \
|
||||||
zwarn(X,Y); \
|
do { \
|
||||||
herrflush(); \
|
zwarn(X,Y); \
|
||||||
if (noerrs != 2) \
|
herrflush(); \
|
||||||
errflag = 1; \
|
if (noerrs != 2) \
|
||||||
YYERROR(ecused) \
|
errflag |= ERRFLAG_ERROR; \
|
||||||
} while(0)
|
YYERROR(ecused) \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -506,7 +507,7 @@ par_event(void)
|
||||||
yyerror(1);
|
yyerror(1);
|
||||||
herrflush();
|
herrflush();
|
||||||
if (noerrs != 2)
|
if (noerrs != 2)
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
ecused--;
|
ecused--;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2339,7 +2340,7 @@ yyerror(int noerr)
|
||||||
zwarn("parse error");
|
zwarn("parse error");
|
||||||
}
|
}
|
||||||
if (!noerr && noerrs != 2)
|
if (!noerr && noerrs != 2)
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3031,7 +3032,7 @@ build_dump(char *nam, char *dump, char **files, int ali, int map, int flags)
|
||||||
file = metafy(file, flen, META_REALLOC);
|
file = metafy(file, flen, META_REALLOC);
|
||||||
|
|
||||||
if (!(prog = parse_string(file, 1)) || errflag) {
|
if (!(prog = parse_string(file, 1)) || errflag) {
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
close(dfd);
|
close(dfd);
|
||||||
zfree(file, flen);
|
zfree(file, flen);
|
||||||
zwarnnam(nam, "can't read file: %s", *files);
|
zwarnnam(nam, "can't read file: %s", *files);
|
||||||
|
@ -3141,7 +3142,7 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map,
|
||||||
for (hn = shfunctab->nodes[i]; hn; hn = hn->next)
|
for (hn = shfunctab->nodes[i]; hn; hn = hn->next)
|
||||||
if (cur_add_func(nam, (Shfunc) hn, lnames, progs,
|
if (cur_add_func(nam, (Shfunc) hn, lnames, progs,
|
||||||
&hlen, &tlen, what)) {
|
&hlen, &tlen, what)) {
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
close(dfd);
|
close(dfd);
|
||||||
unlink(dump);
|
unlink(dump);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -3166,7 +3167,7 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map,
|
||||||
pattry(pprog, hn->nam) &&
|
pattry(pprog, hn->nam) &&
|
||||||
cur_add_func(nam, (Shfunc) hn, lnames, progs,
|
cur_add_func(nam, (Shfunc) hn, lnames, progs,
|
||||||
&hlen, &tlen, what)) {
|
&hlen, &tlen, what)) {
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
close(dfd);
|
close(dfd);
|
||||||
unlink(dump);
|
unlink(dump);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -3177,13 +3178,13 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map,
|
||||||
if (errflag ||
|
if (errflag ||
|
||||||
!(shf = (Shfunc) shfunctab->getnode(shfunctab, *names))) {
|
!(shf = (Shfunc) shfunctab->getnode(shfunctab, *names))) {
|
||||||
zwarnnam(nam, "unknown function: %s", *names);
|
zwarnnam(nam, "unknown function: %s", *names);
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
close(dfd);
|
close(dfd);
|
||||||
unlink(dump);
|
unlink(dump);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (cur_add_func(nam, shf, lnames, progs, &hlen, &tlen, what)) {
|
if (cur_add_func(nam, shf, lnames, progs, &hlen, &tlen, what)) {
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
close(dfd);
|
close(dfd);
|
||||||
unlink(dump);
|
unlink(dump);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -3192,7 +3193,7 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map,
|
||||||
}
|
}
|
||||||
if (empty(progs)) {
|
if (empty(progs)) {
|
||||||
zwarnnam(nam, "no functions");
|
zwarnnam(nam, "no functions");
|
||||||
errflag = 0;
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
close(dfd);
|
close(dfd);
|
||||||
unlink(dump);
|
unlink(dump);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -192,8 +192,11 @@ promptexpand(char *s, int ns, char *rs, char *Rs, unsigned int *txtchangep)
|
||||||
if (*s == Nularg && s[1] == '\0')
|
if (*s == Nularg && s[1] == '\0')
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
|
|
||||||
/* Ignore errors and status change in prompt substitution */
|
/*
|
||||||
errflag = olderr;
|
* Ignore errors and status change in prompt substitution.
|
||||||
|
* However, keep any user interrupt error that occurred.
|
||||||
|
*/
|
||||||
|
errflag = olderr | (errflag & ERRFLAG_INT);
|
||||||
lastval = oldval;
|
lastval = oldval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -619,7 +619,7 @@ zhandler(int sig)
|
||||||
zexit(SIGINT, 1);
|
zexit(SIGINT, 1);
|
||||||
if (list_pipe || chline || simple_pline) {
|
if (list_pipe || chline || simple_pline) {
|
||||||
breaks = loops;
|
breaks = loops;
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_INT;
|
||||||
inerrflush();
|
inerrflush();
|
||||||
check_cursh_sig(SIGINT);
|
check_cursh_sig(SIGINT);
|
||||||
}
|
}
|
||||||
|
@ -640,6 +640,11 @@ zhandler(int sig)
|
||||||
if (idle >= 0 && idle < tmout)
|
if (idle >= 0 && idle < tmout)
|
||||||
alarm(tmout - idle);
|
alarm(tmout - idle);
|
||||||
else {
|
else {
|
||||||
|
/*
|
||||||
|
* We want to exit now.
|
||||||
|
* Cancel all errors, including a user interrupt
|
||||||
|
* which is now redundant.
|
||||||
|
*/
|
||||||
errflag = noerrs = 0;
|
errflag = noerrs = 0;
|
||||||
zwarn("timeout");
|
zwarn("timeout");
|
||||||
stopmsg = 1;
|
stopmsg = 1;
|
||||||
|
@ -1267,7 +1272,18 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
|
||||||
!(isfunc && new_trap_return == 0)) {
|
!(isfunc && new_trap_return == 0)) {
|
||||||
if (isfunc) {
|
if (isfunc) {
|
||||||
breaks = loops;
|
breaks = loops;
|
||||||
errflag = 1;
|
/*
|
||||||
|
* For SIGINT we behave the same as the default behaviour
|
||||||
|
* i.e. we set the error bit indicating an interrupt.
|
||||||
|
* We do this with SIGQUIT, too, even though we don't
|
||||||
|
* handle SIGQUIT by default. That's to try to make
|
||||||
|
* it behave a bit more like its normal behaviour when
|
||||||
|
* the trap handler has told us that's what it wants.
|
||||||
|
*/
|
||||||
|
if (sig == SIGINT || sig == SIGQUIT)
|
||||||
|
errflag |= ERRFLAG_INT;
|
||||||
|
else
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
}
|
}
|
||||||
lastval = new_trap_return;
|
lastval = new_trap_return;
|
||||||
/* return triggered */
|
/* return triggered */
|
||||||
|
@ -1282,8 +1298,12 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
|
||||||
*/
|
*/
|
||||||
lastval = olastval;
|
lastval = olastval;
|
||||||
}
|
}
|
||||||
if (try_tryflag)
|
if (try_tryflag) {
|
||||||
errflag = traperr;
|
if (traperr)
|
||||||
|
errflag |= ERRFLAG_ERROR;
|
||||||
|
else
|
||||||
|
errflag &= ~ERRFLAG_ERROR;
|
||||||
|
}
|
||||||
breaks += obreaks;
|
breaks += obreaks;
|
||||||
/* return not triggered: restore old flag */
|
/* return not triggered: restore old flag */
|
||||||
retflag = oretflag;
|
retflag = oretflag;
|
||||||
|
|
27
Src/subst.c
27
Src/subst.c
|
@ -2822,7 +2822,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
haserr = parse_subst_string(s);
|
haserr = parse_subst_string(s);
|
||||||
noerrs = one;
|
noerrs = one;
|
||||||
if (!quoteerr) {
|
if (!quoteerr) {
|
||||||
errflag = oef;
|
/* Retain user interrupt error status */
|
||||||
|
errflag = oef | (errflag & ERRFLAG_INT);
|
||||||
if (haserr)
|
if (haserr)
|
||||||
shtokenize(s);
|
shtokenize(s);
|
||||||
} else if (haserr || errflag) {
|
} else if (haserr || errflag) {
|
||||||
|
@ -3249,8 +3250,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
haserr = 1;
|
haserr = 1;
|
||||||
}
|
}
|
||||||
noerrs = one;
|
noerrs = one;
|
||||||
if (!quoteerr)
|
if (!quoteerr) {
|
||||||
errflag = oef;
|
/* Retain user interrupt error status */
|
||||||
|
errflag = oef | (errflag & ERRFLAG_INT);
|
||||||
|
}
|
||||||
if (haserr || errflag)
|
if (haserr || errflag)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -3483,8 +3486,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
untokenize(*ap);
|
untokenize(*ap);
|
||||||
}
|
}
|
||||||
noerrs = one;
|
noerrs = one;
|
||||||
if (!quoteerr)
|
if (!quoteerr) {
|
||||||
errflag = oef;
|
/* Retain any user interrupt error status */
|
||||||
|
errflag = oef | (errflag & ERRFLAG_INT);
|
||||||
|
}
|
||||||
else if (haserr || errflag) {
|
else if (haserr || errflag) {
|
||||||
zerr("parse error in parameter value");
|
zerr("parse error in parameter value");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -3516,8 +3521,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
noerrs = 1;
|
noerrs = 1;
|
||||||
haserr = parse_subst_string(val);
|
haserr = parse_subst_string(val);
|
||||||
noerrs = one;
|
noerrs = one;
|
||||||
if (!quoteerr)
|
if (!quoteerr) {
|
||||||
errflag = oef;
|
/* Retain any user interrupt error status */
|
||||||
|
errflag = oef | (errflag & ERRFLAG_INT);
|
||||||
|
}
|
||||||
else if (haserr || errflag) {
|
else if (haserr || errflag) {
|
||||||
zerr("parse error in parameter value");
|
zerr("parse error in parameter value");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -4086,7 +4093,8 @@ modify(char **str, char **ptr)
|
||||||
noerrs = 1;
|
noerrs = 1;
|
||||||
parse_subst_string(copy);
|
parse_subst_string(copy);
|
||||||
noerrs = one;
|
noerrs = one;
|
||||||
errflag = oef;
|
/* Retain any user interrupt error status */
|
||||||
|
errflag = oef | (errflag & ERRFLAG_INT);
|
||||||
remnulargs(copy);
|
remnulargs(copy);
|
||||||
untokenize(copy);
|
untokenize(copy);
|
||||||
}
|
}
|
||||||
|
@ -4161,7 +4169,8 @@ modify(char **str, char **ptr)
|
||||||
noerrs = 1;
|
noerrs = 1;
|
||||||
parse_subst_string(*str);
|
parse_subst_string(*str);
|
||||||
noerrs = one;
|
noerrs = one;
|
||||||
errflag = oef;
|
/* Retain any user interrupt error status */
|
||||||
|
errflag = oef | (errflag & ERRFLAG_INT);
|
||||||
remnulargs(*str);
|
remnulargs(*str);
|
||||||
untokenize(*str);
|
untokenize(*str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ VA_DCL
|
||||||
|
|
||||||
if (errflag || noerrs) {
|
if (errflag || noerrs) {
|
||||||
if (noerrs < 2)
|
if (noerrs < 2)
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ VA_DCL
|
||||||
VA_GET_ARG(ap, fmt, const char *);
|
VA_GET_ARG(ap, fmt, const char *);
|
||||||
zwarning(NULL, fmt, ap);
|
zwarning(NULL, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
@ -181,7 +181,7 @@ VA_DCL
|
||||||
VA_GET_ARG(ap, fmt, const char *);
|
VA_GET_ARG(ap, fmt, const char *);
|
||||||
zwarning(cmd, fmt, ap);
|
zwarning(cmd, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
@ -330,7 +330,7 @@ zerrmsg(FILE *file, const char *fmt, va_list ap)
|
||||||
num = va_arg(ap, int);
|
num = va_arg(ap, int);
|
||||||
if (num == EINTR) {
|
if (num == EINTR) {
|
||||||
fputs("interrupt\n", file);
|
fputs("interrupt\n", file);
|
||||||
errflag = 1;
|
errflag |= ERRFLAG_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
errmsg = strerror(num);
|
errmsg = strerror(num);
|
||||||
|
|
14
Src/zsh.h
14
Src/zsh.h
|
@ -2623,6 +2623,20 @@ enum trap_state {
|
||||||
#define IN_EVAL_TRAP() \
|
#define IN_EVAL_TRAP() \
|
||||||
(intrap && !trapisfunc && traplocallevel == locallevel)
|
(intrap && !trapisfunc && traplocallevel == locallevel)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in the errflag variable.
|
||||||
|
*/
|
||||||
|
enum errflag_bits {
|
||||||
|
/*
|
||||||
|
* Standard internal error bit.
|
||||||
|
*/
|
||||||
|
ERRFLAG_ERROR = 1,
|
||||||
|
/*
|
||||||
|
* User interrupt.
|
||||||
|
*/
|
||||||
|
ERRFLAG_INT = 2
|
||||||
|
};
|
||||||
|
|
||||||
/***********/
|
/***********/
|
||||||
/* Sorting */
|
/* Sorting */
|
||||||
/***********/
|
/***********/
|
||||||
|
|
Loading…
Reference in a new issue