xref: /original-bsd/bin/csh/proc.c (revision d6fabe6e)
1 /*-
2  * Copyright (c) 1980, 1991 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)proc.c	5.15 (Berkeley) 04/04/91";
10 #endif /* not lint */
11 
12 #include "sh.h"
13 #include "sh.dir.h"
14 #include "sh.proc.h"
15 #include <string.h>
16 #include <sys/wait.h>
17 #include <sys/ioctl.h>
18 
19 /*
20  * C Shell - functions that manage processes, handling hanging, termination
21  */
22 
23 #define BIGINDEX	9	/* largest desirable job index */
24 
25 /*
26  * pchild - called at interrupt level by the SIGCHLD signal
27  *	indicating that at least one child has terminated or stopped
28  *	thus at least one wait system call will definitely return a
29  *	childs status.  Top level routines (like pwait) must be sure
30  *	to mask interrupts when playing with the proclist data structures!
31  */
32 void
33 pchild()
34 {
35 	register struct process *pp;
36 	register struct process	*fp;
37 	register int pid;
38 	union wait w;
39 	int jobflags;
40 	struct rusage ru;
41 	extern int insource;
42 
43 loop:
44 	pid = wait3((int *)&w,
45 	    (setintr && (intty || insource) ? WNOHANG|WUNTRACED:WNOHANG), &ru);
46 	if (pid <= 0) {
47 		if (errno == EINTR) {
48 			errno = 0;
49 			goto loop;
50 		}
51 		pnoprocesses = pid == -1;
52 		return;
53 	}
54 	for (pp = proclist.p_next; pp != PNULL; pp = pp->p_next)
55 		if (pid == pp->p_pid)
56 			goto found;
57 	goto loop;
58 found:
59 	if (pid == atoi(value("child")))
60 		unsetv("child");
61 	pp->p_flags &= ~(PRUNNING|PSTOPPED|PREPORTED);
62 	if (WIFSTOPPED(w)) {
63 		pp->p_flags |= PSTOPPED;
64 		pp->p_reason = w.w_stopsig;
65 	} else {
66 		if (pp->p_flags & (PTIME|PPTIME) || adrof("time"))
67 			(void) gettimeofday(&pp->p_etime, (struct timezone *)0);
68 		pp->p_rusage = ru;
69 		if (WIFSIGNALED(w)) {
70 			if (w.w_termsig == SIGINT)
71 				pp->p_flags |= PINTERRUPTED;
72 			else
73 				pp->p_flags |= PSIGNALED;
74 			if (w.w_coredump)
75 				pp->p_flags |= PDUMPED;
76 			pp->p_reason = w.w_termsig;
77 		} else {
78 			pp->p_reason = w.w_retcode;
79 			if (pp->p_reason != 0)
80 				pp->p_flags |= PAEXITED;
81 			else
82 				pp->p_flags |= PNEXITED;
83 		}
84 	}
85 	jobflags = 0;
86 	fp = pp;
87 	do {
88 		if ((fp->p_flags & (PPTIME|PRUNNING|PSTOPPED)) == 0 &&
89 		    !child && adrof("time") &&
90 		    fp->p_rusage.ru_utime.tv_sec+fp->p_rusage.ru_stime.tv_sec >=
91 		     atoi(value("time")))
92 			fp->p_flags |= PTIME;
93 		jobflags |= fp->p_flags;
94 	} while ((fp = fp->p_friends) != pp);
95 	pp->p_flags &= ~PFOREGND;
96 	if (pp == pp->p_friends && (pp->p_flags & PPTIME)) {
97 		pp->p_flags &= ~PPTIME;
98 		pp->p_flags |= PTIME;
99 	}
100 	if ((jobflags & (PRUNNING|PREPORTED)) == 0) {
101 		fp = pp;
102 		do {
103 			if (fp->p_flags&PSTOPPED)
104 				fp->p_flags |= PREPORTED;
105 		} while((fp = fp->p_friends) != pp);
106 		while(fp->p_pid != fp->p_jobid)
107 			fp = fp->p_friends;
108 		if (jobflags&PSTOPPED) {
109 			if (pcurrent && pcurrent != fp)
110 				pprevious = pcurrent;
111 			pcurrent = fp;
112 		} else
113 			pclrcurr(fp);
114 		if (jobflags&PFOREGND) {
115 			if (jobflags & (PSIGNALED|PSTOPPED|PPTIME) ||
116 			    !eq(dcwd->di_name, fp->p_cwd->di_name)) {
117 				;	/* print in pjwait */
118 			}
119 /*
120 		else if ((jobflags & (PTIME|PSTOPPED)) == PTIME)
121 				ptprint(fp);
122 */
123 		} else {
124 			if (jobflags&PNOTIFY || adrof("notify")) {
125 				printf("\215\n");
126 				(void) pprint(pp, NUMBER|NAME|REASON);
127 				if ((jobflags&PSTOPPED) == 0)
128 					pflush(pp);
129 			} else {
130 				fp->p_flags |= PNEEDNOTE;
131 				neednote++;
132 			}
133 		}
134 	}
135 	goto loop;
136 }
137 
138 pnote()
139 {
140 	register struct process *pp;
141 	int flags;
142 	long omask;
143 
144 	neednote = 0;
145 	for (pp = proclist.p_next; pp != PNULL; pp = pp->p_next) {
146 		if (pp->p_flags & PNEEDNOTE) {
147 			omask = sigblock(sigmask(SIGCHLD));
148 			pp->p_flags &= ~PNEEDNOTE;
149 			flags = pprint(pp, NUMBER|NAME|REASON);
150 			if ((flags&(PRUNNING|PSTOPPED)) == 0)
151 				pflush(pp);
152 			(void) sigsetmask(omask);
153 		}
154 	}
155 }
156 
157 /*
158  * pwait - wait for current job to terminate, maintaining integrity
159  *	of current and previous job indicators.
160  */
161 pwait()
162 {
163 	register struct process *fp, *pp;
164 	long omask;
165 
166 	/*
167 	 * Here's where dead procs get flushed.
168 	 */
169 	omask = sigblock(sigmask(SIGCHLD));
170 	for (pp = (fp = &proclist)->p_next; pp != PNULL; pp = (fp = pp)->p_next)
171 		if (pp->p_pid == 0) {
172 			fp->p_next = pp->p_next;
173 			xfree(pp->p_command);
174 			if (pp->p_cwd && --pp->p_cwd->di_count == 0)
175 				if (pp->p_cwd->di_next == 0)
176 					dfree(pp->p_cwd);
177 			xfree((char *)pp);
178 			pp = fp;
179 		}
180 	(void) sigsetmask(omask);
181 	pjwait(pcurrjob);
182 }
183 
184 /*
185  * pjwait - wait for a job to finish or become stopped
186  *	It is assumed to be in the foreground state (PFOREGND)
187  */
188 pjwait(pp)
189 	register struct process *pp;
190 {
191 	register struct process *fp;
192 	int jobflags, reason;
193 	long omask;
194 
195 	while (pp->p_pid != pp->p_jobid)
196 		pp = pp->p_friends;
197 	fp = pp;
198 	do {
199 		if ((fp->p_flags&(PFOREGND|PRUNNING)) == PRUNNING)
200 			printf("BUG: waiting for background job!\n");
201 	} while ((fp = fp->p_friends) != pp);
202 	/*
203 	 * Now keep pausing as long as we are not interrupted (SIGINT),
204 	 * and the target process, or any of its friends, are running
205 	 */
206 	fp = pp;
207 	omask = sigblock(sigmask(SIGCHLD));
208 	for (;;) {
209 		jobflags = 0;
210 		do
211 			jobflags |= fp->p_flags;
212 		while ((fp = (fp->p_friends)) != pp);
213 		if ((jobflags & PRUNNING) == 0)
214 			break;
215 		sigpause(sigblock(0L) &~ sigmask(SIGCHLD));
216 	}
217 	(void) sigsetmask(omask);
218 	if (tpgrp > 0)			/* get tty back */
219 		(void) ioctl(FSHTTY, TIOCSPGRP, (char *)&tpgrp);
220 	if ((jobflags&(PSIGNALED|PSTOPPED|PTIME)) ||
221 	     !eq(dcwd->di_name, fp->p_cwd->di_name)) {
222 		if (jobflags&PSTOPPED)
223 			printf("\n");
224 		(void) pprint(pp, AREASON|SHELLDIR);
225 	}
226 	if ((jobflags&(PINTERRUPTED|PSTOPPED)) && setintr &&
227 	    (!gointr || !eq(gointr, "-"))) {
228 		if ((jobflags & PSTOPPED) == 0)
229 			pflush(pp);
230 		pintr1(0);
231 		/*NOTREACHED*/
232 	}
233 	reason = 0;
234 	fp = pp;
235 	do {
236 		if (fp->p_reason)
237 			reason = fp->p_flags & (PSIGNALED|PINTERRUPTED) ?
238 				fp->p_reason | QUOTE : fp->p_reason;
239 	} while ((fp = fp->p_friends) != pp);
240 	set("status", putn(reason));
241 	if (reason && exiterr)
242 		exitstat();
243 	pflush(pp);
244 }
245 
246 /*
247  * dowait - wait for all processes to finish
248  */
249 dowait()
250 {
251 	register struct process *pp;
252 	long omask;
253 
254 	pjobs++;
255 	omask = sigblock(sigmask(SIGCHLD));
256 loop:
257 	for (pp = proclist.p_next; pp; pp = pp->p_next)
258 		if (pp->p_pid && /* pp->p_pid == pp->p_jobid && */
259 		    pp->p_flags&PRUNNING) {
260 			sigpause(0L);
261 			goto loop;
262 		}
263 	(void) sigsetmask(omask);
264 	pjobs = 0;
265 }
266 
267 /*
268  * pflushall - flush all jobs from list (e.g. at fork())
269  */
270 pflushall()
271 {
272 	register struct process	*pp;
273 
274 	for (pp = proclist.p_next; pp != PNULL; pp = pp->p_next)
275 		if (pp->p_pid)
276 			pflush(pp);
277 }
278 
279 /*
280  * pflush - flag all process structures in the same job as the
281  *	the argument process for deletion.  The actual free of the
282  *	space is not done here since pflush is called at interrupt level.
283  */
284 pflush(pp)
285 	register struct process	*pp;
286 {
287 	register struct process *np;
288 	register int index;
289 
290 	if (pp->p_pid == 0) {
291 		printf("BUG: process flushed twice");
292 		return;
293 	}
294 	while (pp->p_pid != pp->p_jobid)
295 		pp = pp->p_friends;
296 	pclrcurr(pp);
297 	if (pp == pcurrjob)
298 		pcurrjob = 0;
299 	index = pp->p_index;
300 	np = pp;
301 	do {
302 		np->p_index = np->p_pid = 0;
303 		np->p_flags &= ~PNEEDNOTE;
304 	} while ((np = np->p_friends) != pp);
305 	if (index == pmaxindex) {
306 		for (np = proclist.p_next, index = 0; np; np = np->p_next)
307 			if (np->p_index > index)
308 				index = np->p_index;
309 		pmaxindex = index;
310 	}
311 }
312 
313 /*
314  * pclrcurr - make sure the given job is not the current or previous job;
315  *	pp MUST be the job leader
316  */
317 pclrcurr(pp)
318 	register struct process *pp;
319 {
320 
321 	if (pp == pcurrent)
322 		if (pprevious != PNULL) {
323 			pcurrent = pprevious;
324 			pprevious = pgetcurr(pp);
325 		} else {
326 			pcurrent = pgetcurr(pp);
327 			pprevious = pgetcurr(pp);
328 		}
329 	else if (pp == pprevious)
330 		pprevious = pgetcurr(pp);
331 }
332 
333 /* +4 here is 1 for '\0', 1 ea for << >& >> */
334 char	command[PMAXLEN+4];
335 int	cmdlen;
336 char	*cmdp;
337 /*
338  * palloc - allocate a process structure and fill it up.
339  *	an important assumption is made that the process is running.
340  */
341 palloc(pid, t)
342 	int pid;
343 	register struct command *t;
344 {
345 	register struct process	*pp;
346 	int i;
347 
348 	pp = (struct process *)calloc(1, sizeof(struct process));
349 	pp->p_pid = pid;
350 	pp->p_flags = t->t_dflg & F_AMPERSAND ? PRUNNING : PRUNNING|PFOREGND;
351 	if (t->t_dflg & F_TIME)
352 		pp->p_flags |= PPTIME;
353 	cmdp = command;
354 	cmdlen = 0;
355 	padd(t);
356 	*cmdp++ = 0;
357 	if (t->t_dflg & F_PIPEOUT) {
358 		pp->p_flags |= PPOU;
359 		if (t->t_dflg & F_STDERR)
360 			pp->p_flags |= PDIAG;
361 	}
362 	pp->p_command = savestr(command);
363 	if (pcurrjob) {
364 		struct process *fp;
365 		/* careful here with interrupt level */
366 		pp->p_cwd = 0;
367 		pp->p_index = pcurrjob->p_index;
368 		pp->p_friends = pcurrjob;
369 		pp->p_jobid = pcurrjob->p_pid;
370 		for (fp = pcurrjob; fp->p_friends != pcurrjob; fp = fp->p_friends)
371 			;
372 		fp->p_friends = pp;
373 	} else {
374 		pcurrjob = pp;
375 		pp->p_jobid = pid;
376 		pp->p_friends = pp;
377 		pp->p_cwd = dcwd;
378 		dcwd->di_count++;
379 		if (pmaxindex < BIGINDEX)
380 			pp->p_index = ++pmaxindex;
381 		else {
382 			struct process *np;
383 
384 			for (i = 1; ; i++) {
385 				for (np = proclist.p_next; np; np = np->p_next)
386 					if (np->p_index == i)
387 						goto tryagain;
388 				pp->p_index = i;
389 				if (i > pmaxindex)
390 					pmaxindex = i;
391 				break;
392 			tryagain:;
393 			}
394 		}
395 		if (pcurrent == PNULL)
396 			pcurrent = pp;
397 		else if (pprevious == PNULL)
398 			pprevious = pp;
399 	}
400 	pp->p_next = proclist.p_next;
401 	proclist.p_next = pp;
402 	(void) gettimeofday(&pp->p_btime, (struct timezone *)0);
403 }
404 
405 padd(t)
406 	register struct command *t;
407 {
408 	char **argp;
409 
410 	if (t == 0)
411 		return;
412 	switch (t->t_dtyp) {
413 
414 	case NODE_PAREN:
415 		pads("( ");
416 		padd(t->t_dspr);
417 		pads(" )");
418 		break;
419 
420 	case NODE_COMMAND:
421 		for (argp = t->t_dcom; *argp; argp++) {
422 			pads(*argp);
423 			if (argp[1])
424 				pads(" ");
425 		}
426 		break;
427 
428 	case NODE_OR:
429 	case NODE_AND:
430 	case NODE_PIPE:
431 	case NODE_LIST:
432 		padd(t->t_dcar);
433 		switch (t->t_dtyp) {
434 		case NODE_OR:
435 			pads(" || ");
436 			break;
437 		case NODE_AND:
438 			pads(" && ");
439 			break;
440 		case NODE_PIPE:
441 			pads(" | ");
442 			break;
443 		case NODE_LIST:
444 			pads("; ");
445 			break;
446 		}
447 		padd(t->t_dcdr);
448 		return;
449 	}
450 	if ((t->t_dflg & F_PIPEIN) == 0 && t->t_dlef) {
451 		pads((t->t_dflg & F_READ) ? " << " : " < ");
452 		pads(t->t_dlef);
453 	}
454 	if ((t->t_dflg & F_PIPEOUT) == 0 && t->t_drit) {
455 		pads((t->t_dflg & F_APPEND) ? " >>" : " >");
456 		if (t->t_dflg & F_STDERR)
457 			pads("&");
458 		pads(" ");
459 		pads(t->t_drit);
460 	}
461 }
462 
463 pads(cp)
464 	char *cp;
465 {
466 	register int i = strlen(cp);
467 
468 	if (cmdlen >= PMAXLEN)
469 		return;
470 	if (cmdlen + i >= PMAXLEN) {
471 		(void) strcpy(cmdp, " ...");
472 		cmdlen = PMAXLEN;
473 		cmdp += 4;
474 		return;
475 	}
476 	(void) strcpy(cmdp, cp);
477 	cmdp += i;
478 	cmdlen += i;
479 }
480 
481 /*
482  * psavejob - temporarily save the current job on a one level stack
483  *	so another job can be created.  Used for { } in exp6
484  *	and `` in globbing.
485  */
486 psavejob()
487 {
488 
489 	pholdjob = pcurrjob;
490 	pcurrjob = PNULL;
491 }
492 
493 /*
494  * prestjob - opposite of psavejob.  This may be missed if we are interrupted
495  *	somewhere, but pendjob cleans up anyway.
496  */
497 prestjob()
498 {
499 
500 	pcurrjob = pholdjob;
501 	pholdjob = PNULL;
502 }
503 
504 /*
505  * pendjob - indicate that a job (set of commands) has been completed
506  *	or is about to begin.
507  */
508 pendjob()
509 {
510 	register struct process *pp, *tp;
511 
512 	if (pcurrjob && (pcurrjob->p_flags&(PFOREGND|PSTOPPED)) == 0) {
513 		pp = pcurrjob;
514 		while (pp->p_pid != pp->p_jobid)
515 			pp = pp->p_friends;
516 		printf("[%d]", pp->p_index);
517 		tp = pp;
518 		do {
519 			printf(" %d", pp->p_pid);
520 			pp = pp->p_friends;
521 		} while (pp != tp);
522 		printf("\n");
523 	}
524 	pholdjob = pcurrjob = 0;
525 }
526 
527 /*
528  * pprint - print a job
529  */
530 pprint(pp, flag)
531 	register struct process	*pp;
532 {
533 	register status, reason;
534 	struct process *tp;
535 	extern char *linp, linbuf[];
536 	int jobflags, pstatus;
537 	char *format;
538 
539 	while (pp->p_pid != pp->p_jobid)
540 		pp = pp->p_friends;
541 	if (pp == pp->p_friends && (pp->p_flags & PPTIME)) {
542 		pp->p_flags &= ~PPTIME;
543 		pp->p_flags |= PTIME;
544 	}
545 	tp = pp;
546 	status = reason = -1;
547 	jobflags = 0;
548 	do {
549 		jobflags |= pp->p_flags;
550 		pstatus = pp->p_flags & PALLSTATES;
551 		if (tp != pp && linp != linbuf && !(flag&FANCY) &&
552 		    (pstatus == status && pp->p_reason == reason ||
553 		     !(flag&REASON)))
554 			printf(" ");
555 		else {
556 			if (tp != pp && linp != linbuf)
557 				printf("\n");
558 			if(flag&NUMBER)
559 				if (pp == tp)
560 					printf("[%d]%s %c ", pp->p_index,
561 					    pp->p_index < 10 ? " " : "",
562 					    pp==pcurrent ? '+' :
563 						(pp == pprevious ? '-' : ' '));
564 				else
565 					printf("       ");
566 			if (flag&FANCY)
567 				printf("%5d ", pp->p_pid);
568 			if (flag&(REASON|AREASON)) {
569 				if (flag&NAME)
570 					format = "%-23s";
571 				else
572 					format = "%s";
573 				if (pstatus == status)
574 					if (pp->p_reason == reason) {
575 						printf(format, "");
576 						goto prcomd;
577 					} else
578 						reason = pp->p_reason;
579 				else {
580 					status = pstatus;
581 					reason = pp->p_reason;
582 				}
583 				switch (status) {
584 
585 				case PRUNNING:
586 					printf(format, "Running ");
587 					break;
588 
589 				case PINTERRUPTED:
590 				case PSTOPPED:
591 				case PSIGNALED:
592 					if ((flag&(REASON|AREASON))
593 					    && reason != SIGINT
594 					    && reason != SIGPIPE)
595 						printf(format, mesg[pp->p_reason].pname);
596 					break;
597 
598 				case PNEXITED:
599 				case PAEXITED:
600 					if (flag & REASON)
601 						if (pp->p_reason)
602 							printf("Exit %-16d", pp->p_reason);
603 						else
604 							printf(format, "Done");
605 					break;
606 
607 				default:
608 					printf("BUG: status=%-9o", status);
609 				}
610 			}
611 		}
612 prcomd:
613 		if (flag&NAME) {
614 			printf("%s", pp->p_command);
615 			if (pp->p_flags & PPOU)
616 				printf(" |");
617 			if (pp->p_flags & PDIAG)
618 				printf("&");
619 		}
620 		if (flag&(REASON|AREASON) && pp->p_flags&PDUMPED)
621 			printf(" (core dumped)");
622 		if (tp == pp->p_friends) {
623 			if (flag&AMPERSAND)
624 				printf(" &");
625 			if (flag&JOBDIR &&
626 			    !eq(tp->p_cwd->di_name, dcwd->di_name)) {
627 				printf(" (wd: ");
628 				dtildepr(value("home"), tp->p_cwd->di_name);
629 				printf(")");
630 			}
631 		}
632 		if (pp->p_flags&PPTIME && !(status&(PSTOPPED|PRUNNING))) {
633 			if (linp != linbuf)
634 				printf("\n\t");
635 			{ static struct rusage zru;
636 			  prusage(&zru, &pp->p_rusage, &pp->p_etime,
637 			    &pp->p_btime);
638 			}
639 		}
640 		if (tp == pp->p_friends) {
641 			if (linp != linbuf)
642 				printf("\n");
643 			if (flag&SHELLDIR && !eq(tp->p_cwd->di_name, dcwd->di_name)) {
644 				printf("(wd now: ");
645 				dtildepr(value("home"), dcwd->di_name);
646 				printf(")\n");
647 			}
648 		}
649 	} while ((pp = pp->p_friends) != tp);
650 	if (jobflags&PTIME && (jobflags&(PSTOPPED|PRUNNING)) == 0) {
651 		if (jobflags & NUMBER)
652 			printf("       ");
653 		ptprint(tp);
654 	}
655 	return (jobflags);
656 }
657 
658 ptprint(tp)
659 	register struct process *tp;
660 {
661 	struct timeval tetime, diff;
662 	static struct timeval ztime;
663 	struct rusage ru;
664 	static struct rusage zru;
665 	register struct process *pp = tp;
666 
667 	ru = zru;
668 	tetime = ztime;
669 	do {
670 		ruadd(&ru, &pp->p_rusage);
671 		tvsub(&diff, &pp->p_etime, &pp->p_btime);
672 		if (timercmp(&diff, &tetime, >))
673 			tetime = diff;
674 	} while ((pp = pp->p_friends) != tp);
675 	prusage(&zru, &ru, &tetime, &ztime);
676 }
677 
678 /*
679  * dojobs - print all jobs
680  */
681 dojobs(v)
682 	char **v;
683 {
684 	register struct process *pp;
685 	register int flag = NUMBER|NAME|REASON;
686 	int i;
687 
688 	if (chkstop)
689 		chkstop = 2;
690 	if (*++v) {
691 		if (v[1] || !eq(*v, "-l"))
692 			error("Usage: jobs [ -l ]");
693 		flag |= FANCY|JOBDIR;
694 	}
695 	for (i = 1; i <= pmaxindex; i++)
696 		for (pp = proclist.p_next; pp; pp = pp->p_next)
697 			if (pp->p_index == i && pp->p_pid == pp->p_jobid) {
698 				pp->p_flags &= ~PNEEDNOTE;
699 				if (!(pprint(pp, flag) & (PRUNNING|PSTOPPED)))
700 					pflush(pp);
701 				break;
702 			}
703 }
704 
705 /*
706  * dofg - builtin - put the job into the foreground
707  */
708 dofg(v)
709 	char **v;
710 {
711 	register struct process *pp;
712 
713 	okpcntl();
714 	++v;
715 	do {
716 		pp = pfind(*v);
717 		pstart(pp, 1);
718 		pjwait(pp);
719 	} while (*v && *++v);
720 }
721 
722 /*
723  * %... - builtin - put the job into the foreground
724  */
725 dofg1(v)
726 	char **v;
727 {
728 	register struct process *pp;
729 
730 	okpcntl();
731 	pp = pfind(v[0]);
732 	pstart(pp, 1);
733 	pjwait(pp);
734 }
735 
736 /*
737  * dobg - builtin - put the job into the background
738  */
739 dobg(v)
740 	char **v;
741 {
742 	register struct process *pp;
743 
744 	okpcntl();
745 	++v;
746 	do {
747 		pp = pfind(*v);
748 		pstart(pp, 0);
749 	} while (*v && *++v);
750 }
751 
752 /*
753  * %... & - builtin - put the job into the background
754  */
755 dobg1(v)
756 	char **v;
757 {
758 	register struct process *pp;
759 
760 	pp = pfind(v[0]);
761 	pstart(pp, 0);
762 }
763 
764 /*
765  * dostop - builtin - stop the job
766  */
767 dostop(v)
768 	char **v;
769 {
770 
771 	pkill(++v, SIGSTOP);
772 }
773 
774 /*
775  * dokill - builtin - superset of kill (1)
776  */
777 dokill(v)
778 	char **v;
779 {
780 	register int signum;
781 	register char *name;
782 
783 	v++;
784 	if (v[0] && v[0][0] == '-') {
785 		if (v[0][1] == 'l') {
786 			for (signum = 1; signum <= NSIG; signum++) {
787 				if (name = mesg[signum].iname)
788 					printf("%s ", name);
789 				if (signum == 16)
790 					cshputchar('\n');
791 			}
792 			cshputchar('\n');
793 			return;
794 		}
795 		if (digit(v[0][1])) {
796 			signum = atoi(v[0]+1);
797 			if (signum < 0 || signum > NSIG)
798 				bferr("Bad signal number");
799 		} else {
800 			name = &v[0][1];
801 			for (signum = 1; signum <= NSIG; signum++)
802 			if (mesg[signum].iname &&
803 			    eq(name, mesg[signum].iname))
804 				goto gotsig;
805 			setname(name);
806 			bferr("Unknown signal; kill -l lists signals");
807 		}
808 gotsig:
809 		v++;
810 	} else
811 		signum = SIGTERM;
812 	pkill(v, signum);
813 }
814 
815 pkill(v, signum)
816 	char **v;
817 	int signum;
818 {
819 	register struct process *pp, *np;
820 	register int jobflags = 0;
821 	int pid, err = 0;
822 	long omask;
823 	char *cp;
824 
825 	omask = sigmask(SIGCHLD);
826 	if (setintr)
827 		omask |= sigmask(SIGINT);
828 	omask = sigblock(omask) & ~omask;
829 	while (*v) {
830 		cp = globone(*v);
831 		if (*cp == '%') {
832 			np = pp = pfind(cp);
833 			do
834 				jobflags |= np->p_flags;
835 			while ((np = np->p_friends) != pp);
836 			switch (signum) {
837 
838 			case SIGSTOP:
839 			case SIGTSTP:
840 			case SIGTTIN:
841 			case SIGTTOU:
842 				if ((jobflags & PRUNNING) == 0) {
843 					printf("%s: Already suspended\n", cp);
844 					err++;
845 					goto cont;
846 				}
847 			}
848 			if (killpg(pp->p_jobid, signum) < 0) {
849 				printf("%s: %s\n", cp, strerror(errno));
850 				err++;
851 			}
852 			if (signum == SIGTERM || signum == SIGHUP)
853 				(void) killpg(pp->p_jobid, SIGCONT);
854 		} else if (!(digit(*cp) || *cp == '-'))
855 			bferr("Arguments should be jobs or process id's");
856 		else {
857 			pid = atoi(cp);
858 			if (kill(pid, signum) < 0) {
859 				printf("%d: %s\n", pid, strerror(errno));
860 				err++;
861 				goto cont;
862 			}
863 			if (signum == SIGTERM || signum == SIGHUP)
864 				(void) kill(pid, SIGCONT);
865 		}
866 cont:
867 		xfree(cp);
868 		v++;
869 	}
870 	(void) sigsetmask(omask);
871 	if (err)
872 		error(NOSTR);
873 }
874 
875 /*
876  * pstart - start the job in foreground/background
877  */
878 pstart(pp, foregnd)
879 	register struct process *pp;
880 	int foregnd;
881 {
882 	register struct process *np;
883 	int jobflags = 0;
884 	long omask;
885 
886 	omask = sigblock(sigmask(SIGCHLD));
887 	np = pp;
888 	do {
889 		jobflags |= np->p_flags;
890 		if (np->p_flags&(PRUNNING|PSTOPPED)) {
891 			np->p_flags |= PRUNNING;
892 			np->p_flags &= ~PSTOPPED;
893 			if (foregnd)
894 				np->p_flags |= PFOREGND;
895 			else
896 				np->p_flags &= ~PFOREGND;
897 		}
898 	} while((np = np->p_friends) != pp);
899 	if (!foregnd)
900 		pclrcurr(pp);
901 	(void) pprint(pp, foregnd ? NAME|JOBDIR : NUMBER|NAME|AMPERSAND);
902 	if (foregnd)
903 		(void) ioctl(FSHTTY, TIOCSPGRP, (char *)&pp->p_jobid);
904 	if (jobflags&PSTOPPED)
905 		(void) killpg(pp->p_jobid, SIGCONT);
906 	(void) sigsetmask(omask);
907 }
908 
909 panystop(neednl)
910 {
911 	register struct process *pp;
912 
913 	chkstop = 2;
914 	for (pp = proclist.p_next; pp; pp = pp->p_next)
915 		if (pp->p_flags & PSTOPPED)
916 			error("\nThere are suspended jobs" + 1 - neednl);
917 }
918 
919 struct process *
920 pfind(cp)
921 	char *cp;
922 {
923 	register struct process *pp, *np;
924 
925 	if (cp == 0 || cp[1] == 0 || eq(cp, "%%") || eq(cp, "%+")) {
926 		if (pcurrent == PNULL)
927 			bferr("No current job");
928 		return (pcurrent);
929 	}
930 	if (eq(cp, "%-") || eq(cp, "%#")) {
931 		if (pprevious == PNULL)
932 			bferr("No previous job");
933 		return (pprevious);
934 	}
935 	if (digit(cp[1])) {
936 		int index = atoi(cp+1);
937 		for (pp = proclist.p_next; pp; pp = pp->p_next)
938 			if (pp->p_index == index && pp->p_pid == pp->p_jobid)
939 				return (pp);
940 		bferr("No such job");
941 	}
942 	np = PNULL;
943 	for (pp = proclist.p_next; pp; pp = pp->p_next)
944 		if (pp->p_pid == pp->p_jobid) {
945 			if (cp[1] == '?') {
946 				register char *dp;
947 				for (dp = pp->p_command; *dp; dp++) {
948 					if (*dp != cp[2])
949 						continue;
950 					if (prefix(cp+2, dp))
951 						goto match;
952 				}
953 			} else if (prefix(cp+1, pp->p_command)) {
954 match:
955 				if (np)
956 					bferr("Ambiguous");
957 				np = pp;
958 			}
959 		}
960 	if (np)
961 		return (np);
962 	if (cp[1] == '?')
963 		bferr("No job matches pattern");
964 	else
965 		bferr("No such job");
966 	/*NOTREACHED*/
967 }
968 
969 /*
970  * pgetcurr - find most recent job that is not pp, preferably stopped
971  */
972 struct process *
973 pgetcurr(pp)
974 	register struct process *pp;
975 {
976 	register struct process *np;
977 	register struct process *xp = PNULL;
978 
979 	for (np = proclist.p_next; np; np = np->p_next)
980 		if (np != pcurrent && np != pp && np->p_pid &&
981 		    np->p_pid == np->p_jobid) {
982 			if (np->p_flags & PSTOPPED)
983 				return (np);
984 			if (xp == PNULL)
985 				xp = np;
986 		}
987 	return (xp);
988 }
989 
990 /*
991  * donotify - flag the job so as to report termination asynchronously
992  */
993 donotify(v)
994 	char **v;
995 {
996 	register struct process *pp;
997 
998 	pp = pfind(*++v);
999 	pp->p_flags |= PNOTIFY;
1000 }
1001 
1002 /*
1003  * Do the fork and whatever should be done in the child side that
1004  * should not be done if we are not forking at all (like for simple builtin's)
1005  * Also do everything that needs any signals fiddled with in the parent side
1006  *
1007  * Wanttty tells whether process and/or tty pgrps are to be manipulated:
1008  *	-1:	leave tty alone; inherit pgrp from parent
1009  *	 0:	already have tty; manipulate process pgrps only
1010  *	 1:	want to claim tty; manipulate process and tty pgrps
1011  * It is usually just the value of tpgrp.
1012  */
1013 pfork(t, wanttty)
1014 	struct command *t;	/* command we are forking for */
1015 	int wanttty;
1016 {
1017 	register int pid;
1018 	bool ignint = 0;
1019 	int pgrp;
1020 	long omask;
1021 
1022 	/*
1023 	 * A child will be uninterruptible only under very special
1024 	 * conditions. Remember that the semantics of '&' is
1025 	 * implemented by disconnecting the process from the tty so
1026 	 * signals do not need to ignored just for '&'.
1027 	 * Thus signals are set to default action for children unless:
1028 	 *	we have had an "onintr -" (then specifically ignored)
1029 	 *	we are not playing with signals (inherit action)
1030 	 */
1031 	if (setintr)
1032 		ignint = (tpgrp == -1 && (t->t_dflg&F_NOINTERRUPT))
1033 		    || (gointr && eq(gointr, "-"));
1034 	/*
1035 	 * Hold SIGCHLD until we have the process installed in our table.
1036 	 */
1037 	omask = sigblock(sigmask(SIGCHLD));
1038 	while ((pid = fork()) < 0)
1039 		if (setintr == 0)
1040 			sleep(FORKSLEEP);
1041 		else {
1042 			(void) sigsetmask(omask);
1043 			error("No more processes");
1044 		}
1045 	if (pid == 0) {
1046 		settimes();
1047 		pgrp = pcurrjob ? pcurrjob->p_jobid : getpid();
1048 		pflushall();
1049 		pcurrjob = PNULL;
1050 		child++;
1051 		if (setintr) {
1052 			setintr = 0;		/* until I think otherwise */
1053 			/*
1054 			 * Children just get blown away on SIGINT, SIGQUIT
1055 			 * unless "onintr -" seen.
1056 			 */
1057 			(void) signal(SIGINT, ignint ? SIG_IGN : SIG_DFL);
1058 			(void) signal(SIGQUIT, ignint ? SIG_IGN : SIG_DFL);
1059 			if (wanttty >= 0) {
1060 				/* make stoppable */
1061 				(void) signal(SIGTSTP, SIG_DFL);
1062 				(void) signal(SIGTTIN, SIG_DFL);
1063 				(void) signal(SIGTTOU, SIG_DFL);
1064 			}
1065 			(void) signal(SIGTERM, parterm);
1066 		} else if (tpgrp == -1 && (t->t_dflg&F_NOINTERRUPT)) {
1067 			(void) signal(SIGINT, SIG_IGN);
1068 			(void) signal(SIGQUIT, SIG_IGN);
1069 		}
1070 		if (wanttty >= 0 && tpgrp >= 0)
1071 			(void) setpgrp(0, pgrp);
1072 		if (wanttty > 0)
1073 			(void) ioctl(FSHTTY, TIOCSPGRP, (char *)&pgrp);
1074 		if (tpgrp > 0)
1075 			tpgrp = 0;		/* gave tty away */
1076 		/*
1077 		 * Nohup and nice apply only to NODE_COMMAND's but it would be
1078 		 * nice (?!?) if you could say "nohup (foo;bar)".  Then the
1079 		 * parser would have to know about nice/nohup/time.
1080 		 */
1081 		if (t->t_dflg & F_NOHUP)
1082 			(void) signal(SIGHUP, SIG_IGN);
1083 		if (t->t_dflg & F_NICE)
1084 			(void) setpriority(PRIO_PROCESS, 0, t->t_nice);
1085 	} else {
1086 		if (wanttty >= 0 && tpgrp >= 0)
1087 			(void) setpgrp(pid, pcurrjob ? pcurrjob->p_jobid : pid);
1088 		palloc(pid, t);
1089 		(void) sigsetmask(omask);
1090 	}
1091 
1092 	return (pid);
1093 }
1094 
1095 okpcntl()
1096 {
1097 
1098 	if (tpgrp == -1)
1099 		error("No job control in this shell");
1100 	if (tpgrp == 0)
1101 		error("No job control in subshells");
1102 }
1103