diff -up ksh-20100621/src/cmd/ksh93/sh/jobs.c.joblimit ksh-20100621/src/cmd/ksh93/sh/jobs.c --- ksh-20100621/src/cmd/ksh93/sh/jobs.c.joblimit 2011-10-11 11:35:40.565530240 +0200 +++ ksh-20100621/src/cmd/ksh93/sh/jobs.c 2011-10-11 11:36:10.246791092 +0200 @@ -94,6 +94,7 @@ struct back_save { int count; struct jobsave *list; + struct back_save *prev; }; #define BYTE(n) (((n)+CHAR_BIT-1)/CHAR_BIT) @@ -148,6 +149,7 @@ static char by_number; static Sfio_t *outfile; static pid_t lastpid; static struct back_save bck; +static int jobfork; #ifdef JOBS static void job_set(struct process*); @@ -306,6 +308,8 @@ int job_reap(register int sig) continue; if(pid<=0) break; + /*if(pid==0) + job_chksave(pid);*/ flags |= WNOHANG; job.waitsafe++; jp = 0; @@ -1218,7 +1222,7 @@ int job_post(pid_t pid, pid_t join) else pw->p_name = -1; #endif /* JOBS */ - if ((val = job_chksave(pid)) >= 0) + if ((val = job_chksave(pid))>=0 && !jobfork) { pw->p_exit = val; if(pw->p_exit==SH_STOPSIG) @@ -1752,6 +1756,8 @@ static int job_chksave(register pid_t pi register struct jobsave *jp = bck.list, *jpold=0; register int r= -1; register int count=bck.count; + struct back_save *bp= &bck; +again: while(jp && count-->0) { if(jp->pid==pid) @@ -1761,6 +1767,12 @@ static int job_chksave(register pid_t pi jpold = jp; jp = jp->next; } + if(!jp && pid && (bp=bp->prev)) + { + count = bp->count; + jp = bp->list; + goto again; + } if(jp) { r = 0; @@ -1769,8 +1781,8 @@ static int job_chksave(register pid_t pi if(jpold) jpold->next = jp->next; else - bck.list = jp->next; - bck.count--; + bp->list = jp->next; + bp->count--; if(njob_savelist < NJOB_SAVELIST) { njob_savelist++; @@ -1788,28 +1800,35 @@ void *job_subsave(void) struct back_save *bp = new_of(struct back_save,0); job_lock(); *bp = bck; + bp->prev = bck.prev; bck.count = 0; bck.list = 0; + bck.prev = bp; job_unlock(); return((void*)bp); } void job_subrestore(void* ptr) { - register struct jobsave *jp; + register struct jobsave *jp, *jpnext; register struct back_save *bp = (struct back_save*)ptr; register struct process *pw, *px, *pwnext; struct jobsave *end=NULL; job_lock(); for(jp=bck.list; jp; jp=jp->next) + { if (!jp->next) end = jp; + } if(end) end->next = bp->list; else bck.list = bp->list; bck.count += bp->count; + bck.prev = bp->prev; + while(bck.count > sh.lim.child_max) + job_chksave(0); for(pw=job.pwlist; pw; pw=pwnext) { pwnext = pw->p_nxtjob; @@ -1838,14 +1857,17 @@ void job_fork(pid_t parent) { case -1: job_lock(); + jobfork++; break; case 0: job_unlock(); + jobfork--; job.waitsafe = 0; job.in_critical = 0; break; default: - job_chksave(parent); + jobfork--; +// job_chksave(parent); job_unlock(); break; } diff -up ksh-20100621/src/cmd/ksh93/sh/xec.c.joblimit ksh-20100621/src/cmd/ksh93/sh/xec.c --- ksh-20100621/src/cmd/ksh93/sh/xec.c.joblimit 2011-10-11 11:35:40.567530258 +0200 +++ ksh-20100621/src/cmd/ksh93/sh/xec.c 2011-10-11 11:35:40.571530293 +0200 @@ -3096,7 +3096,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons static int savetype; static int savejobid; struct checkpt buff; - int otype=0, jmpval; + int otype=0, jmpval,jobfork=0; volatile int jobwasset=0, scope=0, sigwasset=0; char **arge, *path; volatile pid_t grp = 0; @@ -3314,6 +3314,8 @@ static pid_t sh_ntfork(Shell_t *shp,cons sigwasset++; /* find first path that has a library component */ for(pp=path_get(argv[0]); pp && !pp->lib ; pp=pp->next); + job_fork(-1); + jobfork = 1; spawnpid = path_spawn(path,argv,arge,pp,(grp<<1)|1); if(spawnpid < 0 && errno==ENOEXEC) { @@ -3336,6 +3338,8 @@ static pid_t sh_ntfork(Shell_t *shp,cons argv[0] = argv[-1]; } fail: + if(jobfork && spawnpid<0) + job_fork(spawnpid); if(spawnpid < 0) switch(errno=shp->path_err) { case ENOENT: @@ -3371,6 +3375,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons if(spawnpid>0) { _sh_fork(spawnpid,otype,jobid); + job_fork(spawnpid); #ifdef JOBS if(grp==1) job.curpgid = spawnpid;