xref: /dragonfly/bin/sh/jobs.c (revision 650094e1)
1 /*-
2  * Copyright (c) 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Kenneth Almquist.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * @(#)jobs.c	8.5 (Berkeley) 5/4/95
37  * $FreeBSD: src/bin/sh/jobs.c,v 1.95 2011/06/13 21:03:27 jilles Exp $
38  */
39 
40 #include <sys/ioctl.h>
41 #include <sys/param.h>
42 #include <sys/resource.h>
43 #include <sys/time.h>
44 #include <sys/wait.h>
45 #include <errno.h>
46 #include <fcntl.h>
47 #include <paths.h>
48 #include <signal.h>
49 #include <stddef.h>
50 #include <stdlib.h>
51 #include <unistd.h>
52 
53 #include "shell.h"
54 #if JOBS
55 #include <termios.h>
56 #undef CEOF			/* syntax.h redefines this */
57 #endif
58 #include "redir.h"
59 #include "show.h"
60 #include "main.h"
61 #include "parser.h"
62 #include "nodes.h"
63 #include "jobs.h"
64 #include "options.h"
65 #include "trap.h"
66 #include "syntax.h"
67 #include "input.h"
68 #include "output.h"
69 #include "memalloc.h"
70 #include "error.h"
71 #include "mystring.h"
72 #include "var.h"
73 #include "builtins.h"
74 
75 
76 static struct job *jobtab;	/* array of jobs */
77 static int njobs;		/* size of array */
78 MKINIT pid_t backgndpid = -1;	/* pid of last background process */
79 MKINIT struct job *bgjob = NULL; /* last background process */
80 #if JOBS
81 static struct job *jobmru;	/* most recently used job list */
82 static pid_t initialpgrp;	/* pgrp of shell on invocation */
83 #endif
84 int in_waitcmd = 0;		/* are we in waitcmd()? */
85 int in_dowait = 0;		/* are we in dowait()? */
86 volatile sig_atomic_t breakwaitcmd = 0;	/* should wait be terminated? */
87 static int ttyfd = -1;
88 
89 #if JOBS
90 static void restartjob(struct job *);
91 #endif
92 static void freejob(struct job *);
93 static struct job *getjob(char *);
94 static pid_t dowait(int, struct job *);
95 static pid_t waitproc(int, int *);
96 static void checkzombies(void);
97 static void cmdtxt(union node *);
98 static void cmdputs(const char *);
99 #if JOBS
100 static void setcurjob(struct job *);
101 static void deljob(struct job *);
102 static struct job *getcurjob(struct job *);
103 #endif
104 static void printjobcmd(struct job *);
105 static void showjob(struct job *, int);
106 
107 
108 /*
109  * Turn job control on and off.
110  */
111 
112 MKINIT int jobctl;
113 
114 #if JOBS
115 void
116 setjobctl(int on)
117 {
118 	int i;
119 
120 	if (on == jobctl || rootshell == 0)
121 		return;
122 	if (on) {
123 		if (ttyfd != -1)
124 			close(ttyfd);
125 		if ((ttyfd = open(_PATH_TTY, O_RDWR)) < 0) {
126 			i = 0;
127 			while (i <= 2 && !isatty(i))
128 				i++;
129 			if (i > 2 || (ttyfd = fcntl(i, F_DUPFD, 10)) < 0)
130 				goto out;
131 		}
132 		if (ttyfd < 10) {
133 			/*
134 			 * Keep our TTY file descriptor out of the way of
135 			 * the user's redirections.
136 			 */
137 			if ((i = fcntl(ttyfd, F_DUPFD, 10)) < 0) {
138 				close(ttyfd);
139 				ttyfd = -1;
140 				goto out;
141 			}
142 			close(ttyfd);
143 			ttyfd = i;
144 		}
145 		if (fcntl(ttyfd, F_SETFD, FD_CLOEXEC) < 0) {
146 			close(ttyfd);
147 			ttyfd = -1;
148 			goto out;
149 		}
150 		do { /* while we are in the background */
151 			initialpgrp = tcgetpgrp(ttyfd);
152 			if (initialpgrp < 0) {
153 out:				out2fmt_flush("sh: can't access tty; job control turned off\n");
154 				mflag = 0;
155 				return;
156 			}
157 			if (initialpgrp != getpgrp()) {
158 				kill(0, SIGTTIN);
159 				continue;
160 			}
161 		} while (0);
162 		setsignal(SIGTSTP);
163 		setsignal(SIGTTOU);
164 		setsignal(SIGTTIN);
165 		setpgid(0, rootpid);
166 		tcsetpgrp(ttyfd, rootpid);
167 	} else { /* turning job control off */
168 		setpgid(0, initialpgrp);
169 		tcsetpgrp(ttyfd, initialpgrp);
170 		close(ttyfd);
171 		ttyfd = -1;
172 		setsignal(SIGTSTP);
173 		setsignal(SIGTTOU);
174 		setsignal(SIGTTIN);
175 	}
176 	jobctl = on;
177 }
178 #endif
179 
180 
181 #if JOBS
182 int
183 fgcmd(int argc __unused, char **argv)
184 {
185 	struct job *jp;
186 	pid_t pgrp;
187 	int status;
188 
189 	jp = getjob(argv[1]);
190 	if (jp->jobctl == 0)
191 		error("job not created under job control");
192 	printjobcmd(jp);
193 	flushout(&output);
194 	pgrp = jp->ps[0].pid;
195 	tcsetpgrp(ttyfd, pgrp);
196 	restartjob(jp);
197 	jp->foreground = 1;
198 	INTOFF;
199 	status = waitforjob(jp, NULL);
200 	INTON;
201 	return status;
202 }
203 
204 
205 int
206 bgcmd(int argc, char **argv)
207 {
208 	struct job *jp;
209 
210 	do {
211 		jp = getjob(*++argv);
212 		if (jp->jobctl == 0)
213 			error("job not created under job control");
214 		if (jp->state == JOBDONE)
215 			continue;
216 		restartjob(jp);
217 		jp->foreground = 0;
218 		out1fmt("[%td] ", jp - jobtab + 1);
219 		printjobcmd(jp);
220 	} while (--argc > 1);
221 	return 0;
222 }
223 
224 
225 static void
226 restartjob(struct job *jp)
227 {
228 	struct procstat *ps;
229 	int i;
230 
231 	if (jp->state == JOBDONE)
232 		return;
233 	setcurjob(jp);
234 	INTOFF;
235 	kill(-jp->ps[0].pid, SIGCONT);
236 	for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
237 		if (WIFSTOPPED(ps->status)) {
238 			ps->status = -1;
239 			jp->state = 0;
240 		}
241 	}
242 	INTON;
243 }
244 #endif
245 
246 
247 int
248 jobscmd(int argc, char *argv[])
249 {
250 	char *id;
251 	int ch, mode;
252 
253 	optind = optreset = 1;
254 	opterr = 0;
255 	mode = SHOWJOBS_DEFAULT;
256 	while ((ch = getopt(argc, argv, "lps")) != -1) {
257 		switch (ch) {
258 		case 'l':
259 			mode = SHOWJOBS_VERBOSE;
260 			break;
261 		case 'p':
262 			mode = SHOWJOBS_PGIDS;
263 			break;
264 		case 's':
265 			mode = SHOWJOBS_PIDS;
266 			break;
267 		case '?':
268 		default:
269 			error("unknown option: -%c", optopt);
270 		}
271 	}
272 	argc -= optind;
273 	argv += optind;
274 
275 	if (argc == 0)
276 		showjobs(0, mode);
277 	else
278 		while ((id = *argv++) != NULL)
279 			showjob(getjob(id), mode);
280 
281 	return (0);
282 }
283 
284 static void
285 printjobcmd(struct job *jp)
286 {
287 	struct procstat *ps;
288 	int i;
289 
290 	for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
291 		out1str(ps->cmd);
292 		if (i > 0)
293 			out1str(" | ");
294 	}
295 	out1c('\n');
296 }
297 
298 static void
299 showjob(struct job *jp, int mode)
300 {
301 	char s[64];
302 	char statestr[64];
303 	struct procstat *ps;
304 	struct job *j;
305 	int col, curr, i, jobno, prev, procno;
306 	char c;
307 
308 	procno = (mode == SHOWJOBS_PGIDS) ? 1 : jp->nprocs;
309 	jobno = jp - jobtab + 1;
310 	curr = prev = 0;
311 #if JOBS
312 	if ((j = getcurjob(NULL)) != NULL) {
313 		curr = j - jobtab + 1;
314 		if ((j = getcurjob(j)) != NULL)
315 			prev = j - jobtab + 1;
316 	}
317 #endif
318 	ps = jp->ps + jp->nprocs - 1;
319 	if (jp->state == 0) {
320 		strcpy(statestr, "Running");
321 #if JOBS
322 	} else if (jp->state == JOBSTOPPED) {
323 		while (!WIFSTOPPED(ps->status) && ps > jp->ps)
324 			ps--;
325 		if (WIFSTOPPED(ps->status))
326 			i = WSTOPSIG(ps->status);
327 		else
328 			i = -1;
329 		if (i > 0 && i < sys_nsig && sys_siglist[i])
330 			strcpy(statestr, sys_siglist[i]);
331 		else
332 			strcpy(statestr, "Suspended");
333 #endif
334 	} else if (WIFEXITED(ps->status)) {
335 		if (WEXITSTATUS(ps->status) == 0)
336 			strcpy(statestr, "Done");
337 		else
338 			fmtstr(statestr, 64, "Done(%d)",
339 			    WEXITSTATUS(ps->status));
340 	} else {
341 		i = WTERMSIG(ps->status);
342 		if (i > 0 && i < sys_nsig && sys_siglist[i])
343 			strcpy(statestr, sys_siglist[i]);
344 		else
345 			fmtstr(statestr, 64, "Signal %d", i);
346 		if (WCOREDUMP(ps->status))
347 			strcat(statestr, " (core dumped)");
348 	}
349 
350 	for (ps = jp->ps ; ; ps++) {	/* for each process */
351 		if (mode == SHOWJOBS_PIDS || mode == SHOWJOBS_PGIDS) {
352 			out1fmt("%d\n", (int)ps->pid);
353 			goto skip;
354 		}
355 		if (mode != SHOWJOBS_VERBOSE && ps != jp->ps)
356 			goto skip;
357 		if (jobno == curr && ps == jp->ps)
358 			c = '+';
359 		else if (jobno == prev && ps == jp->ps)
360 			c = '-';
361 		else
362 			c = ' ';
363 		if (ps == jp->ps)
364 			fmtstr(s, 64, "[%d] %c ", jobno, c);
365 		else
366 			fmtstr(s, 64, "    %c ", c);
367 		out1str(s);
368 		col = strlen(s);
369 		if (mode == SHOWJOBS_VERBOSE) {
370 			fmtstr(s, 64, "%d ", (int)ps->pid);
371 			out1str(s);
372 			col += strlen(s);
373 		}
374 		if (ps == jp->ps) {
375 			out1str(statestr);
376 			col += strlen(statestr);
377 		}
378 		do {
379 			out1c(' ');
380 			col++;
381 		} while (col < 30);
382 		if (mode == SHOWJOBS_VERBOSE) {
383 			out1str(ps->cmd);
384 			out1c('\n');
385 		} else
386 			printjobcmd(jp);
387 skip:		if (--procno <= 0)
388 			break;
389 	}
390 }
391 
392 /*
393  * Print a list of jobs.  If "change" is nonzero, only print jobs whose
394  * statuses have changed since the last call to showjobs.
395  *
396  * If the shell is interrupted in the process of creating a job, the
397  * result may be a job structure containing zero processes.  Such structures
398  * will be freed here.
399  */
400 
401 void
402 showjobs(int change, int mode)
403 {
404 	int jobno;
405 	struct job *jp;
406 
407 	TRACE(("showjobs(%d) called\n", change));
408 	checkzombies();
409 	for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
410 		if (! jp->used)
411 			continue;
412 		if (jp->nprocs == 0) {
413 			freejob(jp);
414 			continue;
415 		}
416 		if (change && ! jp->changed)
417 			continue;
418 		showjob(jp, mode);
419 		jp->changed = 0;
420 		/* Hack: discard jobs for which $! has not been referenced
421 		 * in interactive mode when they terminate.
422 		 */
423 		if (jp->state == JOBDONE && !jp->remembered &&
424 				(iflag || jp != bgjob)) {
425 			freejob(jp);
426 		}
427 	}
428 }
429 
430 
431 /*
432  * Mark a job structure as unused.
433  */
434 
435 static void
436 freejob(struct job *jp)
437 {
438 	struct procstat *ps;
439 	int i;
440 
441 	INTOFF;
442 	if (bgjob == jp)
443 		bgjob = NULL;
444 	for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
445 		if (ps->cmd != nullstr)
446 			ckfree(ps->cmd);
447 	}
448 	if (jp->ps != &jp->ps0)
449 		ckfree(jp->ps);
450 	jp->used = 0;
451 #if JOBS
452 	deljob(jp);
453 #endif
454 	INTON;
455 }
456 
457 
458 
459 int
460 waitcmd(int argc, char **argv)
461 {
462 	struct job *job;
463 	int status, retval;
464 	struct job *jp;
465 
466 	if (argc > 1) {
467 		job = getjob(argv[1]);
468 	} else {
469 		job = NULL;
470 	}
471 
472 	/*
473 	 * Loop until a process is terminated or stopped, or a SIGINT is
474 	 * received.
475 	 */
476 
477 	in_waitcmd++;
478 	do {
479 		if (job != NULL) {
480 			if (job->state) {
481 				status = job->ps[job->nprocs - 1].status;
482 				if (WIFEXITED(status))
483 					retval = WEXITSTATUS(status);
484 #if JOBS
485 				else if (WIFSTOPPED(status))
486 					retval = WSTOPSIG(status) + 128;
487 #endif
488 				else
489 					retval = WTERMSIG(status) + 128;
490 				if (! iflag || ! job->changed)
491 					freejob(job);
492 				else {
493 					job->remembered = 0;
494 					if (job == bgjob)
495 						bgjob = NULL;
496 				}
497 				in_waitcmd--;
498 				return retval;
499 			}
500 		} else {
501 			for (jp = jobtab ; jp < jobtab + njobs; jp++)
502 				if (jp->used && jp->state == JOBDONE) {
503 					if (! iflag || ! jp->changed)
504 						freejob(jp);
505 					else {
506 						jp->remembered = 0;
507 						if (jp == bgjob)
508 							bgjob = NULL;
509 					}
510 				}
511 			for (jp = jobtab ; ; jp++) {
512 				if (jp >= jobtab + njobs) {	/* no running procs */
513 					in_waitcmd--;
514 					return 0;
515 				}
516 				if (jp->used && jp->state == 0)
517 					break;
518 			}
519 		}
520 	} while (dowait(1, NULL) != -1);
521 	in_waitcmd--;
522 
523 	return 0;
524 }
525 
526 
527 
528 int
529 jobidcmd(int argc __unused, char **argv)
530 {
531 	struct job *jp;
532 	int i;
533 
534 	jp = getjob(argv[1]);
535 	for (i = 0 ; i < jp->nprocs ; ) {
536 		out1fmt("%d", (int)jp->ps[i].pid);
537 		out1c(++i < jp->nprocs? ' ' : '\n');
538 	}
539 	return 0;
540 }
541 
542 
543 
544 /*
545  * Convert a job name to a job structure.
546  */
547 
548 static struct job *
549 getjob(char *name)
550 {
551 	int jobno;
552 	struct job *found, *jp;
553 	pid_t pid;
554 	int i;
555 
556 	if (name == NULL) {
557 #if JOBS
558 currentjob:	if ((jp = getcurjob(NULL)) == NULL)
559 			error("No current job");
560 		return (jp);
561 #else
562 		error("No current job");
563 #endif
564 	} else if (name[0] == '%') {
565 		if (is_digit(name[1])) {
566 			jobno = number(name + 1);
567 			if (jobno > 0 && jobno <= njobs
568 			 && jobtab[jobno - 1].used != 0)
569 				return &jobtab[jobno - 1];
570 #if JOBS
571 		} else if (name[1] == '%' && name[2] == '\0') {
572 			goto currentjob;
573 		} else if (name[1] == '+' && name[2] == '\0') {
574 			goto currentjob;
575 		} else if (name[1] == '-' && name[2] == '\0') {
576 			if ((jp = getcurjob(NULL)) == NULL ||
577 			    (jp = getcurjob(jp)) == NULL)
578 				error("No previous job");
579 			return (jp);
580 #endif
581 		} else if (name[1] == '?') {
582 			found = NULL;
583 			for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
584 				if (jp->used && jp->nprocs > 0
585 				 && strstr(jp->ps[0].cmd, name + 2) != NULL) {
586 					if (found)
587 						error("%s: ambiguous", name);
588 					found = jp;
589 				}
590 			}
591 			if (found != NULL)
592 				return (found);
593 		} else {
594 			found = NULL;
595 			for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
596 				if (jp->used && jp->nprocs > 0
597 				 && prefix(name + 1, jp->ps[0].cmd)) {
598 					if (found)
599 						error("%s: ambiguous", name);
600 					found = jp;
601 				}
602 			}
603 			if (found)
604 				return found;
605 		}
606 	} else if (is_number(name)) {
607 		pid = (pid_t)number(name);
608 		for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
609 			if (jp->used && jp->nprocs > 0
610 			 && jp->ps[jp->nprocs - 1].pid == pid)
611 				return jp;
612 		}
613 	}
614 	error("No such job: %s", name);
615 	/*NOTREACHED*/
616 	return NULL;
617 }
618 
619 
620 pid_t
621 getjobpgrp(char *name)
622 {
623 	struct job *jp;
624 
625 	jp = getjob(name);
626 	return -jp->ps[0].pid;
627 }
628 
629 /*
630  * Return a new job structure,
631  */
632 
633 struct job *
634 makejob(union node *node __unused, int nprocs)
635 {
636 	int i;
637 	struct job *jp;
638 
639 	for (i = njobs, jp = jobtab ; ; jp++) {
640 		if (--i < 0) {
641 			INTOFF;
642 			if (njobs == 0) {
643 				jobtab = ckmalloc(4 * sizeof jobtab[0]);
644 #if JOBS
645 				jobmru = NULL;
646 #endif
647 			} else {
648 				jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
649 				memcpy(jp, jobtab, njobs * sizeof jp[0]);
650 #if JOBS
651 				/* Relocate `next' pointers and list head */
652 				if (jobmru != NULL)
653 					jobmru = &jp[jobmru - jobtab];
654 				for (i = 0; i < njobs; i++)
655 					if (jp[i].next != NULL)
656 						jp[i].next = &jp[jp[i].next -
657 						    jobtab];
658 #endif
659 				if (bgjob != NULL)
660 					bgjob = &jp[bgjob - jobtab];
661 				/* Relocate `ps' pointers */
662 				for (i = 0; i < njobs; i++)
663 					if (jp[i].ps == &jobtab[i].ps0)
664 						jp[i].ps = &jp[i].ps0;
665 				ckfree(jobtab);
666 				jobtab = jp;
667 			}
668 			jp = jobtab + njobs;
669 			for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0);
670 			INTON;
671 			break;
672 		}
673 		if (jp->used == 0)
674 			break;
675 	}
676 	INTOFF;
677 	jp->state = 0;
678 	jp->used = 1;
679 	jp->changed = 0;
680 	jp->nprocs = 0;
681 	jp->foreground = 0;
682 	jp->remembered = 0;
683 #if JOBS
684 	jp->jobctl = jobctl;
685 	jp->next = NULL;
686 #endif
687 	if (nprocs > 1) {
688 		jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
689 	} else {
690 		jp->ps = &jp->ps0;
691 	}
692 	INTON;
693 	TRACE(("makejob(%p, %d) returns %%%td\n", (void *)node, nprocs,
694 	    jp - jobtab + 1));
695 	return jp;
696 }
697 
698 #if JOBS
699 static void
700 setcurjob(struct job *cj)
701 {
702 	struct job *jp, *prev;
703 
704 	for (prev = NULL, jp = jobmru; jp != NULL; prev = jp, jp = jp->next) {
705 		if (jp == cj) {
706 			if (prev != NULL)
707 				prev->next = jp->next;
708 			else
709 				jobmru = jp->next;
710 			jp->next = jobmru;
711 			jobmru = cj;
712 			return;
713 		}
714 	}
715 	cj->next = jobmru;
716 	jobmru = cj;
717 }
718 
719 static void
720 deljob(struct job *j)
721 {
722 	struct job *jp, *prev;
723 
724 	for (prev = NULL, jp = jobmru; jp != NULL; prev = jp, jp = jp->next) {
725 		if (jp == j) {
726 			if (prev != NULL)
727 				prev->next = jp->next;
728 			else
729 				jobmru = jp->next;
730 			return;
731 		}
732 	}
733 }
734 
735 /*
736  * Return the most recently used job that isn't `nj', and preferably one
737  * that is stopped.
738  */
739 static struct job *
740 getcurjob(struct job *nj)
741 {
742 	struct job *jp;
743 
744 	/* Try to find a stopped one.. */
745 	for (jp = jobmru; jp != NULL; jp = jp->next)
746 		if (jp->used && jp != nj && jp->state == JOBSTOPPED)
747 			return (jp);
748 	/* Otherwise the most recently used job that isn't `nj' */
749 	for (jp = jobmru; jp != NULL; jp = jp->next)
750 		if (jp->used && jp != nj)
751 			return (jp);
752 
753 	return (NULL);
754 }
755 
756 #endif
757 
758 /*
759  * Fork of a subshell.  If we are doing job control, give the subshell its
760  * own process group.  Jp is a job structure that the job is to be added to.
761  * N is the command that will be evaluated by the child.  Both jp and n may
762  * be NULL.  The mode parameter can be one of the following:
763  *	FORK_FG - Fork off a foreground process.
764  *	FORK_BG - Fork off a background process.
765  *	FORK_NOJOB - Like FORK_FG, but don't give the process its own
766  *		     process group even if job control is on.
767  *
768  * When job control is turned off, background processes have their standard
769  * input redirected to /dev/null (except for the second and later processes
770  * in a pipeline).
771  */
772 
773 pid_t
774 forkshell(struct job *jp, union node *n, int mode)
775 {
776 	pid_t pid;
777 	pid_t pgrp;
778 
779 	TRACE(("forkshell(%%%td, %p, %d) called\n", jp - jobtab, (void *)n,
780 	    mode));
781 	INTOFF;
782 	if (mode == FORK_BG && (jp == NULL || jp->nprocs == 0))
783 		checkzombies();
784 	flushall();
785 	pid = fork();
786 	if (pid == -1) {
787 		TRACE(("Fork failed, errno=%d\n", errno));
788 		INTON;
789 		error("Cannot fork: %s", strerror(errno));
790 	}
791 	if (pid == 0) {
792 		struct job *p;
793 		int wasroot;
794 		int i;
795 
796 		TRACE(("Child shell %d\n", (int)getpid()));
797 		wasroot = rootshell;
798 		rootshell = 0;
799 		handler = &main_handler;
800 		closescript();
801 		INTON;
802 		forcelocal = 0;
803 		clear_traps();
804 #if JOBS
805 		jobctl = 0;		/* do job control only in root shell */
806 		if (wasroot && mode != FORK_NOJOB && mflag) {
807 			if (jp == NULL || jp->nprocs == 0)
808 				pgrp = getpid();
809 			else
810 				pgrp = jp->ps[0].pid;
811 			if (setpgid(0, pgrp) == 0 && mode == FORK_FG) {
812 				/*** this causes superfluous TIOCSPGRPS ***/
813 				if (tcsetpgrp(ttyfd, pgrp) < 0)
814 					error("tcsetpgrp failed, errno=%d", errno);
815 			}
816 			setsignal(SIGTSTP);
817 			setsignal(SIGTTOU);
818 		} else if (mode == FORK_BG) {
819 			ignoresig(SIGINT);
820 			ignoresig(SIGQUIT);
821 			if ((jp == NULL || jp->nprocs == 0) &&
822 			    ! fd0_redirected_p ()) {
823 				close(0);
824 				if (open(_PATH_DEVNULL, O_RDONLY) != 0)
825 					error("cannot open %s: %s",
826 					    _PATH_DEVNULL, strerror(errno));
827 			}
828 		}
829 #else
830 		if (mode == FORK_BG) {
831 			ignoresig(SIGINT);
832 			ignoresig(SIGQUIT);
833 			if ((jp == NULL || jp->nprocs == 0) &&
834 			    ! fd0_redirected_p ()) {
835 				close(0);
836 				if (open(_PATH_DEVNULL, O_RDONLY) != 0)
837 					error("cannot open %s: %s",
838 					    _PATH_DEVNULL, strerror(errno));
839 			}
840 		}
841 #endif
842 		INTOFF;
843 		for (i = njobs, p = jobtab ; --i >= 0 ; p++)
844 			if (p->used)
845 				freejob(p);
846 		INTON;
847 		if (wasroot && iflag) {
848 			setsignal(SIGINT);
849 			setsignal(SIGQUIT);
850 			setsignal(SIGTERM);
851 		}
852 		return pid;
853 	}
854 	if (rootshell && mode != FORK_NOJOB && mflag) {
855 		if (jp == NULL || jp->nprocs == 0)
856 			pgrp = pid;
857 		else
858 			pgrp = jp->ps[0].pid;
859 		setpgid(pid, pgrp);
860 	}
861 	if (mode == FORK_BG) {
862 		if (bgjob != NULL && bgjob->state == JOBDONE &&
863 		    !bgjob->remembered && !iflag)
864 			freejob(bgjob);
865 		backgndpid = pid;		/* set $! */
866 		bgjob = jp;
867 	}
868 	if (jp) {
869 		struct procstat *ps = &jp->ps[jp->nprocs++];
870 		ps->pid = pid;
871 		ps->status = -1;
872 		ps->cmd = nullstr;
873 		if (iflag && rootshell && n)
874 			ps->cmd = commandtext(n);
875 		jp->foreground = mode == FORK_FG;
876 #if JOBS
877 		setcurjob(jp);
878 #endif
879 	}
880 	INTON;
881 	TRACE(("In parent shell:  child = %d\n", (int)pid));
882 	return pid;
883 }
884 
885 
886 
887 /*
888  * Wait for job to finish.
889  *
890  * Under job control we have the problem that while a child process is
891  * running interrupts generated by the user are sent to the child but not
892  * to the shell.  This means that an infinite loop started by an inter-
893  * active user may be hard to kill.  With job control turned off, an
894  * interactive user may place an interactive program inside a loop.  If
895  * the interactive program catches interrupts, the user doesn't want
896  * these interrupts to also abort the loop.  The approach we take here
897  * is to have the shell ignore interrupt signals while waiting for a
898  * foreground process to terminate, and then send itself an interrupt
899  * signal if the child process was terminated by an interrupt signal.
900  * Unfortunately, some programs want to do a bit of cleanup and then
901  * exit on interrupt; unless these processes terminate themselves by
902  * sending a signal to themselves (instead of calling exit) they will
903  * confuse this approach.
904  */
905 
906 int
907 waitforjob(struct job *jp, int *origstatus)
908 {
909 #if JOBS
910 	pid_t mypgrp = getpgrp();
911 	int propagate_int = jp->jobctl && jp->foreground;
912 #endif
913 	int status;
914 	int st;
915 
916 	INTOFF;
917 	TRACE(("waitforjob(%%%td) called\n", jp - jobtab + 1));
918 	while (jp->state == 0)
919 		if (dowait(1, jp) == -1)
920 			dotrap();
921 #if JOBS
922 	if (jp->jobctl) {
923 		if (tcsetpgrp(ttyfd, mypgrp) < 0)
924 			error("tcsetpgrp failed, errno=%d\n", errno);
925 	}
926 	if (jp->state == JOBSTOPPED)
927 		setcurjob(jp);
928 #endif
929 	status = jp->ps[jp->nprocs - 1].status;
930 	if (origstatus != NULL)
931 		*origstatus = status;
932 	/* convert to 8 bits */
933 	if (WIFEXITED(status))
934 		st = WEXITSTATUS(status);
935 #if JOBS
936 	else if (WIFSTOPPED(status))
937 		st = WSTOPSIG(status) + 128;
938 #endif
939 	else
940 		st = WTERMSIG(status) + 128;
941 	if (! JOBS || jp->state == JOBDONE)
942 		freejob(jp);
943 	if (int_pending()) {
944 		if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGINT)
945 			CLEAR_PENDING_INT;
946 	}
947 #if JOBS
948 	else if (rootshell && iflag && propagate_int &&
949 			WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
950 		kill(getpid(), SIGINT);
951 #endif
952 	INTON;
953 	return st;
954 }
955 
956 
957 
958 /*
959  * Wait for a process to terminate.
960  */
961 
962 static pid_t
963 dowait(int block, struct job *job)
964 {
965 	pid_t pid;
966 	int status;
967 	struct procstat *sp;
968 	struct job *jp;
969 	struct job *thisjob;
970 	int done;
971 	int stopped;
972 	int sig;
973 	int coredump;
974 
975 	in_dowait++;
976 	TRACE(("dowait(%d) called\n", block));
977 	do {
978 		pid = waitproc(block, &status);
979 		TRACE(("wait returns %d, status=%d\n", (int)pid, status));
980 	} while ((pid == -1 && errno == EINTR && breakwaitcmd == 0) ||
981 		 (pid > 0 && WIFSTOPPED(status) && !iflag));
982 	in_dowait--;
983 	if (pid == -1 && errno == ECHILD && job != NULL)
984 		job->state = JOBDONE;
985 	if (breakwaitcmd != 0) {
986 		breakwaitcmd = 0;
987 		/*
988 		 * Do not early terminate if the pid is positive, else the
989 		 * job will not be properly recorded.
990 		 */
991 		if (pid <= 0)
992 			return -1;
993 	}
994 	if (pid <= 0)
995 		return pid;
996 	INTOFF;
997 	thisjob = NULL;
998 	for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
999 		if (jp->used && jp->nprocs > 0) {
1000 			done = 1;
1001 			stopped = 1;
1002 			for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
1003 				if (sp->pid == -1)
1004 					continue;
1005 				if (sp->pid == pid) {
1006 					TRACE(("Changing status of proc %d from 0x%x to 0x%x\n",
1007 						   (int)pid, sp->status,
1008 						   status));
1009 					sp->status = status;
1010 					thisjob = jp;
1011 				}
1012 				if (sp->status == -1)
1013 					stopped = 0;
1014 				else if (WIFSTOPPED(sp->status))
1015 					done = 0;
1016 			}
1017 			if (stopped) {		/* stopped or done */
1018 				int state = done? JOBDONE : JOBSTOPPED;
1019 				if (jp->state != state) {
1020 					TRACE(("Job %td: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
1021 					jp->state = state;
1022 					if (jp != job) {
1023 						if (done && !jp->remembered &&
1024 						    !iflag && jp != bgjob)
1025 							freejob(jp);
1026 #if JOBS
1027 						else if (done)
1028 							deljob(jp);
1029 #endif
1030 					}
1031 				}
1032 			}
1033 		}
1034 	}
1035 	INTON;
1036 	if (!thisjob || thisjob->state == 0)
1037 		;
1038 	else if ((!rootshell || !iflag || thisjob == job) &&
1039 	    thisjob->foreground && thisjob->state != JOBSTOPPED) {
1040 		sig = 0;
1041 		coredump = 0;
1042 		for (sp = thisjob->ps; sp < thisjob->ps + thisjob->nprocs; sp++)
1043 			if (WIFSIGNALED(sp->status)) {
1044 				sig = WTERMSIG(sp->status);
1045 				coredump = WCOREDUMP(sp->status);
1046 			}
1047 		if (sig > 0 && sig != SIGINT && sig != SIGPIPE) {
1048 			if (sig < sys_nsig && sys_siglist[sig])
1049 				out2str(sys_siglist[sig]);
1050 			else
1051 				outfmt(out2, "Signal %d", sig);
1052 			if (coredump)
1053 				out2str(" (core dumped)");
1054 			out2c('\n');
1055 			flushout(out2);
1056 		}
1057 	} else {
1058 		TRACE(("Not printing status, rootshell=%d, job=%p\n", rootshell, job));
1059 		thisjob->changed = 1;
1060 	}
1061 	return pid;
1062 }
1063 
1064 
1065 
1066 /*
1067  * Do a wait system call.  If job control is compiled in, we accept
1068  * stopped processes.  If block is zero, we return a value of zero
1069  * rather than blocking.
1070  */
1071 static pid_t
1072 waitproc(int block, int *status)
1073 {
1074 	int flags;
1075 
1076 #if JOBS
1077 	flags = WUNTRACED;
1078 #else
1079 	flags = 0;
1080 #endif
1081 	if (block == 0)
1082 		flags |= WNOHANG;
1083 	return wait3(status, flags, NULL);
1084 }
1085 
1086 /*
1087  * return 1 if there are stopped jobs, otherwise 0
1088  */
1089 int job_warning = 0;
1090 int
1091 stoppedjobs(void)
1092 {
1093 	int jobno;
1094 	struct job *jp;
1095 
1096 	if (job_warning)
1097 		return (0);
1098 	for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
1099 		if (jp->used == 0)
1100 			continue;
1101 		if (jp->state == JOBSTOPPED) {
1102 			out2fmt_flush("You have stopped jobs.\n");
1103 			job_warning = 2;
1104 			return (1);
1105 		}
1106 	}
1107 
1108 	return (0);
1109 }
1110 
1111 
1112 static void
1113 checkzombies(void)
1114 {
1115 	while (njobs > 0 && dowait(0, NULL) > 0)
1116 		;
1117 }
1118 
1119 
1120 int
1121 backgndpidset(void)
1122 {
1123 	return backgndpid != -1;
1124 }
1125 
1126 
1127 pid_t
1128 backgndpidval(void)
1129 {
1130 	if (bgjob != NULL && !forcelocal)
1131 		bgjob->remembered = 1;
1132 	return backgndpid;
1133 }
1134 
1135 /*
1136  * Return a string identifying a command (to be printed by the
1137  * jobs command.
1138  */
1139 
1140 static char *cmdnextc;
1141 static int cmdnleft;
1142 #define MAXCMDTEXT	200
1143 
1144 char *
1145 commandtext(union node *n)
1146 {
1147 	char *name;
1148 
1149 	cmdnextc = name = ckmalloc(MAXCMDTEXT);
1150 	cmdnleft = MAXCMDTEXT - 4;
1151 	cmdtxt(n);
1152 	*cmdnextc = '\0';
1153 	return name;
1154 }
1155 
1156 
1157 static void
1158 cmdtxt(union node *n)
1159 {
1160 	union node *np;
1161 	struct nodelist *lp;
1162 	const char *p;
1163 	int i;
1164 	char s[2];
1165 
1166 	if (n == NULL)
1167 		return;
1168 	switch (n->type) {
1169 	case NSEMI:
1170 		cmdtxt(n->nbinary.ch1);
1171 		cmdputs("; ");
1172 		cmdtxt(n->nbinary.ch2);
1173 		break;
1174 	case NAND:
1175 		cmdtxt(n->nbinary.ch1);
1176 		cmdputs(" && ");
1177 		cmdtxt(n->nbinary.ch2);
1178 		break;
1179 	case NOR:
1180 		cmdtxt(n->nbinary.ch1);
1181 		cmdputs(" || ");
1182 		cmdtxt(n->nbinary.ch2);
1183 		break;
1184 	case NPIPE:
1185 		for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
1186 			cmdtxt(lp->n);
1187 			if (lp->next)
1188 				cmdputs(" | ");
1189 		}
1190 		break;
1191 	case NSUBSHELL:
1192 		cmdputs("(");
1193 		cmdtxt(n->nredir.n);
1194 		cmdputs(")");
1195 		break;
1196 	case NREDIR:
1197 	case NBACKGND:
1198 		cmdtxt(n->nredir.n);
1199 		break;
1200 	case NIF:
1201 		cmdputs("if ");
1202 		cmdtxt(n->nif.test);
1203 		cmdputs("; then ");
1204 		cmdtxt(n->nif.ifpart);
1205 		cmdputs("...");
1206 		break;
1207 	case NWHILE:
1208 		cmdputs("while ");
1209 		goto until;
1210 	case NUNTIL:
1211 		cmdputs("until ");
1212 until:
1213 		cmdtxt(n->nbinary.ch1);
1214 		cmdputs("; do ");
1215 		cmdtxt(n->nbinary.ch2);
1216 		cmdputs("; done");
1217 		break;
1218 	case NFOR:
1219 		cmdputs("for ");
1220 		cmdputs(n->nfor.var);
1221 		cmdputs(" in ...");
1222 		break;
1223 	case NCASE:
1224 		cmdputs("case ");
1225 		cmdputs(n->ncase.expr->narg.text);
1226 		cmdputs(" in ...");
1227 		break;
1228 	case NDEFUN:
1229 		cmdputs(n->narg.text);
1230 		cmdputs("() ...");
1231 		break;
1232 	case NCMD:
1233 		for (np = n->ncmd.args ; np ; np = np->narg.next) {
1234 			cmdtxt(np);
1235 			if (np->narg.next)
1236 				cmdputs(" ");
1237 		}
1238 		for (np = n->ncmd.redirect ; np ; np = np->nfile.next) {
1239 			cmdputs(" ");
1240 			cmdtxt(np);
1241 		}
1242 		break;
1243 	case NARG:
1244 		cmdputs(n->narg.text);
1245 		break;
1246 	case NTO:
1247 		p = ">";  i = 1;  goto redir;
1248 	case NAPPEND:
1249 		p = ">>";  i = 1;  goto redir;
1250 	case NTOFD:
1251 		p = ">&";  i = 1;  goto redir;
1252 	case NCLOBBER:
1253 		p = ">|"; i = 1; goto redir;
1254 	case NFROM:
1255 		p = "<";  i = 0;  goto redir;
1256 	case NFROMTO:
1257 		p = "<>";  i = 0;  goto redir;
1258 	case NFROMFD:
1259 		p = "<&";  i = 0;  goto redir;
1260 redir:
1261 		if (n->nfile.fd != i) {
1262 			s[0] = n->nfile.fd + '0';
1263 			s[1] = '\0';
1264 			cmdputs(s);
1265 		}
1266 		cmdputs(p);
1267 		if (n->type == NTOFD || n->type == NFROMFD) {
1268 			if (n->ndup.dupfd >= 0)
1269 				s[0] = n->ndup.dupfd + '0';
1270 			else
1271 				s[0] = '-';
1272 			s[1] = '\0';
1273 			cmdputs(s);
1274 		} else {
1275 			cmdtxt(n->nfile.fname);
1276 		}
1277 		break;
1278 	case NHERE:
1279 	case NXHERE:
1280 		cmdputs("<<...");
1281 		break;
1282 	default:
1283 		cmdputs("???");
1284 		break;
1285 	}
1286 }
1287 
1288 
1289 
1290 static void
1291 cmdputs(const char *s)
1292 {
1293 	const char *p;
1294 	char *q;
1295 	char c;
1296 	int subtype = 0;
1297 
1298 	if (cmdnleft <= 0)
1299 		return;
1300 	p = s;
1301 	q = cmdnextc;
1302 	while ((c = *p++) != '\0') {
1303 		if (c == CTLESC)
1304 			*q++ = *p++;
1305 		else if (c == CTLVAR) {
1306 			*q++ = '$';
1307 			if (--cmdnleft > 0)
1308 				*q++ = '{';
1309 			subtype = *p++;
1310 			if ((subtype & VSTYPE) == VSLENGTH && --cmdnleft > 0)
1311 				*q++ = '#';
1312 		} else if (c == '=' && subtype != 0) {
1313 			*q = "}-+?=##%%\0X"[(subtype & VSTYPE) - VSNORMAL];
1314 			if (*q)
1315 				q++;
1316 			else
1317 				cmdnleft++;
1318 			if (((subtype & VSTYPE) == VSTRIMLEFTMAX ||
1319 			    (subtype & VSTYPE) == VSTRIMRIGHTMAX) &&
1320 			    --cmdnleft > 0)
1321 				*q = q[-1], q++;
1322 			subtype = 0;
1323 		} else if (c == CTLENDVAR) {
1324 			*q++ = '}';
1325 		} else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE) {
1326 			cmdnleft -= 5;
1327 			if (cmdnleft > 0) {
1328 				*q++ = '$';
1329 				*q++ = '(';
1330 				*q++ = '.';
1331 				*q++ = '.';
1332 				*q++ = '.';
1333 				*q++ = ')';
1334 			}
1335 		} else if (c == CTLARI) {
1336 			cmdnleft -= 2;
1337 			if (cmdnleft > 0) {
1338 				*q++ = '$';
1339 				*q++ = '(';
1340 				*q++ = '(';
1341 			}
1342 			p++;
1343 		} else if (c == CTLENDARI) {
1344 			if (--cmdnleft > 0) {
1345 				*q++ = ')';
1346 				*q++ = ')';
1347 			}
1348 		} else if (c == CTLQUOTEMARK || c == CTLQUOTEEND)
1349 			cmdnleft++; /* ignore */
1350 		else
1351 			*q++ = c;
1352 		if (--cmdnleft <= 0) {
1353 			*q++ = '.';
1354 			*q++ = '.';
1355 			*q++ = '.';
1356 			break;
1357 		}
1358 	}
1359 	cmdnextc = q;
1360 }
1361