1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

xtrace: fix restore of standard error stream state

The sh_trace() function, which prints an xtrace line to standard
error, clears the SF_SHARE and SF_PUBLIC flags from the sfstderr
stream during the xtrace in order to guarantee an atomic trace
write. But it only restored those flags if the passed argv pointer
is non-NULL. Redirections are traced with a NULL argv parameter, so
the stderr state was not restored for them.

This somehow caused unpredictable behaviour, including (on some
systems) a crash in sfwrite(3) when running the heredoc.sh tests
with xtrace on.

src/cmd/ksh93/sh/xec.c: sh_xtrace():
- Move the sfset() invocation that restores the SF_SHARE|SF_PUBLIC
  flags to sfstderr out of the if(argv) block.
- Since we're here, don't bother wasting cycles initialising local
  variable values if xtrace is not on. Move that inside the
  if(sh_isoption(SH_XTRACE)) block.

Resolves: https://github.com/ksh93/ksh/issues/306
This commit is contained in:
Martijn Dekker 2021-11-07 22:27:02 +00:00
parent c7140cf01c
commit d7cada7b2e

View file

@ -2795,12 +2795,12 @@ int sh_run(int argn, char *argv[])
int sh_trace(Shell_t *shp,register char *argv[], register int nl)
{
register char *cp;
register int bracket = 0;
int decl = (nl&2);
nl &= ~2;
if(sh_isoption(SH_XTRACE))
{
register char *cp;
register int bracket = 0;
int decl = (nl&2);
nl &= ~2;
/* make this trace atomic */
sfset(sfstderr,SF_SHARE|SF_PUBLIC,0);
if(!(cp=nv_getval(sh_scoped(shp,PS4NOD))))
@ -2836,8 +2836,8 @@ int sh_trace(Shell_t *shp,register char *argv[], register int nl)
}
sfputr(sfstderr,cp,*argv?' ':nl);
}
sfset(sfstderr,SF_SHARE|SF_PUBLIC,1);
}
sfset(sfstderr,SF_SHARE|SF_PUBLIC,1);
return(1);
}
return(0);