2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: jobs.c /main/4 1996/10/04 15:50:46 drk $ */
24 /***************************************************************
26 * AT&T - PROPRIETARY *
28 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF *
29 * AT&T BELL LABORATORIES *
30 * AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN *
31 * ACCORDANCE WITH APPLICABLE AGREEMENTS *
33 * Copyright (c) 1995 AT&T Corp. *
34 * Unpublished & Not for Publication *
35 * All Rights Reserved *
37 * The copyright notice above does not evidence any *
38 * actual or intended publication of such source code *
40 * This software was created by the *
41 * Advanced Software Technology Department *
42 * AT&T Bell Laboratories *
44 * For further information contact *
45 * {research,attmail}!dgk *
47 ***************************************************************/
49 /* : : generated by proto : : */
51 #if !defined(__PROTO__)
52 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
53 #if defined(__cplusplus)
54 #define __MANGLE__ "C"
59 #define __PROTO__(x) x
61 #define __PARAM__(n,o) n
62 #if !defined(__STDC__) && !defined(__cplusplus)
63 #if !defined(c_plusplus)
74 #define __PROTO__(x) ()
75 #define __OTORP__(x) x
76 #define __PARAM__(n,o) o
84 #if defined(__cplusplus) || defined(c_plusplus)
85 #define __VARARG__ ...
89 #if defined(__STDARG__)
90 #define __VA_START__(p,a) va_start(p,a)
92 #define __VA_START__(p,a) va_start(p)
103 * temporary hack to get W* macros to work
106 #define wait ______wait
108 * This struct saves a link list of processes that have non-zero exit
109 * status, have had $! saved, but haven't been waited for
113 struct jobsave *next;
115 unsigned short exitval;
120 #define BYTE(n) (1+ (n)/CHAR_BIT)
125 # ifdef _POSIX_VDISABLE
126 # define CNSUSP _POSIX_VDISABLE
129 # endif /* _POSIX_VDISABLE */
133 # define CSWTCH CSUSP
135 # define CSWTCH ('z'&037)
141 #define P_EXITSAVE 01
144 #define P_SIGNALLED 010
147 #define P_COREDUMP 0100
148 #define P_DISOWN 0200
150 static struct process *job_bypid __PROTO__((pid_t));
151 static struct process *job_byjid __PROTO__((int));
152 static char *job_sigmsg __PROTO__((int));
153 static int job_alloc __PROTO__((void));
154 static void job_free __PROTO__((int));
155 static struct process *job_unpost __PROTO__((struct process*,int));
156 static void job_unlink __PROTO__((struct process*));
157 static void job_prmsg __PROTO__((struct process*));
158 static struct process *freelist;
159 static char beenhere;
160 static char possible;
162 static struct process dummy;
163 static int bck_count;
164 static struct jobsave *bck_list;
165 static char by_number;
166 static Sfio_t *outfile;
169 static void job_set __PROTO__((struct process*));
170 static void job_reset __PROTO__((struct process*));
171 static void job_waitsafe __PROTO__((int));
172 static struct process *job_byname __PROTO__((char*));
173 static struct process *job_bystring __PROTO__((char*));
174 static struct termios my_stty; /* terminal state for shell */
175 static char *job_string;
177 extern __MANGLE__ const char e_coredump[];
181 static void job_unstop __PROTO__((struct process*));
182 static void job_fgrp __PROTO__((struct process*, int));
183 # ifndef _lib_tcgetpgrp
186 # define tcgetpgrp(a) (ioctl(a, TIOCGPGRP, &_i_)>=0?_i_:-1)
187 # endif /* TIOCGPGRP */
188 int tcsetpgrp __PARAM__((int fd,pid_t pgrp), (fd, pgrp)) __OTORP__(int fd;pid_t pgrp;){
191 return(ioctl(fd, TIOCSPGRP, &pgid));
194 # endif /* TIOCGPGRP */
196 # endif /* _lib_tcgetpgrp */
198 # define job_unstop(pw)
204 #endif /* OTTYDISC */
210 * This is the SIGCLD interrupt routine
211 * When called with sig==0, it does a blocking wait
213 static void job_waitsafe __PARAM__((register int sig), (sig)) __OTORP__(register int sig;){
215 register struct process *pw;
217 struct process dummy;
221 if(sfprintf(sfstderr,"%ld: signal %d critical=%d\n",(long)getpid(),sig,job.in_critical) <=0)
222 write(2,"waitsafe\n",9);
225 if(job.in_critical && sig)
232 flags = WNOHANG|WUNTRACED;
242 pid = waitpid((pid_t)-1,&wstat,flags);
243 if(sig && pid<0 && errno==EINTR)
249 if(!(pw=job_bypid(pid)))
252 sfprintf(sfstderr,"%ld: unknown job pid=%ld pw=%p\n",(long)getpid(),(long)pid,pw);
254 if(WIFSTOPPED(wstat))
257 if(bck_count++ > sh.lim.child_max)
259 jp = new_of(struct jobsave,0);
262 pw->p_pid = jp->pid = pid;
268 if(WIFSTOPPED(wstat))
270 /* move to top of job list */
271 struct process *px=job_byjid(pw->p_job);
273 px->p_nxtjob = job.pwlist;
275 pw->p_exit = WSTOPSIG(wstat);
276 pw->p_flag |= (P_NOTIFY|P_SIGNALLED|P_STOPPED);
277 if(pw->p_pgrp && pw->p_pgrp==job.curpgid && sh_isstate(SH_STOPOK))
278 sh_fault(pw->p_exit);
284 /* check for coprocess completion */
287 sh_close(sh.coutpipe);
288 sh_close(sh.cpipe[1]);
292 if (WIFSIGNALED(wstat))
294 pw->p_flag &= ~P_STOPPED;
295 pw->p_flag |= (P_DONE|P_NOTIFY|P_SIGNALLED);
296 if (WTERMCORE(wstat))
297 pw->p_flag |= P_COREDUMP;
298 pw->p_exit = WTERMSIG(wstat);
299 /* if process in current jobs terminates from
300 * an interrupt, propogate to parent shell
302 if(pw->p_pgrp && pw->p_pgrp==job.curpgid && pw->p_exit==SIGINT && sh_isstate(SH_STOPOK))
304 pw->p_flag &= ~P_NOTIFY;
305 sh_offstate(SH_STOPOK);
307 sh_onstate(SH_STOPOK);
312 pw->p_flag |= (P_DONE|P_NOTIFY);
313 pw->p_exit = WEXITSTATUS(wstat);
316 pw->p_flag &= ~P_NOTIFY;
320 jp->exitval = pw->p_exit;
321 if(pw->p_flag&P_SIGNALLED)
322 jp->exitval |= SH_EXITSIG;
325 sfprintf(sfstderr,"%ld: job %d with pid %ld flags=%o complete with status=%x exit=%d\n",(long)getpid(),pw->p_job,(long)pid,pw->p_flag,wstat,pw->p_exit);
329 if(sh.st.trapcom[SIGCHLD])
331 sh.sigflag[SIGCHLD] |= SH_SIGTRAP;
332 sh.trapnote |= SH_SIGTRAP;
334 if(sh_isoption(SH_NOTIFY) && sh_isstate(SH_TTYWAIT))
337 job_list(pw,JOB_NFLAG|JOB_NLFLAG);
342 signal(sig, job_waitsafe);
346 * initialize job control if possible
347 * if lflag is set the switching driver message will not print
349 void job_init __PARAM__((int lflag), (lflag)) __OTORP__(int lflag;){
353 signal(SIGCHLD,job_waitsafe);
354 # if defined(SIGCLD) && (SIGCLD!=SIGCHLD)
355 signal(SIGCLD,job_waitsafe);
357 if(!sh_isoption(SH_INTERACTIVE))
359 /* use new line discipline when available */
362 if((job.linedisc = ioctl(JOBTTY, FIOLOOKLD, 0)) <0)
364 if(ioctl(JOBTTY,TIOCGETD,&job.linedisc) !=0)
365 # endif /* FIOLOOKLD */
367 if(job.linedisc!=NTTYDISC && job.linedisc!=OTTYDISC)
369 /* no job control when running with MPX */
371 sh_onoption(SH_VIRAW);
372 # endif /* SHOPT_VSH */
375 if(job.linedisc==NTTYDISC)
377 #endif /* NTTYDISC */
379 job.mypgid = getpgrp();
380 /* some systems have job control, but not initialized */
383 /* Get a controlling terminal and set process group */
384 /* This should have already been done by rlogin */
386 register char *ttynam;
390 if(job.mypgid<0 || !(ttynam=ttyname(JOBTTY)))
393 if((fd = open(ttynam,O_RDWR)) <0)
396 sh_iorenumber(fd,JOBTTY);
399 tcsetpgrp(JOBTTY,sh.pid);
404 if(possible = (setpgid(0,job.mypgid)>=0) || errno==EPERM)
406 /* wait until we are in the foreground */
407 while((job.mytgid=tcgetpgrp(JOBTTY)) != job.mypgid)
411 /* Stop this shell until continued */
412 signal(SIGTTIN,SIG_DFL);
413 kill(sh.pid,SIGTTIN);
414 /* resumes here after continue tries again */
415 if(ntry++ > IOMAXTRY)
425 /* set the line discipline */
428 int linedisc = NTTYDISC;
430 tty_get(JOBTTY,&my_stty);
431 if (ioctl(JOBTTY, FIOPOPLD, 0) < 0)
433 if (ioctl(JOBTTY, FIOPUSHLD, &linedisc) < 0)
435 ioctl(JOBTTY, FIOPUSHLD, &job.linedisc);
438 tty_set(JOBTTY,TCSANOW,&my_stty);
440 if(ioctl(JOBTTY,TIOCSETD,&linedisc) !=0)
442 # endif /* FIOPUSHLD */
448 #endif /* NTTYDISC */
453 /* make sure that we are a process group leader */
455 # if defined(SA_NOCLDWAIT) && defined(_lib_sigflag)
456 sigflag(SIGCHLD, SA_NOCLDSTOP|SA_NOCLDWAIT, 0);
457 # endif /* SA_NOCLDWAIT */
458 signal(SIGTTIN,SIG_IGN);
459 signal(SIGTTOU,SIG_IGN);
460 /* The shell now handles ^Z */
461 signal(SIGTSTP,sh_fault);
462 tcsetpgrp(JOBTTY,sh.pid);
464 /* set the switch character */
465 tty_get(JOBTTY,&my_stty);
466 job.suspend = (unsigned)my_stty.c_cc[VSUSP];
467 if(job.suspend == (unsigned char)CNSUSP)
469 my_stty.c_cc[VSUSP] = CSWTCH;
470 tty_set(JOBTTY,TCSAFLUSH,&my_stty);
473 sh_onoption(SH_MONITOR);
481 * see if there are any stopped jobs
482 * restore tty driver and pgrp
484 int job_close __PARAM__((void), ()){
485 register struct process *pw = job.pwlist;
486 register int count = 0, running = 0;
487 if(possible && !job.jobcontrol)
489 else if(!possible && (!sh_isstate(SH_MONITOR) || sh_isstate(SH_FORKED)))
493 for(;pw;pw=pw->p_nxtjob)
495 if(!(pw->p_flag&P_STOPPED))
497 if(!(pw->p_flag&P_DONE))
502 killpg(pw->p_pgrp,SIGTERM);
505 if(beenhere++ == 0 && job.pwlist)
509 error(0,e_terminate);
512 else if(running && sh.login_sh)
514 error(0,e_jobsrunning);
519 if(possible && setpgid(0,job.mypgid)>=0)
520 tcsetpgrp(job.fd,job.mypgid);
521 # endif /* SIGTSTP */
525 /* restore old line discipline */
527 tty_get(job.fd,&my_stty);
528 if (ioctl(job.fd, FIOPOPLD, 0) < 0)
530 if (ioctl(job.fd, FIOPUSHLD, &job.linedisc) < 0)
532 job.linedisc = NTTYDISC;
533 ioctl(job.fd, FIOPUSHLD, &job.linedisc);
536 tty_set(job.fd,TCSAFLUSH,&my_stty);
538 if(ioctl(job.fd,TIOCSETD,&job.linedisc) !=0)
540 # endif /* FIOPUSHLD */
543 # endif /* NTTYDISC */
545 if(possible && job.suspend==CNSUSP)
547 tty_get(job.fd,&my_stty);
548 my_stty.c_cc[VSUSP] = CNSUSP;
549 tty_set(job.fd,TCSAFLUSH,&my_stty);
556 static void job_set __PARAM__((register struct process *pw), (pw)) __OTORP__(register struct process *pw;){
557 /* save current terminal state */
558 tty_get(job.fd,&my_stty);
559 if(pw->p_flag&P_STTY)
561 /* restore terminal state for job */
562 tty_set(job.fd,TCSAFLUSH,&pw->p_stty);
565 tcsetpgrp(job.fd,pw->p_fgrp);
566 /* if job is stopped, resume it in the background */
571 static void job_reset __PARAM__((register struct process *pw), (pw)) __OTORP__(register struct process *pw;){
572 /* save the terminal state for current job */
574 job_fgrp(pw,tcgetpgrp(job.fd));
575 if(tcsetpgrp(job.fd,sh.pid) !=0)
578 /* force the following tty_get() to do a tcgetattr() */
579 tty_set(-1, 0, NIL(struct termios*));
580 if(pw && (pw->p_flag&P_SIGNALLED) && pw->p_exit!=SIGHUP)
582 if(tty_get(job.fd,&pw->p_stty) == 0)
583 pw->p_flag |= P_STTY;
584 /* restore terminal state for job */
585 tty_set(job.fd,TCSAFLUSH,&my_stty);
592 * wait built-in command
595 void job_bwait __PARAM__((char **jobs), (jobs)) __OTORP__(char **jobs;){
597 register struct process *pw;
601 else while(job = *jobs++)
606 if(pw = job_bystring(job))
620 * execute function <fun> for each job
623 int job_walk __PARAM__((Sfio_t *file,int (*fun)(struct process*,int),int arg,char *joblist[]), (file, fun, arg, joblist)) __OTORP__(Sfio_t *file;int (*fun)();int arg;char *joblist[];){
624 register struct process *pw = job.pwlist;
626 register char *jobid, **jobs=joblist;
627 register struct process *px;
641 else if(*jobs==0) /* current job */
643 /* skip over non-stop jobs */
644 while(pw && pw->p_pgrp==0)
649 else while(jobid = *jobs++)
653 error(ERROR_exit(1),e_jobusage,job_string);
655 pw = job_bystring(jobid);
658 int pid = atoi(jobid);
661 while(isdigit(*jobid))
664 error(ERROR_exit(1),e_jobusage,job_string);
665 if(!(pw = job_bypid(pid)))
681 * send signal <sig> to background process group if not disowned
683 int job_terminate __PARAM__((register struct process *pw,register int sig), (pw, sig)) __OTORP__(register struct process *pw;register int sig;){
684 if(pw->p_pgrp && !(pw->p_flag&P_DISOWN))
691 * flag JOB_LFLAG for long listing
692 * flag JOB_NFLAG for list only jobs marked for notification
693 * flag JOB_PFLAG for process id(s) only
696 int job_list __PARAM__((struct process *pw,register int flag), (pw, flag)) __OTORP__(struct process *pw;register int flag;){
697 register struct process *px = pw;
699 register const char *msg;
701 if(!pw || pw->p_job<=0)
703 if(pw->p_env != sh.jobenv)
705 if((flag&JOB_NFLAG) && (!(px->p_flag&P_NOTIFY)||px->p_pgrp==0))
709 sfprintf(outfile,"%ld\n",(long)px->p_pgrp);
712 if((px->p_flag&P_DONE) && job.waitall && !(flag&JOB_LFLAG))
717 else if(px==job.pwlist->p_nxtjob)
722 sfputc(outfile,'\n');
723 sfprintf(outfile,"[%d] %c ",n, msize);
728 sfprintf(outfile,"%ld\t",(long)px->p_pid);
729 if(px->p_flag&P_SIGNALLED)
730 msg = job_sigmsg((int)(px->p_exit));
731 else if(px->p_flag&P_NOTIFY)
738 px->p_flag &= ~P_NOTIFY;
739 msg = ERROR_translate(msg,1);
740 sfputr(outfile,msg,-1);
744 sfprintf(outfile,"(%d)",(int)n);
745 msize += (3+(n>10)+(n>100));
747 if(px->p_flag&P_COREDUMP)
749 msg = ERROR_translate(e_coredump,1);
750 sfputr(outfile, msg, -1);
751 msize += strlen(msg);
753 sfnputc(outfile,' ',MAXMSG>msize?MAXMSG-msize:1);
759 hist_list(sh.hist_ptr,outfile,pw->p_name,0,";");
761 sfputr(outfile, e_nlspace, -1);
768 * get the process group given the job number
769 * This routine returns the process group number or -1
771 static struct process *job_bystring __PARAM__((register char *ajob), (ajob)) __OTORP__(register char *ajob;){
772 register struct process *pw=job.pwlist;
774 if(*ajob++ != '%' || !pw)
775 return(NIL(struct process*));
778 pw = job_byjid(atoi(ajob));
779 else if(c=='+' || c=='%')
784 pw = job.pwlist->p_nxtjob;
787 pw = job_byname(ajob);
790 return(NIL(struct process*));
794 * Kill a job or process
797 int job_kill __PARAM__((register struct process *pw,register int sig), (pw, sig)) __OTORP__(register struct process *pw;register int sig;){
802 int stopsig = (sig==SIGSTOP||sig==SIGTSTP||sig==SIGTTIN||sig==SIGTTOU);
812 if(pid==0 && job.jobcontrol)
813 r = job_walk(outfile, job_kill,sig, (char**)0);
815 if(sig==SIGSTOP && pid==sh.pid && sh.ppid==1)
817 /* can't stop login shell */
825 if((r = kill(pid,sig))>=0 && !stopsig)
827 if(pw->p_flag&P_STOPPED)
828 pw->p_flag &= ~(P_STOPPED|P_SIGNALLED);
834 if((r = killpg(-pid,sig))>=0 && !stopsig)
836 job_unstop(job_bypid(pw->p_pid));
837 killpg(-pid,SIGCONT);
845 r = killpg(-pid,sig);
852 if((r = killpg(pid,sig))>=0 && (sig==SIGHUP||sig==SIGTERM))
857 while(pw && pw->p_pgrp==0 && (r=kill(pw->p_pid,sig))>=0)
860 if(sig==SIGHUP || sig==SIGTERM)
861 kill(pw->p_pid,SIGCONT);
866 if(r<0 && job_string)
875 sfprintf(sfstderr,"kill: %s: %s\n",job_string, ERROR_translate(msg,1));
882 * Get process structure from first letters of jobname
886 static struct process *job_byname __PARAM__((char *name), (name)) __OTORP__(char *name;){
887 register struct process *pw = job.pwlist;
888 register struct process *pz = 0;
889 register int *flag = 0;
890 register char *cp = name;
893 return(NIL(struct process*));
896 for(;pw;pw=pw->p_nxtjob)
898 if(hist_match(sh.hist_ptr,pw->p_name,cp,flag)>=0)
901 error(ERROR_exit(1),e_jobusage,name-1);
910 # define job_reset(x)
916 * Initialize the process posting array
919 void job_clear __PARAM__((void), ()){
920 register struct process *pw, *px;
921 register struct process *pwnext;
922 register int j = BYTE(sh.lim.child_max);
923 register struct jobsave *jp;
924 for(pw=job.pwlist; pw; pw=pwnext)
926 pwnext = pw->p_nxtjob;
933 for(jp=bck_list; jp;)
935 px = (struct process*)jp;
940 job.pwlist = NIL(struct process*);
946 job.freejobs = (unsigned char*)malloc((unsigned)(j+1));
948 job.freejobs[j--] = 0;
952 * put the process <pid> on the process list and return the job number
953 * if non-zero, <join> is the process id of the job to join
956 int job_post __PARAM__((pid_t pid, pid_t join), (pid, join)) __OTORP__(pid_t pid; pid_t join;){
957 register struct process *pw;
958 register History_t *hp = sh.hist_ptr;
959 sh.jobenv = sh.curenv;
965 if(join && (pw=job_bypid(join)))
967 /* if job to join is not first move it to front */
968 if((pw=job_byjid(pw->p_job)) != job.pwlist)
971 pw->p_nxtjob = job.pwlist;
976 freelist = pw->p_nxtjob;
978 pw = new_of(struct process,0);
980 if(join && job.pwlist)
982 /* join existing current job */
983 pw->p_nxtjob = job.pwlist->p_nxtjob;
984 pw->p_nxtproc = job.pwlist;
985 pw->p_job = job.pwlist->p_job;
989 /* create a new job */
990 pw->p_nxtjob = job.pwlist;
991 while((pw->p_job = job_alloc()) < 0)
996 pw->p_env = sh.curenv;
998 pw->p_flag = P_EXITSAVE;
999 if(sh_isstate(SH_MONITOR))
1000 pw->p_fgrp = job.curpgid;
1003 pw->p_pgrp = pw->p_fgrp;
1005 sfprintf(sfstderr,"%ld: posting %d pid=%ld pgid=%ld savesig=%d join=%ld\n",
1006 (long)getpid(),pw->p_job,(long)pw->p_pid,(long)pw->p_pgrp,savesig,(long)join);
1010 if(hp && !sh_isstate(SH_PROFILE))
1011 pw->p_name=hist_tell(sh.hist_ptr,(int)hp->histind-1);
1017 job_waitsafe(savesig);
1022 * Returns a process structure give a process id
1025 static struct process *job_bypid __PARAM__((pid_t pid), (pid)) __OTORP__(pid_t pid;){
1026 register struct process *pw, *px;
1027 for(pw=job.pwlist; pw; pw=pw->p_nxtjob)
1028 for(px=pw; px; px=px->p_nxtproc)
1033 return(NIL(struct process*));
1037 * return a pointer to a job given the job id
1040 static struct process *job_byjid __PARAM__((int jobid), (jobid)) __OTORP__(int jobid;){
1041 register struct process *pw;
1042 for(pw=job.pwlist;pw; pw = pw->p_nxtjob)
1044 if(pw->p_job==jobid)
1051 * print a signal message
1053 static void job_prmsg __PARAM__((register struct process *pw), (pw)) __OTORP__(register struct process *pw;){
1054 if(pw->p_exit!=SIGINT && pw->p_exit!=SIGPIPE)
1056 register const char *msg, *dump;
1057 msg = job_sigmsg((int)(pw->p_exit));
1058 msg = ERROR_translate(msg,1);
1059 if(pw->p_flag&P_COREDUMP)
1060 dump = ERROR_translate(e_coredump,1);
1063 if(sh_isstate(SH_INTERACTIVE))
1064 sfprintf(sfstderr,"%s%s\n",msg,dump);
1066 error(2,"%d: %s%s",pw->p_pid,msg,dump);
1071 * Wait for process pid to complete
1072 * If pid < -1, then wait can be interrupted, -pid is waited for (wait builtin)
1073 * pid=0 to unpost all done processes
1074 * pid=1 to wait for at least one process to complete
1075 * pid=-1 to wait for all runing processes
1078 void job_wait __PARAM__((register pid_t pid), (pid)) __OTORP__(register pid_t pid;){
1079 register struct process *pw=0,*px;
1080 register int jobid = 0;
1089 job.in_critical = 1;
1092 if(!(pw=job_bypid(pid)))
1094 /* check to see whether job status has been saved */
1095 if((sh.exitval = job_chksave(pid)) < 0)
1096 sh.exitval = ERROR_NOENT;
1098 job.in_critical = 0;
1100 job_waitsafe(savesig);
1103 else if(intr && pw->p_env!=sh.curenv)
1105 sh.exitval = ERROR_NOENT;
1110 pw->p_flag &= ~P_EXITSAVE;
1111 if(pw->p_pgrp && job.parent!= (pid_t)-1)
1112 job_set(job_byjid(jobid));
1115 sfprintf(sfstderr,"%ld: job_wait job=%d pid=%ld\n",(long)getpid(),jobid,(long)pid);
1117 sfprintf(sfstderr,"%ld: job_wait flags=%o\n",(long)getpid(),pw->p_flag);
1121 job.in_critical = 1;
1124 for(px=job.pwlist;px; px = px->p_nxtjob)
1126 if(px!=pw && (px->p_flag&P_NOTIFY))
1128 if(sh_isoption(SH_NOTIFY))
1131 job_list(px,JOB_NFLAG|JOB_NLFLAG);
1134 else if(!sh_isoption(SH_INTERACTIVE) && (px->p_flag&P_SIGNALLED))
1137 px->p_flag &= ~P_NOTIFY;
1142 if(pw && (pw->p_flag&(P_DONE|P_STOPPED)))
1145 if(pw->p_flag&P_STOPPED)
1147 pw->p_flag |= P_EXITSAVE;
1148 if(sh_isoption(SH_INTERACTIVE) && !sh_isstate(SH_FORKED))
1150 if( pw->p_exit!=SIGTTIN && pw->p_exit!=SIGTTOU)
1153 killpg(pw->p_pgrp,SIGCONT);
1155 else /* ignore stop when non-interactive */
1156 pw->p_flag &= ~(P_NOTIFY|P_SIGNALLED|P_STOPPED|P_EXITSAVE);
1159 #endif /* SIGTSTP */
1161 if(pw->p_flag&P_SIGNALLED)
1163 pw->p_flag &= ~P_NOTIFY;
1166 else if(pw->p_flag&P_DONE)
1167 pw->p_flag &= ~P_NOTIFY;
1168 if(pw == job_byjid(jobid))
1170 /* last process in job */
1171 sh.exitval = pw->p_exit;
1172 if(pw->p_flag&P_SIGNALLED)
1173 sh.exitval |= SH_EXITSIG;
1175 pw->p_flag &= ~P_EXITSAVE;
1177 if(!(px=job_unpost(pw,1)) || !job.waitall)
1184 job.in_critical = !savesig;
1186 job_waitsafe(savesig);
1191 if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
1193 if((intr && sh.trapnote) || (pid==1 && !intr))
1196 job.in_critical = 0;
1198 job_waitsafe(savesig);
1205 /* propogate keyboard interrupts to parent */
1206 if((pw->p_flag&P_SIGNALLED) && pw->p_exit==SIGINT && !(sh.sigflag[SIGINT]&SH_SIGOFF))
1209 else if((pw->p_flag&P_STOPPED) && pw->p_exit==SIGTSTP)
1214 #endif /* SIGTSTP */
1219 for(pw=job.pwlist; pw; pw=px)
1228 * move job to foreground if bgflag == 'f'
1229 * move job to background if bgflag == 'b'
1230 * disown job if bgflag == 'd'
1233 job_switch __PARAM__((register struct process *pw,int bgflag), (pw, bgflag)) __OTORP__(register struct process *pw;int bgflag;){
1234 register const char *msg;
1235 if(!pw || !(pw=job_byjid((int)pw->p_job)))
1239 for(; pw; pw=pw->p_nxtproc)
1240 pw->p_flag |= P_DISOWN;
1246 sfprintf(outfile,"[%d]\t",(int)pw->p_job);
1252 pw->p_nxtjob = job.pwlist;
1256 hist_list(sh.hist_ptr,outfile,pw->p_name,'&',";");
1257 sfputr(outfile,msg,'\n');
1261 if(!(pw=job_unpost(pw,1)))
1264 job_wait(pw->p_pid);
1267 else if(pw->p_flag&P_STOPPED)
1269 #endif /* SIGTSTP */
1276 * Set the foreground group associated with a job
1279 static void job_fgrp __PARAM__((register struct process *pw, int newgrp), (pw, newgrp)) __OTORP__(register struct process *pw; int newgrp;){
1280 for(; pw; pw=pw->p_nxtproc)
1281 pw->p_fgrp = newgrp;
1285 * turn off STOP state of a process group and send CONT signals
1288 static void job_unstop __PARAM__((register struct process *px), (px)) __OTORP__(register struct process *px;){
1289 register struct process *pw;
1290 register int num = 0;
1291 for(pw=px ;pw ;pw=pw->p_nxtproc)
1293 if(pw->p_flag&P_STOPPED)
1296 pw->p_flag &= ~(P_STOPPED|P_SIGNALLED|P_NOTIFY);
1301 if(px->p_fgrp != px->p_pgrp)
1302 killpg(px->p_fgrp,SIGCONT);
1303 killpg(px->p_pgrp,SIGCONT);
1306 #endif /* SIGTSTP */
1309 * remove a job from table
1310 * If all the processes have not completed, unpost first non-completed process
1311 * Otherwise the job is removed and job_unpost returns NULL.
1312 * pwlist is reset if the first job is removed
1313 * if <notify> is non-zero, then jobs with pending notifications are unposted
1316 static struct process *job_unpost __PARAM__((register struct process *pwtop,int notify), (pwtop, notify)) __OTORP__(register struct process *pwtop;int notify;){
1317 register struct process *pw;
1318 /* make sure all processes are done */
1320 sfprintf(sfstderr,"%ld: unpost pid=%ld\n",(long)getpid(),(long)pwtop->p_pid);
1323 pwtop = pw = job_byjid((int)pwtop->p_job);
1324 for(; pw && (pw->p_flag&P_DONE)&&(notify||!(pw->p_flag&P_NOTIFY)); pw=pw->p_nxtproc);
1327 /* all processes complete, unpost job */
1329 for(pw=pwtop; pw; pw=pw->p_nxtproc)
1331 /* save the exit status for background jobs */
1332 if(pw->p_flag&P_EXITSAVE)
1335 /* save status for future wait */
1336 if(bck_count++ > sh.lim.child_max)
1338 jp = new_of(struct jobsave,0);
1339 jp->next = bck_list;
1341 jp->pid = pw->p_pid;
1342 jp->env = sh.curenv;
1343 jp->exitval = pw->p_exit;
1344 if(pw->p_flag&P_SIGNALLED)
1345 jp->exitval |= SH_EXITSIG;
1346 pw->p_flag &= ~P_EXITSAVE;
1348 pw->p_flag &= ~P_DONE;
1350 pw->p_nxtjob = freelist;
1354 sfprintf(sfstderr,"%ld: free job=%d\n",(long)getpid(),pwtop->p_job);
1357 job_free((int)pwtop->p_job);
1358 return((struct process*)0);
1362 * unlink a job form the job list
1364 static void job_unlink __PARAM__((register struct process *pw), (pw)) __OTORP__(register struct process *pw;){
1365 register struct process *px;
1368 job.pwlist = pw->p_nxtjob;
1372 for(px=job.pwlist;px;px=px->p_nxtjob)
1373 if(px->p_nxtjob == pw)
1375 px->p_nxtjob = pw->p_nxtjob;
1381 * get an unused job number
1382 * freejobs is a bit vector, 0 is unused
1385 static int job_alloc __PARAM__((void), ()){
1387 register unsigned mask = 1;
1388 register unsigned char *freeword;
1389 register int jmax = BYTE(sh.lim.child_max);
1390 /* skip to first word with a free slot */
1391 for(j=0;job.freejobs[j] == UCHAR_MAX; j++);
1394 register struct process *pw;
1395 for(j=1; j < sh.lim.child_max; j++)
1397 if((pw=job_byjid(j))&& !job_unpost(pw,0))
1404 freeword = &job.freejobs[j];
1406 for(j++;mask&(*freeword);j++,mask <<=1);
1412 * return a job number
1415 static void job_free __PARAM__((register int n), (n)) __OTORP__(register int n;){
1416 register int j = (--n)/CHAR_BIT;
1417 register unsigned mask;
1420 job.freejobs[j] &= ~mask;
1423 static char *job_sigmsg __PARAM__((int sig), (sig)) __OTORP__(int sig;){
1424 static char signo[] = "Signal xxxx";
1427 * This code handles the formatting for the apollo specific signal
1430 extern __MANGLE__ char *apollo_error __PROTO__((void));
1432 if ( sig == SIGAPOLLO )
1433 return( apollo_error() );
1435 if(sig<sh.sigmax && sh.sigmsg[sig])
1436 return(sh.sigmsg[sig]);
1437 #if defined(SIGRTMIN) && defined(SIGRTMAX)
1438 if(sig>=SIGRTMIN && sig<=SIGRTMAX)
1440 static char sigrt[20];
1441 sfsprintf(sigrt,sizeof(sigrt),"SIGRTMIN+%d",sig-SIGRTMIN);
1445 strncpy(signo+7,fmtbase((long)sig,10,0),4);
1450 * see whether exit status has been saved and delete it
1451 * if pid==0, then oldest saved process is deleted
1452 * If pid is not found a -1 is returned.
1454 int job_chksave __PARAM__((register pid_t pid), (pid)) __OTORP__(register pid_t pid;){
1455 register struct jobsave *jp = bck_list, *jpold=0;
1461 if(pid==0 && !jp->next)
1471 if(jp->env!=sh.curenv)
1476 jpold->next = jp->next;
1478 bck_list = jp->next;