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