diff --git a/NEWS b/NEWS index 5ad37b063916..97db9550eb9b 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,15 @@ Any uppercase BUG_* names are modernish shell bug IDs. [1] 30909 <--- incorrect job control output from subshell done +- Fixed: after suspending (Ctrl+Z) a subshell that is running an external + command, resuming the subshell with 'fg' failed and the job was lost. + $ (vi) <--- press Ctrl+Z + [2] + Stopped (vi) + $ fg + (vi) <--- vi failed to resume; immediate return to command line + $ fg + ksh: no such job + 2021-12-20: - Ported performance optimizations from illumos to improve the performance diff --git a/src/cmd/ksh93/sh/fault.c b/src/cmd/ksh93/sh/fault.c index 92146f40d28f..1ba4a38b1683 100644 --- a/src/cmd/ksh93/sh/fault.c +++ b/src/cmd/ksh93/sh/fault.c @@ -547,7 +547,7 @@ void sh_exit(register int xno) sh_offstate(SH_STOPOK); shp->trapnote = 0; shp->forked = 1; - if(!shp->subshell && (sig=sh_fork(shp,0,NIL(int*)))) + if(sh_isstate(SH_INTERACTIVE) && (sig=sh_fork(shp,0,NIL(int*)))) { job.curpgid = 0; job.parent = (pid_t)-1; @@ -564,7 +564,7 @@ void sh_exit(register int xno) { if(shp->subshell) sh_subfork(); - /* child process, put to sleep */ + /* script or child process; put to sleep */ sh_offstate(SH_STOPOK); sh_offstate(SH_MONITOR); shp->sigflag[SIGTSTP] = 0; diff --git a/src/cmd/ksh93/sh/main.c b/src/cmd/ksh93/sh/main.c index 0ce2d81a94aa..17efc8451ba9 100644 --- a/src/cmd/ksh93/sh/main.c +++ b/src/cmd/ksh93/sh/main.c @@ -160,9 +160,11 @@ int sh_main(int ac, char *av[], Shinit_f userinit) else sh_onoption(SH_BRACEEXPAND); #endif - if((beenhere++)==0) + if(!beenhere) { + beenhere++; sh_onstate(SH_PROFILE); + shp->sigflag[SIGTSTP] |= SH_SIGIGNORE; if(shp->gd->ppid==1) shp->login_sh++; if(shp->login_sh >= 2) @@ -236,6 +238,7 @@ int sh_main(int ac, char *av[], Shinit_f userinit) sh_source(shp, iop, e_suidprofile); } shp->st.cmdname = error_info.id = command; + shp->sigflag[SIGTSTP] &= ~(SH_SIGIGNORE); sh_offstate(SH_PROFILE); if(rshflag) sh_onoption(SH_RESTRICTED); diff --git a/src/cmd/ksh93/sh/subshell.c b/src/cmd/ksh93/sh/subshell.c index 81ab3ae01b2d..f76a6168ecd9 100644 --- a/src/cmd/ksh93/sh/subshell.c +++ b/src/cmd/ksh93/sh/subshell.c @@ -660,6 +660,16 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) sh_subfork(); } #endif /* _lib_fchdir */ +#ifdef SIGTSTP + /* Virtual subshells are not safe to suspend (^Z, SIGTSTP) in the interactive main shell. */ + if(sh_isstate(SH_INTERACTIVE)) + { + if(comsub) + sigblock(SIGTSTP); + else if(!sh_isstate(SH_PROFILE)) + sh_subfork(); + } +#endif sh_offstate(SH_INTERACTIVE); sh_exec(t,flags); } @@ -686,6 +696,10 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) nv_restore(sp); if(comsub) { +#ifdef SIGTSTP + if(savst.states & sh_state(SH_INTERACTIVE)) + sigrelease(SIGTSTP); +#endif /* re-enable job control */ if(!sp->nofork) sh_offstate(SH_NOFORK);