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