jobs.c revision 287750
190075Sobrien/*-
2169689Skan * Copyright (c) 1991, 1993
3169689Skan *	The Regents of the University of California.  All rights reserved.
490075Sobrien *
5132718Skan * This code is derived from software contributed to Berkeley by
690075Sobrien * Kenneth Almquist.
7132718Skan *
890075Sobrien * Redistribution and use in source and binary forms, with or without
990075Sobrien * modification, are permitted provided that the following conditions
1090075Sobrien * are met:
1190075Sobrien * 1. Redistributions of source code must retain the above copyright
12132718Skan *    notice, this list of conditions and the following disclaimer.
1390075Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1490075Sobrien *    notice, this list of conditions and the following disclaimer in the
1590075Sobrien *    documentation and/or other materials provided with the distribution.
1690075Sobrien * 4. Neither the name of the University nor the names of its contributors
1790075Sobrien *    may be used to endorse or promote products derived from this software
18132718Skan *    without specific prior written permission.
19169689Skan *
20169689Skan * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2190075Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2290075Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2390075Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2490075Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2590075Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2690075Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2790075Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2890075Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2990075Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3090075Sobrien * SUCH DAMAGE.
3190075Sobrien */
3290075Sobrien
3390075Sobrien#ifndef lint
3490075Sobrien#if 0
3590075Sobrienstatic char sccsid[] = "@(#)jobs.c	8.5 (Berkeley) 5/4/95";
3690075Sobrien#endif
3790075Sobrien#endif /* not lint */
3890075Sobrien#include <sys/cdefs.h>
3990075Sobrien__FBSDID("$FreeBSD: stable/10/bin/sh/jobs.c 287750 2015-09-13 13:43:08Z jilles $");
4090075Sobrien
4190075Sobrien#include <sys/ioctl.h>
4290075Sobrien#include <sys/param.h>
4390075Sobrien#include <sys/resource.h>
44117395Skan#include <sys/time.h>
45117395Skan#include <sys/wait.h>
4690075Sobrien#include <errno.h>
4790075Sobrien#include <fcntl.h>
4890075Sobrien#include <paths.h>
4990075Sobrien#include <signal.h>
5090075Sobrien#include <stddef.h>
5190075Sobrien#include <stdlib.h>
5290075Sobrien#include <unistd.h>
5390075Sobrien
5490075Sobrien#include "shell.h"
5590075Sobrien#if JOBS
5690075Sobrien#include <termios.h>
5790075Sobrien#undef CEOF			/* syntax.h redefines this */
58117395Skan#endif
59169689Skan#include "redir.h"
60169689Skan#include "exec.h"
61117395Skan#include "show.h"
62117395Skan#include "main.h"
63117395Skan#include "parser.h"
64117395Skan#include "nodes.h"
65117395Skan#include "jobs.h"
66117395Skan#include "options.h"
67117395Skan#include "trap.h"
68117395Skan#include "syntax.h"
69117395Skan#include "input.h"
70117395Skan#include "output.h"
71117395Skan#include "memalloc.h"
7290075Sobrien#include "error.h"
7390075Sobrien#include "mystring.h"
7490075Sobrien#include "var.h"
7590075Sobrien#include "builtins.h"
7690075Sobrien
7790075Sobrien
78132718Skanstatic struct job *jobtab;	/* array of jobs */
7990075Sobrienstatic int njobs;		/* size of array */
8090075Sobrienstatic pid_t backgndpid = -1;	/* pid of last background process */
8190075Sobrienstatic struct job *bgjob = NULL; /* last background process */
8290075Sobrien#if JOBS
8390075Sobrienstatic struct job *jobmru;	/* most recently used job list */
8490075Sobrienstatic pid_t initialpgrp;	/* pgrp of shell on invocation */
8590075Sobrien#endif
8690075Sobrienstatic int ttyfd = -1;
8790075Sobrien
8890075Sobrien/* mode flags for dowait */
8990075Sobrien#define DOWAIT_BLOCK	0x1 /* wait until a child exits */
9090075Sobrien#define DOWAIT_SIG	0x2 /* if DOWAIT_BLOCK, abort on SIGINT/SIGQUIT */
9190075Sobrien#define DOWAIT_SIG_ANY	0x4 /* if DOWAIT_SIG, abort on any signal */
9290075Sobrien
9390075Sobrien#if JOBS
9490075Sobrienstatic void restartjob(struct job *);
9590075Sobrien#endif
9690075Sobrienstatic void freejob(struct job *);
9790075Sobrienstatic int waitcmdloop(struct job *);
9890075Sobrienpid_t getjobpgrp(char *);
9990075Sobrienstatic struct job *getjob_nonotfound(const char *);
10090075Sobrienstatic struct job *getjob(const char *);
10190075Sobrienstatic pid_t dowait(int, struct job *);
10290075Sobrienstatic void checkzombies(void);
10390075Sobrienstatic void cmdtxt(union node *);
10490075Sobrienstatic void cmdputs(const char *);
10590075Sobrien#if JOBS
10690075Sobrienstatic void setcurjob(struct job *);
10790075Sobrienstatic void deljob(struct job *);
10890075Sobrienstatic struct job *getcurjob(struct job *);
10990075Sobrien#endif
11090075Sobrienstatic void printjobcmd(struct job *);
11190075Sobrienstatic void showjob(struct job *, int);
11290075Sobrien
11390075Sobrien
11490075Sobrien/*
11590075Sobrien * Turn job control on and off.
11690075Sobrien */
11790075Sobrien
11890075Sobrienstatic int jobctl;
11990075Sobrien
12090075Sobrien#if JOBS
12190075Sobrienvoid
12290075Sobriensetjobctl(int on)
12390075Sobrien{
12490075Sobrien	int i;
12590075Sobrien
12690075Sobrien	if (on == jobctl || rootshell == 0)
12790075Sobrien		return;
12890075Sobrien	if (on) {
12990075Sobrien		if (ttyfd != -1)
13090075Sobrien			close(ttyfd);
13190075Sobrien		if ((ttyfd = open(_PATH_TTY, O_RDWR | O_CLOEXEC)) < 0) {
13290075Sobrien			i = 0;
13390075Sobrien			while (i <= 2 && !isatty(i))
13490075Sobrien				i++;
13590075Sobrien			if (i > 2 ||
13690075Sobrien			    (ttyfd = fcntl(i, F_DUPFD_CLOEXEC, 10)) < 0)
13790075Sobrien				goto out;
13890075Sobrien		}
13990075Sobrien		if (ttyfd < 10) {
14090075Sobrien			/*
14190075Sobrien			 * Keep our TTY file descriptor out of the way of
14290075Sobrien			 * the user's redirections.
14390075Sobrien			 */
14490075Sobrien			if ((i = fcntl(ttyfd, F_DUPFD_CLOEXEC, 10)) < 0) {
14590075Sobrien				close(ttyfd);
14690075Sobrien				ttyfd = -1;
14790075Sobrien				goto out;
14890075Sobrien			}
14990075Sobrien			close(ttyfd);
15090075Sobrien			ttyfd = i;
15190075Sobrien		}
15290075Sobrien		do { /* while we are in the background */
15390075Sobrien			initialpgrp = tcgetpgrp(ttyfd);
15490075Sobrien			if (initialpgrp < 0) {
15590075Sobrienout:				out2fmt_flush("sh: can't access tty; job control turned off\n");
15690075Sobrien				mflag = 0;
15790075Sobrien				return;
15890075Sobrien			}
15990075Sobrien			if (initialpgrp != getpgrp()) {
16090075Sobrien				kill(0, SIGTTIN);
16190075Sobrien				continue;
16290075Sobrien			}
16390075Sobrien		} while (0);
16490075Sobrien		setsignal(SIGTSTP);
16590075Sobrien		setsignal(SIGTTOU);
16690075Sobrien		setsignal(SIGTTIN);
16790075Sobrien		setpgid(0, rootpid);
16890075Sobrien		tcsetpgrp(ttyfd, rootpid);
16990075Sobrien	} else { /* turning job control off */
17090075Sobrien		setpgid(0, initialpgrp);
17190075Sobrien		tcsetpgrp(ttyfd, initialpgrp);
17290075Sobrien		close(ttyfd);
17390075Sobrien		ttyfd = -1;
17490075Sobrien		setsignal(SIGTSTP);
17590075Sobrien		setsignal(SIGTTOU);
17690075Sobrien		setsignal(SIGTTIN);
17790075Sobrien	}
17890075Sobrien	jobctl = on;
17990075Sobrien}
18090075Sobrien#endif
18190075Sobrien
18290075Sobrien
18390075Sobrien#if JOBS
18490075Sobrienint
18590075Sobrienfgcmd(int argc __unused, char **argv __unused)
18690075Sobrien{
18790075Sobrien	struct job *jp;
18890075Sobrien	pid_t pgrp;
18990075Sobrien	int status;
19090075Sobrien
19190075Sobrien	nextopt("");
19290075Sobrien	jp = getjob(*argptr);
19390075Sobrien	if (jp->jobctl == 0)
19490075Sobrien		error("job not created under job control");
19590075Sobrien	printjobcmd(jp);
19690075Sobrien	flushout(&output);
19790075Sobrien	pgrp = jp->ps[0].pid;
19890075Sobrien	tcsetpgrp(ttyfd, pgrp);
19990075Sobrien	restartjob(jp);
20090075Sobrien	jp->foreground = 1;
20190075Sobrien	INTOFF;
20290075Sobrien	status = waitforjob(jp, (int *)NULL);
20390075Sobrien	INTON;
20490075Sobrien	return status;
20590075Sobrien}
20690075Sobrien
20790075Sobrien
20890075Sobrienint
20990075Sobrienbgcmd(int argc, char **argv)
21090075Sobrien{
21190075Sobrien	struct job *jp;
21290075Sobrien
21390075Sobrien	nextopt("");
21490075Sobrien	do {
21590075Sobrien		jp = getjob(*argptr);
21690075Sobrien		if (jp->jobctl == 0)
21790075Sobrien			error("job not created under job control");
21890075Sobrien		if (jp->state == JOBDONE)
21990075Sobrien			continue;
22090075Sobrien		restartjob(jp);
22190075Sobrien		jp->foreground = 0;
22290075Sobrien		out1fmt("[%td] ", jp - jobtab + 1);
22390075Sobrien		printjobcmd(jp);
22490075Sobrien	} while (*argptr != NULL && *++argptr != NULL);
22590075Sobrien	return 0;
22690075Sobrien}
22790075Sobrien
22890075Sobrien
22990075Sobrienstatic void
23090075Sobrienrestartjob(struct job *jp)
23190075Sobrien{
23290075Sobrien	struct procstat *ps;
23390075Sobrien	int i;
234169689Skan
235169689Skan	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 ; procno > 0 ; ps++, procno--) { /* for each process */
351		if (mode == SHOWJOBS_PIDS || mode == SHOWJOBS_PGIDS) {
352			out1fmt("%d\n", (int)ps->pid);
353			continue;
354		}
355		if (mode != SHOWJOBS_VERBOSE && ps != jp->ps)
356			continue;
357		if (jobno == curr && ps == jp->ps)
358			c = '+';
359		else if (jobno == prev && ps == jp->ps)
360			c = '-';
361		else
362			c = ' ';
363		if (ps == jp->ps)
364			fmtstr(s, 64, "[%d] %c ", jobno, c);
365		else
366			fmtstr(s, 64, "    %c ", c);
367		out1str(s);
368		col = strlen(s);
369		if (mode == SHOWJOBS_VERBOSE) {
370			fmtstr(s, 64, "%d ", (int)ps->pid);
371			out1str(s);
372			col += strlen(s);
373		}
374		if (ps == jp->ps) {
375			out1str(statestr);
376			col += strlen(statestr);
377		}
378		do {
379			out1c(' ');
380			col++;
381		} while (col < 30);
382		if (mode == SHOWJOBS_VERBOSE) {
383			out1str(ps->cmd);
384			out1c('\n');
385		} else
386			printjobcmd(jp);
387	}
388}
389
390/*
391 * Print a list of jobs.  If "change" is nonzero, only print jobs whose
392 * statuses have changed since the last call to showjobs.
393 *
394 * If the shell is interrupted in the process of creating a job, the
395 * result may be a job structure containing zero processes.  Such structures
396 * will be freed here.
397 */
398
399void
400showjobs(int change, int mode)
401{
402	int jobno;
403	struct job *jp;
404
405	TRACE(("showjobs(%d) called\n", change));
406	checkzombies();
407	for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
408		if (! jp->used)
409			continue;
410		if (jp->nprocs == 0) {
411			freejob(jp);
412			continue;
413		}
414		if (change && ! jp->changed)
415			continue;
416		showjob(jp, mode);
417		if (mode == SHOWJOBS_DEFAULT || mode == SHOWJOBS_VERBOSE) {
418			jp->changed = 0;
419			/* Hack: discard jobs for which $! has not been
420			 * referenced in interactive mode when they terminate.
421			 */
422			if (jp->state == JOBDONE && !jp->remembered &&
423					(iflag || jp != bgjob)) {
424				freejob(jp);
425			}
426		}
427	}
428}
429
430
431/*
432 * Mark a job structure as unused.
433 */
434
435static void
436freejob(struct job *jp)
437{
438	struct procstat *ps;
439	int i;
440
441	INTOFF;
442	if (bgjob == jp)
443		bgjob = NULL;
444	for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
445		if (ps->cmd != nullstr)
446			ckfree(ps->cmd);
447	}
448	if (jp->ps != &jp->ps0)
449		ckfree(jp->ps);
450	jp->used = 0;
451#if JOBS
452	deljob(jp);
453#endif
454	INTON;
455}
456
457
458
459int
460waitcmd(int argc __unused, char **argv __unused)
461{
462	struct job *job;
463	int retval;
464
465	nextopt("");
466	if (*argptr == NULL)
467		return (waitcmdloop(NULL));
468
469	do {
470		job = getjob_nonotfound(*argptr);
471		if (job == NULL)
472			retval = 127;
473		else
474			retval = waitcmdloop(job);
475		argptr++;
476	} while (*argptr != NULL);
477
478	return (retval);
479}
480
481static int
482waitcmdloop(struct job *job)
483{
484	int status, retval, sig;
485	struct job *jp;
486
487	/*
488	 * Loop until a process is terminated or stopped, or a SIGINT is
489	 * received.
490	 */
491
492	do {
493		if (job != NULL) {
494			if (job->state == JOBDONE) {
495				status = job->ps[job->nprocs - 1].status;
496				if (WIFEXITED(status))
497					retval = WEXITSTATUS(status);
498				else
499					retval = WTERMSIG(status) + 128;
500				if (! iflag || ! job->changed)
501					freejob(job);
502				else {
503					job->remembered = 0;
504					if (job == bgjob)
505						bgjob = NULL;
506				}
507				return retval;
508			}
509		} else {
510			for (jp = jobtab ; jp < jobtab + njobs; jp++)
511				if (jp->used && jp->state == JOBDONE) {
512					if (! iflag || ! jp->changed)
513						freejob(jp);
514					else {
515						jp->remembered = 0;
516						if (jp == bgjob)
517							bgjob = NULL;
518					}
519				}
520			for (jp = jobtab ; ; jp++) {
521				if (jp >= jobtab + njobs) {	/* no running procs */
522					return 0;
523				}
524				if (jp->used && jp->state == 0)
525					break;
526			}
527		}
528	} while (dowait(DOWAIT_BLOCK | DOWAIT_SIG, (struct job *)NULL) != -1);
529
530	sig = pendingsig_waitcmd;
531	pendingsig_waitcmd = 0;
532	return sig + 128;
533}
534
535
536
537int
538jobidcmd(int argc __unused, char **argv __unused)
539{
540	struct job *jp;
541	int i;
542
543	nextopt("");
544	jp = getjob(*argptr);
545	for (i = 0 ; i < jp->nprocs ; ) {
546		out1fmt("%d", (int)jp->ps[i].pid);
547		out1c(++i < jp->nprocs? ' ' : '\n');
548	}
549	return 0;
550}
551
552
553
554/*
555 * Convert a job name to a job structure.
556 */
557
558static struct job *
559getjob_nonotfound(const char *name)
560{
561	int jobno;
562	struct job *found, *jp;
563	pid_t pid;
564	int i;
565
566	if (name == NULL) {
567#if JOBS
568currentjob:	if ((jp = getcurjob(NULL)) == NULL)
569			error("No current job");
570		return (jp);
571#else
572		error("No current job");
573#endif
574	} else if (name[0] == '%') {
575		if (is_digit(name[1])) {
576			jobno = number(name + 1);
577			if (jobno > 0 && jobno <= njobs
578			 && jobtab[jobno - 1].used != 0)
579				return &jobtab[jobno - 1];
580#if JOBS
581		} else if (name[1] == '%' && name[2] == '\0') {
582			goto currentjob;
583		} else if (name[1] == '+' && name[2] == '\0') {
584			goto currentjob;
585		} else if (name[1] == '-' && name[2] == '\0') {
586			if ((jp = getcurjob(NULL)) == NULL ||
587			    (jp = getcurjob(jp)) == NULL)
588				error("No previous job");
589			return (jp);
590#endif
591		} else if (name[1] == '?') {
592			found = NULL;
593			for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
594				if (jp->used && jp->nprocs > 0
595				 && strstr(jp->ps[0].cmd, name + 2) != NULL) {
596					if (found)
597						error("%s: ambiguous", name);
598					found = jp;
599				}
600			}
601			if (found != NULL)
602				return (found);
603		} else {
604			found = NULL;
605			for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
606				if (jp->used && jp->nprocs > 0
607				 && prefix(name + 1, jp->ps[0].cmd)) {
608					if (found)
609						error("%s: ambiguous", name);
610					found = jp;
611				}
612			}
613			if (found)
614				return found;
615		}
616	} else if (is_number(name)) {
617		pid = (pid_t)number(name);
618		for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
619			if (jp->used && jp->nprocs > 0
620			 && jp->ps[jp->nprocs - 1].pid == pid)
621				return jp;
622		}
623	}
624	return NULL;
625}
626
627
628static struct job *
629getjob(const char *name)
630{
631	struct job *jp;
632
633	jp = getjob_nonotfound(name);
634	if (jp == NULL)
635		error("No such job: %s", name);
636	return (jp);
637}
638
639
640pid_t
641getjobpgrp(char *name)
642{
643	struct job *jp;
644
645	jp = getjob(name);
646	return -jp->ps[0].pid;
647}
648
649/*
650 * Return a new job structure,
651 */
652
653struct job *
654makejob(union node *node __unused, int nprocs)
655{
656	int i;
657	struct job *jp;
658
659	for (i = njobs, jp = jobtab ; ; jp++) {
660		if (--i < 0) {
661			INTOFF;
662			if (njobs == 0) {
663				jobtab = ckmalloc(4 * sizeof jobtab[0]);
664#if JOBS
665				jobmru = NULL;
666#endif
667			} else {
668				jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
669				memcpy(jp, jobtab, njobs * sizeof jp[0]);
670#if JOBS
671				/* Relocate `next' pointers and list head */
672				if (jobmru != NULL)
673					jobmru = &jp[jobmru - jobtab];
674				for (i = 0; i < njobs; i++)
675					if (jp[i].next != NULL)
676						jp[i].next = &jp[jp[i].next -
677						    jobtab];
678#endif
679				if (bgjob != NULL)
680					bgjob = &jp[bgjob - jobtab];
681				/* Relocate `ps' pointers */
682				for (i = 0; i < njobs; i++)
683					if (jp[i].ps == &jobtab[i].ps0)
684						jp[i].ps = &jp[i].ps0;
685				ckfree(jobtab);
686				jobtab = jp;
687			}
688			jp = jobtab + njobs;
689			for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0)
690				;
691			INTON;
692			break;
693		}
694		if (jp->used == 0)
695			break;
696	}
697	INTOFF;
698	jp->state = 0;
699	jp->used = 1;
700	jp->changed = 0;
701	jp->nprocs = 0;
702	jp->foreground = 0;
703	jp->remembered = 0;
704#if JOBS
705	jp->jobctl = jobctl;
706	jp->next = NULL;
707#endif
708	if (nprocs > 1) {
709		jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
710	} else {
711		jp->ps = &jp->ps0;
712	}
713	INTON;
714	TRACE(("makejob(%p, %d) returns %%%td\n", (void *)node, nprocs,
715	    jp - jobtab + 1));
716	return jp;
717}
718
719#if JOBS
720static void
721setcurjob(struct job *cj)
722{
723	struct job *jp, *prev;
724
725	for (prev = NULL, jp = jobmru; jp != NULL; prev = jp, jp = jp->next) {
726		if (jp == cj) {
727			if (prev != NULL)
728				prev->next = jp->next;
729			else
730				jobmru = jp->next;
731			jp->next = jobmru;
732			jobmru = cj;
733			return;
734		}
735	}
736	cj->next = jobmru;
737	jobmru = cj;
738}
739
740static void
741deljob(struct job *j)
742{
743	struct job *jp, *prev;
744
745	for (prev = NULL, jp = jobmru; jp != NULL; prev = jp, jp = jp->next) {
746		if (jp == j) {
747			if (prev != NULL)
748				prev->next = jp->next;
749			else
750				jobmru = jp->next;
751			return;
752		}
753	}
754}
755
756/*
757 * Return the most recently used job that isn't `nj', and preferably one
758 * that is stopped.
759 */
760static struct job *
761getcurjob(struct job *nj)
762{
763	struct job *jp;
764
765	/* Try to find a stopped one.. */
766	for (jp = jobmru; jp != NULL; jp = jp->next)
767		if (jp->used && jp != nj && jp->state == JOBSTOPPED)
768			return (jp);
769	/* Otherwise the most recently used job that isn't `nj' */
770	for (jp = jobmru; jp != NULL; jp = jp->next)
771		if (jp->used && jp != nj)
772			return (jp);
773
774	return (NULL);
775}
776
777#endif
778
779/*
780 * Fork of a subshell.  If we are doing job control, give the subshell its
781 * own process group.  Jp is a job structure that the job is to be added to.
782 * N is the command that will be evaluated by the child.  Both jp and n may
783 * be NULL.  The mode parameter can be one of the following:
784 *	FORK_FG - Fork off a foreground process.
785 *	FORK_BG - Fork off a background process.
786 *	FORK_NOJOB - Like FORK_FG, but don't give the process its own
787 *		     process group even if job control is on.
788 *
789 * When job control is turned off, background processes have their standard
790 * input redirected to /dev/null (except for the second and later processes
791 * in a pipeline).
792 */
793
794pid_t
795forkshell(struct job *jp, union node *n, int mode)
796{
797	pid_t pid;
798	pid_t pgrp;
799
800	TRACE(("forkshell(%%%td, %p, %d) called\n", jp - jobtab, (void *)n,
801	    mode));
802	INTOFF;
803	if (mode == FORK_BG && (jp == NULL || jp->nprocs == 0))
804		checkzombies();
805	flushall();
806	pid = fork();
807	if (pid == -1) {
808		TRACE(("Fork failed, errno=%d\n", errno));
809		INTON;
810		error("Cannot fork: %s", strerror(errno));
811	}
812	if (pid == 0) {
813		struct job *p;
814		int wasroot;
815		int i;
816
817		TRACE(("Child shell %d\n", (int)getpid()));
818		wasroot = rootshell;
819		rootshell = 0;
820		handler = &main_handler;
821		closescript();
822		INTON;
823		forcelocal = 0;
824		clear_traps();
825#if JOBS
826		jobctl = 0;		/* do job control only in root shell */
827		if (wasroot && mode != FORK_NOJOB && mflag) {
828			if (jp == NULL || jp->nprocs == 0)
829				pgrp = getpid();
830			else
831				pgrp = jp->ps[0].pid;
832			if (setpgid(0, pgrp) == 0 && mode == FORK_FG) {
833				/*** this causes superfluous TIOCSPGRPS ***/
834				if (tcsetpgrp(ttyfd, pgrp) < 0)
835					error("tcsetpgrp failed, errno=%d", errno);
836			}
837			setsignal(SIGTSTP);
838			setsignal(SIGTTOU);
839		} else if (mode == FORK_BG) {
840			ignoresig(SIGINT);
841			ignoresig(SIGQUIT);
842			if ((jp == NULL || jp->nprocs == 0) &&
843			    ! fd0_redirected_p ()) {
844				close(0);
845				if (open(_PATH_DEVNULL, O_RDONLY) != 0)
846					error("cannot open %s: %s",
847					    _PATH_DEVNULL, strerror(errno));
848			}
849		}
850#else
851		if (mode == FORK_BG) {
852			ignoresig(SIGINT);
853			ignoresig(SIGQUIT);
854			if ((jp == NULL || jp->nprocs == 0) &&
855			    ! fd0_redirected_p ()) {
856				close(0);
857				if (open(_PATH_DEVNULL, O_RDONLY) != 0)
858					error("cannot open %s: %s",
859					    _PATH_DEVNULL, strerror(errno));
860			}
861		}
862#endif
863		INTOFF;
864		for (i = njobs, p = jobtab ; --i >= 0 ; p++)
865			if (p->used)
866				freejob(p);
867		INTON;
868		if (wasroot && iflag) {
869			setsignal(SIGINT);
870			setsignal(SIGQUIT);
871			setsignal(SIGTERM);
872		}
873		return pid;
874	}
875	if (rootshell && mode != FORK_NOJOB && mflag) {
876		if (jp == NULL || jp->nprocs == 0)
877			pgrp = pid;
878		else
879			pgrp = jp->ps[0].pid;
880		setpgid(pid, pgrp);
881	}
882	if (mode == FORK_BG) {
883		if (bgjob != NULL && bgjob->state == JOBDONE &&
884		    !bgjob->remembered && !iflag)
885			freejob(bgjob);
886		backgndpid = pid;		/* set $! */
887		bgjob = jp;
888	}
889	if (jp) {
890		struct procstat *ps = &jp->ps[jp->nprocs++];
891		ps->pid = pid;
892		ps->status = -1;
893		ps->cmd = nullstr;
894		if (iflag && rootshell && n)
895			ps->cmd = commandtext(n);
896		jp->foreground = mode == FORK_FG;
897#if JOBS
898		setcurjob(jp);
899#endif
900	}
901	INTON;
902	TRACE(("In parent shell:  child = %d\n", (int)pid));
903	return pid;
904}
905
906
907pid_t
908vforkexecshell(struct job *jp, char **argv, char **envp, const char *path, int idx, int pip[2])
909{
910	pid_t pid;
911	struct jmploc jmploc;
912	struct jmploc *savehandler;
913
914	TRACE(("vforkexecshell(%%%td, %s, %p) called\n", jp - jobtab, argv[0],
915	    (void *)pip));
916	INTOFF;
917	flushall();
918	savehandler = handler;
919	pid = vfork();
920	if (pid == -1) {
921		TRACE(("Vfork failed, errno=%d\n", errno));
922		INTON;
923		error("Cannot fork: %s", strerror(errno));
924	}
925	if (pid == 0) {
926		TRACE(("Child shell %d\n", (int)getpid()));
927		if (setjmp(jmploc.loc))
928			_exit(exception == EXEXEC ? exerrno : 2);
929		if (pip != NULL) {
930			close(pip[0]);
931			if (pip[1] != 1) {
932				dup2(pip[1], 1);
933				close(pip[1]);
934			}
935		}
936		handler = &jmploc;
937		shellexec(argv, envp, path, idx);
938	}
939	handler = savehandler;
940	if (jp) {
941		struct procstat *ps = &jp->ps[jp->nprocs++];
942		ps->pid = pid;
943		ps->status = -1;
944		ps->cmd = nullstr;
945		jp->foreground = 1;
946#if JOBS
947		setcurjob(jp);
948#endif
949	}
950	INTON;
951	TRACE(("In parent shell:  child = %d\n", (int)pid));
952	return pid;
953}
954
955
956/*
957 * Wait for job to finish.
958 *
959 * Under job control we have the problem that while a child process is
960 * running interrupts generated by the user are sent to the child but not
961 * to the shell.  This means that an infinite loop started by an inter-
962 * active user may be hard to kill.  With job control turned off, an
963 * interactive user may place an interactive program inside a loop.  If
964 * the interactive program catches interrupts, the user doesn't want
965 * these interrupts to also abort the loop.  The approach we take here
966 * is to have the shell ignore interrupt signals while waiting for a
967 * foreground process to terminate, and then send itself an interrupt
968 * signal if the child process was terminated by an interrupt signal.
969 * Unfortunately, some programs want to do a bit of cleanup and then
970 * exit on interrupt; unless these processes terminate themselves by
971 * sending a signal to themselves (instead of calling exit) they will
972 * confuse this approach.
973 */
974
975int
976waitforjob(struct job *jp, int *origstatus)
977{
978#if JOBS
979	int propagate_int = jp->jobctl && jp->foreground;
980#endif
981	int status;
982	int st;
983
984	INTOFF;
985	TRACE(("waitforjob(%%%td) called\n", jp - jobtab + 1));
986	while (jp->state == 0)
987		if (dowait(DOWAIT_BLOCK | (Tflag ? DOWAIT_SIG |
988		    DOWAIT_SIG_ANY : 0), jp) == -1)
989			dotrap();
990#if JOBS
991	if (jp->jobctl) {
992		if (tcsetpgrp(ttyfd, rootpid) < 0)
993			error("tcsetpgrp failed, errno=%d\n", errno);
994	}
995	if (jp->state == JOBSTOPPED)
996		setcurjob(jp);
997#endif
998	status = jp->ps[jp->nprocs - 1].status;
999	if (origstatus != NULL)
1000		*origstatus = status;
1001	/* convert to 8 bits */
1002	if (WIFEXITED(status))
1003		st = WEXITSTATUS(status);
1004#if JOBS
1005	else if (WIFSTOPPED(status))
1006		st = WSTOPSIG(status) + 128;
1007#endif
1008	else
1009		st = WTERMSIG(status) + 128;
1010	if (! JOBS || jp->state == JOBDONE)
1011		freejob(jp);
1012	if (int_pending()) {
1013		if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGINT)
1014			CLEAR_PENDING_INT;
1015	}
1016#if JOBS
1017	else if (rootshell && iflag && propagate_int &&
1018			WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
1019		kill(getpid(), SIGINT);
1020#endif
1021	INTON;
1022	return st;
1023}
1024
1025
1026static void
1027dummy_handler(int sig __unused)
1028{
1029}
1030
1031/*
1032 * Wait for a process to terminate.
1033 */
1034
1035static pid_t
1036dowait(int mode, struct job *job)
1037{
1038	struct sigaction sa, osa;
1039	sigset_t mask, omask;
1040	pid_t pid;
1041	int status;
1042	struct procstat *sp;
1043	struct job *jp;
1044	struct job *thisjob;
1045	const char *sigstr;
1046	int done;
1047	int stopped;
1048	int sig;
1049	int coredump;
1050	int wflags;
1051	int restore_sigchld;
1052
1053	TRACE(("dowait(%d, %p) called\n", mode, job));
1054	restore_sigchld = 0;
1055	if ((mode & DOWAIT_SIG) != 0) {
1056		sigfillset(&mask);
1057		sigprocmask(SIG_BLOCK, &mask, &omask);
1058		INTOFF;
1059		if (!issigchldtrapped()) {
1060			restore_sigchld = 1;
1061			sa.sa_handler = dummy_handler;
1062			sa.sa_flags = 0;
1063			sigemptyset(&sa.sa_mask);
1064			sigaction(SIGCHLD, &sa, &osa);
1065		}
1066	}
1067	do {
1068#if JOBS
1069		if (iflag)
1070			wflags = WUNTRACED | WCONTINUED;
1071		else
1072#endif
1073			wflags = 0;
1074		if ((mode & (DOWAIT_BLOCK | DOWAIT_SIG)) != DOWAIT_BLOCK)
1075			wflags |= WNOHANG;
1076		pid = wait3(&status, wflags, (struct rusage *)NULL);
1077		TRACE(("wait returns %d, status=%d\n", (int)pid, status));
1078		if (pid == 0 && (mode & DOWAIT_SIG) != 0) {
1079			pid = -1;
1080			if (((mode & DOWAIT_SIG_ANY) != 0 ?
1081			    pendingsig : pendingsig_waitcmd) != 0) {
1082				errno = EINTR;
1083				break;
1084			}
1085			sigsuspend(&omask);
1086			if (int_pending())
1087				break;
1088		}
1089	} while (pid == -1 && errno == EINTR);
1090	if (pid == -1 && errno == ECHILD && job != NULL)
1091		job->state = JOBDONE;
1092	if ((mode & DOWAIT_SIG) != 0) {
1093		if (restore_sigchld)
1094			sigaction(SIGCHLD, &osa, NULL);
1095		sigprocmask(SIG_SETMASK, &omask, NULL);
1096		INTON;
1097	}
1098	if (pid <= 0)
1099		return pid;
1100	INTOFF;
1101	thisjob = NULL;
1102	for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
1103		if (jp->used && jp->nprocs > 0) {
1104			done = 1;
1105			stopped = 1;
1106			for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
1107				if (sp->pid == -1)
1108					continue;
1109				if (sp->pid == pid) {
1110					TRACE(("Changing status of proc %d from 0x%x to 0x%x\n",
1111						   (int)pid, sp->status,
1112						   status));
1113					if (WIFCONTINUED(status)) {
1114						sp->status = -1;
1115						jp->state = 0;
1116					} else
1117						sp->status = status;
1118					thisjob = jp;
1119				}
1120				if (sp->status == -1)
1121					stopped = 0;
1122				else if (WIFSTOPPED(sp->status))
1123					done = 0;
1124			}
1125			if (stopped) {		/* stopped or done */
1126				int state = done? JOBDONE : JOBSTOPPED;
1127				if (jp->state != state) {
1128					TRACE(("Job %td: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
1129					jp->state = state;
1130					if (jp != job) {
1131						if (done && !jp->remembered &&
1132						    !iflag && jp != bgjob)
1133							freejob(jp);
1134#if JOBS
1135						else if (done)
1136							deljob(jp);
1137#endif
1138					}
1139				}
1140			}
1141		}
1142	}
1143	INTON;
1144	if (!thisjob || thisjob->state == 0)
1145		;
1146	else if ((!rootshell || !iflag || thisjob == job) &&
1147	    thisjob->foreground && thisjob->state != JOBSTOPPED) {
1148		sig = 0;
1149		coredump = 0;
1150		for (sp = thisjob->ps; sp < thisjob->ps + thisjob->nprocs; sp++)
1151			if (WIFSIGNALED(sp->status)) {
1152				sig = WTERMSIG(sp->status);
1153				coredump = WCOREDUMP(sp->status);
1154			}
1155		if (sig > 0 && sig != SIGINT && sig != SIGPIPE) {
1156			sigstr = strsignal(sig);
1157			if (sigstr != NULL)
1158				out2str(sigstr);
1159			else
1160				out2str("Unknown signal");
1161			if (coredump)
1162				out2str(" (core dumped)");
1163			out2c('\n');
1164			flushout(out2);
1165		}
1166	} else {
1167		TRACE(("Not printing status, rootshell=%d, job=%p\n", rootshell, job));
1168		thisjob->changed = 1;
1169	}
1170	return pid;
1171}
1172
1173
1174
1175/*
1176 * return 1 if there are stopped jobs, otherwise 0
1177 */
1178int job_warning = 0;
1179int
1180stoppedjobs(void)
1181{
1182	int jobno;
1183	struct job *jp;
1184
1185	if (job_warning)
1186		return (0);
1187	for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
1188		if (jp->used == 0)
1189			continue;
1190		if (jp->state == JOBSTOPPED) {
1191			out2fmt_flush("You have stopped jobs.\n");
1192			job_warning = 2;
1193			return (1);
1194		}
1195	}
1196
1197	return (0);
1198}
1199
1200
1201static void
1202checkzombies(void)
1203{
1204	while (njobs > 0 && dowait(0, NULL) > 0)
1205		;
1206}
1207
1208
1209int
1210backgndpidset(void)
1211{
1212	return backgndpid != -1;
1213}
1214
1215
1216pid_t
1217backgndpidval(void)
1218{
1219	if (bgjob != NULL && !forcelocal)
1220		bgjob->remembered = 1;
1221	return backgndpid;
1222}
1223
1224/*
1225 * Return a string identifying a command (to be printed by the
1226 * jobs command.
1227 */
1228
1229static char *cmdnextc;
1230static int cmdnleft;
1231#define MAXCMDTEXT	200
1232
1233char *
1234commandtext(union node *n)
1235{
1236	char *name;
1237
1238	cmdnextc = name = ckmalloc(MAXCMDTEXT);
1239	cmdnleft = MAXCMDTEXT - 4;
1240	cmdtxt(n);
1241	*cmdnextc = '\0';
1242	return name;
1243}
1244
1245
1246static void
1247cmdtxt(union node *n)
1248{
1249	union node *np;
1250	struct nodelist *lp;
1251	const char *p;
1252	int i;
1253	char s[2];
1254
1255	if (n == NULL)
1256		return;
1257	switch (n->type) {
1258	case NSEMI:
1259		cmdtxt(n->nbinary.ch1);
1260		cmdputs("; ");
1261		cmdtxt(n->nbinary.ch2);
1262		break;
1263	case NAND:
1264		cmdtxt(n->nbinary.ch1);
1265		cmdputs(" && ");
1266		cmdtxt(n->nbinary.ch2);
1267		break;
1268	case NOR:
1269		cmdtxt(n->nbinary.ch1);
1270		cmdputs(" || ");
1271		cmdtxt(n->nbinary.ch2);
1272		break;
1273	case NPIPE:
1274		for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
1275			cmdtxt(lp->n);
1276			if (lp->next)
1277				cmdputs(" | ");
1278		}
1279		break;
1280	case NSUBSHELL:
1281		cmdputs("(");
1282		cmdtxt(n->nredir.n);
1283		cmdputs(")");
1284		break;
1285	case NREDIR:
1286	case NBACKGND:
1287		cmdtxt(n->nredir.n);
1288		break;
1289	case NIF:
1290		cmdputs("if ");
1291		cmdtxt(n->nif.test);
1292		cmdputs("; then ");
1293		cmdtxt(n->nif.ifpart);
1294		cmdputs("...");
1295		break;
1296	case NWHILE:
1297		cmdputs("while ");
1298		goto until;
1299	case NUNTIL:
1300		cmdputs("until ");
1301until:
1302		cmdtxt(n->nbinary.ch1);
1303		cmdputs("; do ");
1304		cmdtxt(n->nbinary.ch2);
1305		cmdputs("; done");
1306		break;
1307	case NFOR:
1308		cmdputs("for ");
1309		cmdputs(n->nfor.var);
1310		cmdputs(" in ...");
1311		break;
1312	case NCASE:
1313		cmdputs("case ");
1314		cmdputs(n->ncase.expr->narg.text);
1315		cmdputs(" in ...");
1316		break;
1317	case NDEFUN:
1318		cmdputs(n->narg.text);
1319		cmdputs("() ...");
1320		break;
1321	case NNOT:
1322		cmdputs("! ");
1323		cmdtxt(n->nnot.com);
1324		break;
1325	case NCMD:
1326		for (np = n->ncmd.args ; np ; np = np->narg.next) {
1327			cmdtxt(np);
1328			if (np->narg.next)
1329				cmdputs(" ");
1330		}
1331		for (np = n->ncmd.redirect ; np ; np = np->nfile.next) {
1332			cmdputs(" ");
1333			cmdtxt(np);
1334		}
1335		break;
1336	case NARG:
1337		cmdputs(n->narg.text);
1338		break;
1339	case NTO:
1340		p = ">";  i = 1;  goto redir;
1341	case NAPPEND:
1342		p = ">>";  i = 1;  goto redir;
1343	case NTOFD:
1344		p = ">&";  i = 1;  goto redir;
1345	case NCLOBBER:
1346		p = ">|"; i = 1; goto redir;
1347	case NFROM:
1348		p = "<";  i = 0;  goto redir;
1349	case NFROMTO:
1350		p = "<>";  i = 0;  goto redir;
1351	case NFROMFD:
1352		p = "<&";  i = 0;  goto redir;
1353redir:
1354		if (n->nfile.fd != i) {
1355			s[0] = n->nfile.fd + '0';
1356			s[1] = '\0';
1357			cmdputs(s);
1358		}
1359		cmdputs(p);
1360		if (n->type == NTOFD || n->type == NFROMFD) {
1361			if (n->ndup.dupfd >= 0)
1362				s[0] = n->ndup.dupfd + '0';
1363			else
1364				s[0] = '-';
1365			s[1] = '\0';
1366			cmdputs(s);
1367		} else {
1368			cmdtxt(n->nfile.fname);
1369		}
1370		break;
1371	case NHERE:
1372	case NXHERE:
1373		cmdputs("<<...");
1374		break;
1375	default:
1376		cmdputs("???");
1377		break;
1378	}
1379}
1380
1381
1382
1383static void
1384cmdputs(const char *s)
1385{
1386	const char *p;
1387	char *q;
1388	char c;
1389	int subtype = 0;
1390
1391	if (cmdnleft <= 0)
1392		return;
1393	p = s;
1394	q = cmdnextc;
1395	while ((c = *p++) != '\0') {
1396		if (c == CTLESC)
1397			*q++ = *p++;
1398		else if (c == CTLVAR) {
1399			*q++ = '$';
1400			if (--cmdnleft > 0)
1401				*q++ = '{';
1402			subtype = *p++;
1403			if ((subtype & VSTYPE) == VSLENGTH && --cmdnleft > 0)
1404				*q++ = '#';
1405		} else if (c == '=' && subtype != 0) {
1406			*q = "}-+?=##%%\0X"[(subtype & VSTYPE) - VSNORMAL];
1407			if (*q)
1408				q++;
1409			else
1410				cmdnleft++;
1411			if (((subtype & VSTYPE) == VSTRIMLEFTMAX ||
1412			    (subtype & VSTYPE) == VSTRIMRIGHTMAX) &&
1413			    --cmdnleft > 0)
1414				*q = q[-1], q++;
1415			subtype = 0;
1416		} else if (c == CTLENDVAR) {
1417			*q++ = '}';
1418		} else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE) {
1419			cmdnleft -= 5;
1420			if (cmdnleft > 0) {
1421				*q++ = '$';
1422				*q++ = '(';
1423				*q++ = '.';
1424				*q++ = '.';
1425				*q++ = '.';
1426				*q++ = ')';
1427			}
1428		} else if (c == CTLARI) {
1429			cmdnleft -= 2;
1430			if (cmdnleft > 0) {
1431				*q++ = '$';
1432				*q++ = '(';
1433				*q++ = '(';
1434			}
1435			p++;
1436		} else if (c == CTLENDARI) {
1437			if (--cmdnleft > 0) {
1438				*q++ = ')';
1439				*q++ = ')';
1440			}
1441		} else if (c == CTLQUOTEMARK || c == CTLQUOTEEND)
1442			cmdnleft++; /* ignore */
1443		else
1444			*q++ = c;
1445		if (--cmdnleft <= 0) {
1446			*q++ = '.';
1447			*q++ = '.';
1448			*q++ = '.';
1449			break;
1450		}
1451	}
1452	cmdnextc = q;
1453}
1454