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