--- src/cmd/ksh93/sh/jobs.c +++ src/cmd/ksh93/sh/jobs.c Tue Aug 28 12:58:29 2007 @@ -43,6 +43,8 @@ # define WIFCONTINUED(wstat) (0) #endif +#define NJOB_SAVELIST 4 + /* * temporary hack to get W* macros to work */ @@ -59,13 +61,35 @@ unsigned short exitval; }; +static struct jobsave *job_savelist; +static int njob_savelist; + +static void init_savelist(void) +{ + register struct jobsave *jp; + while(njob_savelist < NJOB_SAVELIST) + { + jp = newof(0,struct jobsave,1,0); + jp->next = job_savelist; + job_savelist = jp; + njob_savelist++; + } +} + /* * return next on link list of jobsave free list */ static struct jobsave *jobsave_create(pid_t pid) { - struct jobsave *jp; - if(jp = newof(0,struct jobsave,1,0)) + register struct jobsave *jp = job_savelist; + if(jp) + { + njob_savelist--; + job_savelist = jp->next; + } + else + jp = newof(0,struct jobsave,1,0); + if(jp) jp->pid = pid; return(jp); } @@ -371,6 +395,8 @@ # if defined(SIGCLD) && (SIGCLD!=SIGCHLD) signal(SIGCLD,job_waitsafe); # endif + if(njob_savelist < NJOB_SAVELIST) + init_savelist(); if(!sh_isoption(SH_INTERACTIVE)) return; /* use new line discipline when available */ @@ -993,6 +1019,8 @@ free((void*)jp); } bck.list = 0; + if(njob_savelist < NJOB_SAVELIST) + init_savelist(); job.pwlist = NIL(struct process*); job.numpost=0; job.waitall = 0; @@ -1015,6 +1043,8 @@ register struct process *pw; register History_t *hp = sh.hist_ptr; sh.jobenv = sh.curenv; + if(njob_savelist < NJOB_SAVELIST) + init_savelist(); if(job.toclear) { job_clear(); @@ -1273,7 +1303,13 @@ px->p_flag &= ~P_EXITSAVE; } } - if(!(px=job_unpost(pw,1)) || !job.waitall) + if(!job.waitall) + { + if(!sh_isoption(SH_PIPEFAIL)) + job_unpost(pw,1); + break; + } + else if(!(px=job_unpost(pw,1))) break; pw = px; continue; @@ -1312,6 +1348,8 @@ else tty_set(-1, 0, NIL(struct termios*)); done: + if(!job.waitall && sh_isoption(SH_PIPEFAIL)) + return; if(!sh.intrap) { job_lock(); @@ -1593,7 +1631,14 @@ else bck.list = jp->next; bck.count--; - free((void*)jp); + if(njob_savelist < NJOB_SAVELIST) + { + njob_savelist++; + jp->next = job_savelist; + job_savelist = jp; + } + else + free((void*)jp); } return(r); }