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

Fix crash, take three (re: e805c7d9, 33858689)

The current fix appears to be only partially successful in
eliminating the intermittent crash, and also breaks '-o notify'
during the 60-second $TMOUT grace period. This replaces it.

The root cause appears to be that the state of job control becomes
somehow inconsistent when running external commands in a command
substitution expanded from the $PS1 prompt. The job_unpost() or
(sometimes) the job_list() function intermittently crash. These are
called if the SH_TTYWAIT state is active:
88e8fa67/src/cmd/ksh93/sh/jobs.c (L463-L469)
Temporarily deactivating the SSH_TTYWAIT state while expanding
PS{1..4} prompts appears to fix the problem reliably.

It is quite possible that this fix merely masks a bug in the job
control system, but testing has shown that it stops ksh crashing
without side effects, so I'm calling it good for now.

Thanks to Marc Wilson for many hours of persistent testing.

src/cmd/ksh93/sh/jobs.c:
- Revert changes made in 33858689 and e805c7d9.

src/cmd/ksh93/sh/io.c: io_prompt():
- Save SH_TTYWAIT state and turn it off while expanding prompts.

Resolves: https://github.com/ksh93/ksh/issues/103
Resolves: https://github.com/ksh93/ksh/issues/112
This commit is contained in:
Martijn Dekker 2020-08-11 01:02:31 +01:00
parent 8477d2ce22
commit 61437b2728
3 changed files with 9 additions and 7 deletions

View file

@ -2067,12 +2067,15 @@ static int io_prompt(Shell_t *shp,Sfio_t *iop,register int flag)
char *endprompt;
static short cmdno;
int sfflags;
int was_ttywait_on;
if(flag<3 && !sh_isstate(SH_INTERACTIVE))
flag = 0;
if(flag==2 && sfpkrd(sffileno(iop),buff,1,'\n',0,1) >= 0)
flag = 0;
if(flag==0)
return(sfsync(sfstderr));
was_ttywait_on = sh_isstate(SH_TTYWAIT);
sh_offstate(SH_TTYWAIT);
sfflags = sfset(sfstderr,SF_SHARE|SF_PUBLIC|SF_READ,0);
if(!(shp->prompt=(char*)sfreserve(sfstderr,0,0)))
shp->prompt = "";
@ -2125,6 +2128,8 @@ static int io_prompt(Shell_t *shp,Sfio_t *iop,register int flag)
done:
if(*shp->prompt && (endprompt=(char*)sfreserve(sfstderr,0,0)))
*endprompt = 0;
if(was_ttywait_on)
sh_onstate(SH_TTYWAIT);
sfset(sfstderr,sfflags&SF_READ|SF_SHARE|SF_PUBLIC,1);
return(sfsync(sfstderr));
}

View file

@ -460,7 +460,7 @@ int job_reap(register int sig)
nochild = 1;
}
shp->gd->waitevent = waitevent;
if(job.jobcontrol && sh_isoption(SH_NOTIFY) && sh_isstate(SH_TTYWAIT) && !sh_isstate(SH_GRACE))
if(sh_isoption(SH_NOTIFY) && sh_isstate(SH_TTYWAIT))
{
outfile = sfstderr;
job_list(pw,JOB_NFLAG|JOB_NLFLAG);