jobs.c revision 264168
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: stable/10/bin/sh/jobs.c 264168 2014-04-05 20:01:08Z jilles $");
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 *);
98pid_t getjobpgrp(char *);
99static struct job *getjob_nonotfound(const char *);
100static struct job *getjob(const 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(const 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(const 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	int propagate_int = jp->jobctl && jp->foreground;
982#endif
983	int status;
984	int st;
985
986	INTOFF;
987	TRACE(("waitforjob(%%%td) called\n", jp - jobtab + 1));
988	while (jp->state == 0)
989		if (dowait(DOWAIT_BLOCK | (Tflag ? DOWAIT_SIG |
990		    DOWAIT_SIG_ANY : 0), jp) == -1)
991			dotrap();
992#if JOBS
993	if (jp->jobctl) {
994		if (tcsetpgrp(ttyfd, rootpid) < 0)
995			error("tcsetpgrp failed, errno=%d\n", errno);
996	}
997	if (jp->state == JOBSTOPPED)
998		setcurjob(jp);
999#endif
1000	status = jp->ps[jp->nprocs - 1].status;
1001	if (origstatus != NULL)
1002		*origstatus = status;
1003	/* convert to 8 bits */
1004	if (WIFEXITED(status))
1005		st = WEXITSTATUS(status);
1006#if JOBS
1007	else if (WIFSTOPPED(status))
1008		st = WSTOPSIG(status) + 128;
1009#endif
1010	else
1011		st = WTERMSIG(status) + 128;
1012	if (! JOBS || jp->state == JOBDONE)
1013		freejob(jp);
1014	if (int_pending()) {
1015		if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGINT)
1016			CLEAR_PENDING_INT;
1017	}
1018#if JOBS
1019	else if (rootshell && iflag && propagate_int &&
1020			WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
1021		kill(getpid(), SIGINT);
1022#endif
1023	INTON;
1024	return st;
1025}
1026
1027
1028static void
1029dummy_handler(int sig __unused)
1030{
1031}
1032
1033/*
1034 * Wait for a process to terminate.
1035 */
1036
1037static pid_t
1038dowait(int mode, struct job *job)
1039{
1040	struct sigaction sa, osa;
1041	sigset_t mask, omask;
1042	pid_t pid;
1043	int status;
1044	struct procstat *sp;
1045	struct job *jp;
1046	struct job *thisjob;
1047	const char *sigstr;
1048	int done;
1049	int stopped;
1050	int sig;
1051	int coredump;
1052	int wflags;
1053	int restore_sigchld;
1054
1055	TRACE(("dowait(%d, %p) called\n", mode, job));
1056	restore_sigchld = 0;
1057	if ((mode & DOWAIT_SIG) != 0) {
1058		sigfillset(&mask);
1059		sigprocmask(SIG_BLOCK, &mask, &omask);
1060		INTOFF;
1061		if (!issigchldtrapped()) {
1062			restore_sigchld = 1;
1063			sa.sa_handler = dummy_handler;
1064			sa.sa_flags = 0;
1065			sigemptyset(&sa.sa_mask);
1066			sigaction(SIGCHLD, &sa, &osa);
1067		}
1068	}
1069	do {
1070#if JOBS
1071		if (iflag)
1072			wflags = WUNTRACED | WCONTINUED;
1073		else
1074#endif
1075			wflags = 0;
1076		if ((mode & (DOWAIT_BLOCK | DOWAIT_SIG)) != DOWAIT_BLOCK)
1077			wflags |= WNOHANG;
1078		pid = wait3(&status, wflags, (struct rusage *)NULL);
1079		TRACE(("wait returns %d, status=%d\n", (int)pid, status));
1080		if (pid == 0 && (mode & DOWAIT_SIG) != 0) {
1081			pid = -1;
1082			if (((mode & DOWAIT_SIG_ANY) != 0 ?
1083			    pendingsig : pendingsig_waitcmd) != 0) {
1084				errno = EINTR;
1085				break;
1086			}
1087			sigsuspend(&omask);
1088			if (int_pending())
1089				break;
1090		}
1091	} while (pid == -1 && errno == EINTR);
1092	if (pid == -1 && errno == ECHILD && job != NULL)
1093		job->state = JOBDONE;
1094	if ((mode & DOWAIT_SIG) != 0) {
1095		if (restore_sigchld)
1096			sigaction(SIGCHLD, &osa, NULL);
1097		sigprocmask(SIG_SETMASK, &omask, NULL);
1098		INTON;
1099	}
1100	if (pid <= 0)
1101		return pid;
1102	INTOFF;
1103	thisjob = NULL;
1104	for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
1105		if (jp->used && jp->nprocs > 0) {
1106			done = 1;
1107			stopped = 1;
1108			for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
1109				if (sp->pid == -1)
1110					continue;
1111				if (sp->pid == pid) {
1112					TRACE(("Changing status of proc %d from 0x%x to 0x%x\n",
1113						   (int)pid, sp->status,
1114						   status));
1115					if (WIFCONTINUED(status)) {
1116						sp->status = -1;
1117						jp->state = 0;
1118					} else
1119						sp->status = status;
1120					thisjob = jp;
1121				}
1122				if (sp->status == -1)
1123					stopped = 0;
1124				else if (WIFSTOPPED(sp->status))
1125					done = 0;
1126			}
1127			if (stopped) {		/* stopped or done */
1128				int state = done? JOBDONE : JOBSTOPPED;
1129				if (jp->state != state) {
1130					TRACE(("Job %td: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
1131					jp->state = state;
1132					if (jp != job) {
1133						if (done && !jp->remembered &&
1134						    !iflag && jp != bgjob)
1135							freejob(jp);
1136#if JOBS
1137						else if (done)
1138							deljob(jp);
1139#endif
1140					}
1141				}
1142			}
1143		}
1144	}
1145	INTON;
1146	if (!thisjob || thisjob->state == 0)
1147		;
1148	else if ((!rootshell || !iflag || thisjob == job) &&
1149	    thisjob->foreground && thisjob->state != JOBSTOPPED) {
1150		sig = 0;
1151		coredump = 0;
1152		for (sp = thisjob->ps; sp < thisjob->ps + thisjob->nprocs; sp++)
1153			if (WIFSIGNALED(sp->status)) {
1154				sig = WTERMSIG(sp->status);
1155				coredump = WCOREDUMP(sp->status);
1156			}
1157		if (sig > 0 && sig != SIGINT && sig != SIGPIPE) {
1158			sigstr = strsignal(sig);
1159			if (sigstr != NULL)
1160				out2str(sigstr);
1161			else
1162				out2str("Unknown signal");
1163			if (coredump)
1164				out2str(" (core dumped)");
1165			out2c('\n');
1166			flushout(out2);
1167		}
1168	} else {
1169		TRACE(("Not printing status, rootshell=%d, job=%p\n", rootshell, job));
1170		thisjob->changed = 1;
1171	}
1172	return pid;
1173}
1174
1175
1176
1177/*
1178 * return 1 if there are stopped jobs, otherwise 0
1179 */
1180int job_warning = 0;
1181int
1182stoppedjobs(void)
1183{
1184	int jobno;
1185	struct job *jp;
1186
1187	if (job_warning)
1188		return (0);
1189	for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
1190		if (jp->used == 0)
1191			continue;
1192		if (jp->state == JOBSTOPPED) {
1193			out2fmt_flush("You have stopped jobs.\n");
1194			job_warning = 2;
1195			return (1);
1196		}
1197	}
1198
1199	return (0);
1200}
1201
1202
1203static void
1204checkzombies(void)
1205{
1206	while (njobs > 0 && dowait(0, NULL) > 0)
1207		;
1208}
1209
1210
1211int
1212backgndpidset(void)
1213{
1214	return backgndpid != -1;
1215}
1216
1217
1218pid_t
1219backgndpidval(void)
1220{
1221	if (bgjob != NULL && !forcelocal)
1222		bgjob->remembered = 1;
1223	return backgndpid;
1224}
1225
1226/*
1227 * Return a string identifying a command (to be printed by the
1228 * jobs command.
1229 */
1230
1231static char *cmdnextc;
1232static int cmdnleft;
1233#define MAXCMDTEXT	200
1234
1235char *
1236commandtext(union node *n)
1237{
1238	char *name;
1239
1240	cmdnextc = name = ckmalloc(MAXCMDTEXT);
1241	cmdnleft = MAXCMDTEXT - 4;
1242	cmdtxt(n);
1243	*cmdnextc = '\0';
1244	return name;
1245}
1246
1247
1248static void
1249cmdtxt(union node *n)
1250{
1251	union node *np;
1252	struct nodelist *lp;
1253	const char *p;
1254	int i;
1255	char s[2];
1256
1257	if (n == NULL)
1258		return;
1259	switch (n->type) {
1260	case NSEMI:
1261		cmdtxt(n->nbinary.ch1);
1262		cmdputs("; ");
1263		cmdtxt(n->nbinary.ch2);
1264		break;
1265	case NAND:
1266		cmdtxt(n->nbinary.ch1);
1267		cmdputs(" && ");
1268		cmdtxt(n->nbinary.ch2);
1269		break;
1270	case NOR:
1271		cmdtxt(n->nbinary.ch1);
1272		cmdputs(" || ");
1273		cmdtxt(n->nbinary.ch2);
1274		break;
1275	case NPIPE:
1276		for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
1277			cmdtxt(lp->n);
1278			if (lp->next)
1279				cmdputs(" | ");
1280		}
1281		break;
1282	case NSUBSHELL:
1283		cmdputs("(");
1284		cmdtxt(n->nredir.n);
1285		cmdputs(")");
1286		break;
1287	case NREDIR:
1288	case NBACKGND:
1289		cmdtxt(n->nredir.n);
1290		break;
1291	case NIF:
1292		cmdputs("if ");
1293		cmdtxt(n->nif.test);
1294		cmdputs("; then ");
1295		cmdtxt(n->nif.ifpart);
1296		cmdputs("...");
1297		break;
1298	case NWHILE:
1299		cmdputs("while ");
1300		goto until;
1301	case NUNTIL:
1302		cmdputs("until ");
1303until:
1304		cmdtxt(n->nbinary.ch1);
1305		cmdputs("; do ");
1306		cmdtxt(n->nbinary.ch2);
1307		cmdputs("; done");
1308		break;
1309	case NFOR:
1310		cmdputs("for ");
1311		cmdputs(n->nfor.var);
1312		cmdputs(" in ...");
1313		break;
1314	case NCASE:
1315		cmdputs("case ");
1316		cmdputs(n->ncase.expr->narg.text);
1317		cmdputs(" in ...");
1318		break;
1319	case NDEFUN:
1320		cmdputs(n->narg.text);
1321		cmdputs("() ...");
1322		break;
1323	case NNOT:
1324		cmdputs("! ");
1325		cmdtxt(n->nnot.com);
1326		break;
1327	case NCMD:
1328		for (np = n->ncmd.args ; np ; np = np->narg.next) {
1329			cmdtxt(np);
1330			if (np->narg.next)
1331				cmdputs(" ");
1332		}
1333		for (np = n->ncmd.redirect ; np ; np = np->nfile.next) {
1334			cmdputs(" ");
1335			cmdtxt(np);
1336		}
1337		break;
1338	case NARG:
1339		cmdputs(n->narg.text);
1340		break;
1341	case NTO:
1342		p = ">";  i = 1;  goto redir;
1343	case NAPPEND:
1344		p = ">>";  i = 1;  goto redir;
1345	case NTOFD:
1346		p = ">&";  i = 1;  goto redir;
1347	case NCLOBBER:
1348		p = ">|"; i = 1; goto redir;
1349	case NFROM:
1350		p = "<";  i = 0;  goto redir;
1351	case NFROMTO:
1352		p = "<>";  i = 0;  goto redir;
1353	case NFROMFD:
1354		p = "<&";  i = 0;  goto redir;
1355redir:
1356		if (n->nfile.fd != i) {
1357			s[0] = n->nfile.fd + '0';
1358			s[1] = '\0';
1359			cmdputs(s);
1360		}
1361		cmdputs(p);
1362		if (n->type == NTOFD || n->type == NFROMFD) {
1363			if (n->ndup.dupfd >= 0)
1364				s[0] = n->ndup.dupfd + '0';
1365			else
1366				s[0] = '-';
1367			s[1] = '\0';
1368			cmdputs(s);
1369		} else {
1370			cmdtxt(n->nfile.fname);
1371		}
1372		break;
1373	case NHERE:
1374	case NXHERE:
1375		cmdputs("<<...");
1376		break;
1377	default:
1378		cmdputs("???");
1379		break;
1380	}
1381}
1382
1383
1384
1385static void
1386cmdputs(const char *s)
1387{
1388	const char *p;
1389	char *q;
1390	char c;
1391	int subtype = 0;
1392
1393	if (cmdnleft <= 0)
1394		return;
1395	p = s;
1396	q = cmdnextc;
1397	while ((c = *p++) != '\0') {
1398		if (c == CTLESC)
1399			*q++ = *p++;
1400		else if (c == CTLVAR) {
1401			*q++ = '$';
1402			if (--cmdnleft > 0)
1403				*q++ = '{';
1404			subtype = *p++;
1405			if ((subtype & VSTYPE) == VSLENGTH && --cmdnleft > 0)
1406				*q++ = '#';
1407		} else if (c == '=' && subtype != 0) {
1408			*q = "}-+?=##%%\0X"[(subtype & VSTYPE) - VSNORMAL];
1409			if (*q)
1410				q++;
1411			else
1412				cmdnleft++;
1413			if (((subtype & VSTYPE) == VSTRIMLEFTMAX ||
1414			    (subtype & VSTYPE) == VSTRIMRIGHTMAX) &&
1415			    --cmdnleft > 0)
1416				*q = q[-1], q++;
1417			subtype = 0;
1418		} else if (c == CTLENDVAR) {
1419			*q++ = '}';
1420		} else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE) {
1421			cmdnleft -= 5;
1422			if (cmdnleft > 0) {
1423				*q++ = '$';
1424				*q++ = '(';
1425				*q++ = '.';
1426				*q++ = '.';
1427				*q++ = '.';
1428				*q++ = ')';
1429			}
1430		} else if (c == CTLARI) {
1431			cmdnleft -= 2;
1432			if (cmdnleft > 0) {
1433				*q++ = '$';
1434				*q++ = '(';
1435				*q++ = '(';
1436			}
1437			p++;
1438		} else if (c == CTLENDARI) {
1439			if (--cmdnleft > 0) {
1440				*q++ = ')';
1441				*q++ = ')';
1442			}
1443		} else if (c == CTLQUOTEMARK || c == CTLQUOTEEND)
1444			cmdnleft++; /* ignore */
1445		else
1446			*q++ = c;
1447		if (--cmdnleft <= 0) {
1448			*q++ = '.';
1449			*q++ = '.';
1450			*q++ = '.';
1451			break;
1452		}
1453	}
1454	cmdnextc = q;
1455}
1456