jobs.c revision 38521
160786Sps/*-
260786Sps * Copyright (c) 1991, 1993
360786Sps *	The Regents of the University of California.  All rights reserved.
460786Sps *
560786Sps * This code is derived from software contributed to Berkeley by
660786Sps * Kenneth Almquist.
760786Sps *
860786Sps * Redistribution and use in source and binary forms, with or without
960786Sps * modification, are permitted provided that the following conditions
1060786Sps * are met:
1160786Sps * 1. Redistributions of source code must retain the above copyright
1260786Sps *    notice, this list of conditions and the following disclaimer.
1360786Sps * 2. Redistributions in binary form must reproduce the above copyright
1460786Sps *    notice, this list of conditions and the following disclaimer in the
1560786Sps *    documentation and/or other materials provided with the distribution.
1660786Sps * 3. All advertising materials mentioning features or use of this software
1760786Sps *    must display the following acknowledgement:
1860786Sps *	This product includes software developed by the University of
1960786Sps *	California, Berkeley and its contributors.
2060786Sps * 4. Neither the name of the University nor the names of its contributors
2160786Sps *    may be used to endorse or promote products derived from this software
2260786Sps *    without specific prior written permission.
2360786Sps *
2460786Sps * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2560786Sps * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2660786Sps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2760786Sps * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2860786Sps * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2960786Sps * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3060786Sps * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3160786Sps * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3260786Sps * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3360786Sps * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3460786Sps * SUCH DAMAGE.
3589019Sps */
3660786Sps
3789019Sps#ifndef lint
3860786Sps#if 0
3960786Spsstatic char sccsid[] = "@(#)jobs.c	8.5 (Berkeley) 5/4/95";
4060786Sps#endif
4160786Spsstatic const char rcsid[] =
4260786Sps	"$Id: jobs.c,v 1.20 1998/05/18 06:43:47 charnier Exp $";
4360786Sps#endif /* not lint */
4460786Sps
4589019Sps#include <fcntl.h>
4689019Sps#include <signal.h>
4789019Sps#include <errno.h>
4889019Sps#include <unistd.h>
4989019Sps#include <stdlib.h>
5089019Sps#include <sys/param.h>
5189019Sps#ifdef BSD
5289019Sps#include <sys/wait.h>
5389019Sps#include <sys/time.h>
5460786Sps#include <sys/resource.h>
5560786Sps#endif
5660786Sps#include <sys/ioctl.h>
5760786Sps
5860786Sps#include "shell.h"
5960786Sps#if JOBS
6060786Sps#if OLD_TTY_DRIVER
6160786Sps#include "sgtty.h"
6260786Sps#else
6360786Sps#include <termios.h>
6460786Sps#endif
6560786Sps#undef CEOF			/* syntax.h redefines this */
6660786Sps#endif
6760786Sps#include "redir.h"
6860786Sps#include "show.h"
6960786Sps#include "main.h"
7060786Sps#include "parser.h"
7160786Sps#include "nodes.h"
7260786Sps#include "jobs.h"
7360786Sps#include "options.h"
7460786Sps#include "trap.h"
7560786Sps#include "syntax.h"
7660786Sps#include "input.h"
7760786Sps#include "output.h"
7860786Sps#include "memalloc.h"
7960786Sps#include "error.h"
8060786Sps#include "mystring.h"
8160786Sps
8260786Sps
8360786Spsstruct job *jobtab;		/* array of jobs */
8460786Spsint njobs;			/* size of array */
8560786SpsMKINIT pid_t backgndpid = -1;	/* pid of last background process */
8660786Sps#if JOBS
8760786Spsint initialpgrp;		/* pgrp of shell on invocation */
8860786Spsint curjob;			/* current job */
8960786Sps#endif
9060786Spsint in_waitcmd = 0;		/* Are we in waitcmd? */
9160786Spsvolatile sig_atomic_t breakwaitcmd = 0;	/* Should wait be terminated? */
9260786Sps
9360786Sps#if JOBS
9460786SpsSTATIC void restartjob __P((struct job *));
9560786Sps#endif
9660786SpsSTATIC void freejob __P((struct job *));
9760786SpsSTATIC struct job *getjob __P((char *));
9860786SpsSTATIC int dowait __P((int, struct job *));
9960786Sps#if SYSV
10060786SpsSTATIC volatile int onsigchild __P((void));
10160786Sps#endif
10260786SpsSTATIC int waitproc __P((int, int *));
10360786SpsSTATIC void cmdtxt __P((union node *));
10460786SpsSTATIC void cmdputs __P((char *));
10560786Sps
10660786Sps
10760786Sps/*
10860786Sps * Turn job control on and off.
10960786Sps *
11060786Sps * Note:  This code assumes that the third arg to ioctl is a character
11160786Sps * pointer, which is true on Berkeley systems but not System V.  Since
11260786Sps * System V doesn't have job control yet, this isn't a problem now.
11360786Sps */
11460786Sps
11560786SpsMKINIT int jobctl;
11660786Sps
11760786Sps#if JOBS
11860786Spsvoid
11960786Spssetjobctl(on)
12060786Sps	int on;
12160786Sps{
12260786Sps#ifdef OLD_TTY_DRIVER
12360786Sps	int ldisc;
12460786Sps#endif
12560786Sps
12660786Sps	if (on == jobctl || rootshell == 0)
12760786Sps		return;
12860786Sps	if (on) {
12960786Sps		do { /* while we are in the background */
13060786Sps#ifdef OLD_TTY_DRIVER
13160786Sps			if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
13260786Sps#else
13360786Sps			initialpgrp = tcgetpgrp(2);
13460786Sps			if (initialpgrp < 0) {
13560786Sps#endif
13660786Sps				out2str("sh: can't access tty; job control turned off\n");
13760786Sps				mflag = 0;
13889019Sps				return;
13960786Sps			}
14060786Sps			if (initialpgrp == -1)
14160786Sps				initialpgrp = getpgrp();
14260786Sps			else if (initialpgrp != getpgrp()) {
14389019Sps				killpg(initialpgrp, SIGTTIN);
14489019Sps				continue;
14589019Sps			}
14689019Sps		} while (0);
14789019Sps#ifdef OLD_TTY_DRIVER
14889019Sps		if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
14989019Sps			out2str("sh: need new tty driver to run job control; job control turned off\n");
15089019Sps			mflag = 0;
15189019Sps			return;
15289019Sps		}
15360786Sps#endif
15460786Sps		setsignal(SIGTSTP);
15560786Sps		setsignal(SIGTTOU);
15660786Sps		setsignal(SIGTTIN);
15760786Sps		setpgid(0, rootpid);
15860786Sps#ifdef OLD_TTY_DRIVER
15960786Sps		ioctl(2, TIOCSPGRP, (char *)&rootpid);
16060786Sps#else
16160786Sps		tcsetpgrp(2, rootpid);
16260786Sps#endif
16360786Sps	} else { /* turning job control off */
16460786Sps		setpgid(0, initialpgrp);
16560786Sps#ifdef OLD_TTY_DRIVER
16660786Sps		ioctl(2, TIOCSPGRP, (char *)&initialpgrp);
16760786Sps#else
16860786Sps		tcsetpgrp(2, initialpgrp);
16960786Sps#endif
17060786Sps		setsignal(SIGTSTP);
17160786Sps		setsignal(SIGTTOU);
17260786Sps		setsignal(SIGTTIN);
17360786Sps	}
17460786Sps	jobctl = on;
17560786Sps}
17660786Sps#endif
17760786Sps
17860786Sps
17960786Sps#ifdef mkinit
18060786SpsINCLUDE <sys/types.h>
18160786SpsINCLUDE <stdlib.h>
18260786Sps
18360786SpsSHELLPROC {
18460786Sps	backgndpid = -1;
18560786Sps#if JOBS
18660786Sps	jobctl = 0;
18760786Sps#endif
18860786Sps}
18960786Sps
19060786Sps#endif
19160786Sps
19260786Sps
19360786Sps
19460786Sps#if JOBS
19560786Spsint
19660786Spsfgcmd(argc, argv)
19760786Sps	int argc __unused;
19860786Sps	char **argv;
19960786Sps{
20060786Sps	struct job *jp;
20160786Sps	int pgrp;
20260786Sps	int status;
20360786Sps
20460786Sps	jp = getjob(argv[1]);
20560786Sps	if (jp->jobctl == 0)
20660786Sps		error("job not created under job control");
20760786Sps	pgrp = jp->ps[0].pid;
20860786Sps#ifdef OLD_TTY_DRIVER
20960786Sps	ioctl(2, TIOCSPGRP, (char *)&pgrp);
21060786Sps#else
21160786Sps	tcsetpgrp(2, pgrp);
21260786Sps#endif
21360786Sps	restartjob(jp);
21460786Sps	INTOFF;
21560786Sps	status = waitforjob(jp);
21660786Sps	INTON;
21760786Sps	return status;
21860786Sps}
21960786Sps
22060786Sps
22160786Spsint
22260786Spsbgcmd(argc, argv)
22360786Sps	int argc;
22460786Sps	char **argv;
22560786Sps{
22660786Sps	struct job *jp;
22760786Sps
22860786Sps	do {
22960786Sps		jp = getjob(*++argv);
23060786Sps		if (jp->jobctl == 0)
23160786Sps			error("job not created under job control");
23260786Sps		restartjob(jp);
23360786Sps	} while (--argc > 1);
23460786Sps	return 0;
23560786Sps}
23660786Sps
23760786Sps
23860786SpsSTATIC void
23960786Spsrestartjob(jp)
24060786Sps	struct job *jp;
24160786Sps{
24260786Sps	struct procstat *ps;
24360786Sps	int i;
24460786Sps
24560786Sps	if (jp->state == JOBDONE)
24660786Sps		return;
24760786Sps	INTOFF;
24860786Sps	killpg(jp->ps[0].pid, SIGCONT);
24960786Sps	for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
25060786Sps		if (WIFSTOPPED(ps->status)) {
25160786Sps			ps->status = -1;
25260786Sps			jp->state = 0;
25360786Sps		}
25460786Sps	}
25560786Sps	INTON;
25660786Sps}
25760786Sps#endif
25860786Sps
25960786Sps
26060786Spsint
26160786Spsjobscmd(argc, argv)
26260786Sps	int argc __unused;
26360786Sps	char **argv __unused;
26460786Sps{
26589019Sps	showjobs(0);
26660786Sps	return 0;
26789019Sps}
26889019Sps
26989019Sps
27089019Sps/*
27189019Sps * Print a list of jobs.  If "change" is nonzero, only print jobs whose
27260786Sps * statuses have changed since the last call to showjobs.
27360786Sps *
27460786Sps * If the shell is interrupted in the process of creating a job, the
27560786Sps * result may be a job structure containing zero processes.  Such structures
27689019Sps * will be freed here.
27760786Sps */
27860786Sps
27960786Spsvoid
28060786Spsshowjobs(change)
28160786Sps	int change;
28260786Sps{
28360786Sps	int jobno;
28460786Sps	int procno;
28560786Sps	int i;
28660786Sps	struct job *jp;
28760786Sps	struct procstat *ps;
28860786Sps	int col;
28960786Sps	char s[64];
29060786Sps
29160786Sps	TRACE(("showjobs(%d) called\n", change));
29260786Sps	while (dowait(0, (struct job *)NULL) > 0);
29360786Sps	for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
29460786Sps		if (! jp->used)
29560786Sps			continue;
29660786Sps		if (jp->nprocs == 0) {
29760786Sps			freejob(jp);
29860786Sps			continue;
29960786Sps		}
30060786Sps		if (change && ! jp->changed)
30160786Sps			continue;
30260786Sps		procno = jp->nprocs;
30360786Sps		for (ps = jp->ps ; ; ps++) {	/* for each process */
30460786Sps			if (ps == jp->ps)
30560786Sps				fmtstr(s, 64, "[%d] %d ", jobno, ps->pid);
30660786Sps			else
30760786Sps				fmtstr(s, 64, "    %d ", ps->pid);
30860786Sps			out1str(s);
30960786Sps			col = strlen(s);
31060786Sps			s[0] = '\0';
31160786Sps			if (ps->status == -1) {
31260786Sps				/* don't print anything */
31360786Sps			} else if (WIFEXITED(ps->status)) {
31460786Sps				fmtstr(s, 64, "Exit %d", WEXITSTATUS(ps->status));
31560786Sps			} else {
31689019Sps#if JOBS
31789019Sps				if (WIFSTOPPED(ps->status))
31889019Sps					i = WSTOPSIG(ps->status);
31989019Sps				else
32089019Sps#endif
32189019Sps					i = WTERMSIG(ps->status);
32289019Sps				if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
32389019Sps					scopy(sys_siglist[i & 0x7F], s);
32489019Sps				else
32589019Sps					fmtstr(s, 64, "Signal %d", i & 0x7F);
32689019Sps				if (WCOREDUMP(ps->status))
32789019Sps					strcat(s, " (core dumped)");
32889019Sps			}
32989019Sps			out1str(s);
33089019Sps			col += strlen(s);
33189019Sps			do {
33260786Sps				out1c(' ');
33360786Sps				col++;
33460786Sps			} while (col < 30);
33560786Sps			out1str(ps->cmd);
336			out1c('\n');
337			if (--procno <= 0)
338				break;
339		}
340		jp->changed = 0;
341		if (jp->state == JOBDONE) {
342			freejob(jp);
343		}
344	}
345}
346
347
348/*
349 * Mark a job structure as unused.
350 */
351
352STATIC void
353freejob(jp)
354	struct job *jp;
355	{
356	struct procstat *ps;
357	int i;
358
359	INTOFF;
360	for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
361		if (ps->cmd != nullstr)
362			ckfree(ps->cmd);
363	}
364	if (jp->ps != &jp->ps0)
365		ckfree(jp->ps);
366	jp->used = 0;
367#if JOBS
368	if (curjob == jp - jobtab + 1)
369		curjob = 0;
370#endif
371	INTON;
372}
373
374
375
376int
377waitcmd(argc, argv)
378	int argc;
379	char **argv;
380{
381	struct job *job;
382	int status, retval;
383	struct job *jp;
384
385	if (argc > 1) {
386		job = getjob(argv[1]);
387	} else {
388		job = NULL;
389	}
390	in_waitcmd++;
391	do {	/* loop until process terminated or stopped or SIGINT is
392		 * received
393		 */
394		if (job != NULL) {
395			if (job->state) {
396				status = job->ps[job->nprocs - 1].status;
397				if (WIFEXITED(status))
398					retval = WEXITSTATUS(status);
399#if JOBS
400				else if (WIFSTOPPED(status))
401					retval = WSTOPSIG(status) + 128;
402#endif
403				else
404					retval = WTERMSIG(status) + 128;
405				if (! iflag)
406					freejob(job);
407				return retval;
408			}
409		} else {
410			for (jp = jobtab ; ; jp++) {
411				if (jp >= jobtab + njobs) {	/* no running procs */
412					return 0;
413				}
414				if (jp->used && jp->state == 0)
415					break;
416			}
417		}
418	} while (dowait(1, (struct job *)NULL) != -1);
419	in_waitcmd--;
420
421	/* Not reachable */
422	return 0;
423}
424
425
426
427int
428jobidcmd(argc, argv)
429	int argc __unused;
430	char **argv;
431{
432	struct job *jp;
433	int i;
434
435	jp = getjob(argv[1]);
436	for (i = 0 ; i < jp->nprocs ; ) {
437		out1fmt("%d", jp->ps[i].pid);
438		out1c(++i < jp->nprocs? ' ' : '\n');
439	}
440	return 0;
441}
442
443
444
445/*
446 * Convert a job name to a job structure.
447 */
448
449STATIC struct job *
450getjob(name)
451	char *name;
452	{
453	int jobno;
454	struct job *jp;
455	int pid;
456	int i;
457
458	if (name == NULL) {
459#if JOBS
460currentjob:
461		if ((jobno = curjob) == 0 || jobtab[jobno - 1].used == 0)
462			error("No current job");
463		return &jobtab[jobno - 1];
464#else
465		error("No current job");
466#endif
467	} else if (name[0] == '%') {
468		if (is_digit(name[1])) {
469			jobno = number(name + 1);
470			if (jobno > 0 && jobno <= njobs
471			 && jobtab[jobno - 1].used != 0)
472				return &jobtab[jobno - 1];
473#if JOBS
474		} else if (name[1] == '%' && name[2] == '\0') {
475			goto currentjob;
476#endif
477		} else {
478			struct job *found = NULL;
479			for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
480				if (jp->used && jp->nprocs > 0
481				 && prefix(name + 1, jp->ps[0].cmd)) {
482					if (found)
483						error("%s: ambiguous", name);
484					found = jp;
485				}
486			}
487			if (found)
488				return found;
489		}
490	} else if (is_number(name)) {
491		pid = number(name);
492		for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
493			if (jp->used && jp->nprocs > 0
494			 && jp->ps[jp->nprocs - 1].pid == pid)
495				return jp;
496		}
497	}
498	error("No such job: %s", name);
499	/*NOTREACHED*/
500	return NULL;
501}
502
503
504
505/*
506 * Return a new job structure,
507 */
508
509struct job *
510makejob(node, nprocs)
511	union node *node __unused;
512	int nprocs;
513{
514	int i;
515	struct job *jp;
516
517	for (i = njobs, jp = jobtab ; ; jp++) {
518		if (--i < 0) {
519			INTOFF;
520			if (njobs == 0) {
521				jobtab = ckmalloc(4 * sizeof jobtab[0]);
522			} else {
523				jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
524				memcpy(jp, jobtab, njobs * sizeof jp[0]);
525				/* Relocate `ps' pointers */
526				for (i = 0; i < njobs; i++)
527					if (jp[i].ps == &jobtab[i].ps0)
528						jp[i].ps = &jp[i].ps0;
529				ckfree(jobtab);
530				jobtab = jp;
531			}
532			jp = jobtab + njobs;
533			for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0);
534			INTON;
535			break;
536		}
537		if (jp->used == 0)
538			break;
539	}
540	INTOFF;
541	jp->state = 0;
542	jp->used = 1;
543	jp->changed = 0;
544	jp->nprocs = 0;
545#if JOBS
546	jp->jobctl = jobctl;
547#endif
548	if (nprocs > 1) {
549		jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
550	} else {
551		jp->ps = &jp->ps0;
552	}
553	INTON;
554	TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
555	    jp - jobtab + 1));
556	return jp;
557}
558
559
560/*
561 * Fork of a subshell.  If we are doing job control, give the subshell its
562 * own process group.  Jp is a job structure that the job is to be added to.
563 * N is the command that will be evaluated by the child.  Both jp and n may
564 * be NULL.  The mode parameter can be one of the following:
565 *	FORK_FG - Fork off a foreground process.
566 *	FORK_BG - Fork off a background process.
567 *	FORK_NOJOB - Like FORK_FG, but don't give the process its own
568 *		     process group even if job control is on.
569 *
570 * When job control is turned off, background processes have their standard
571 * input redirected to /dev/null (except for the second and later processes
572 * in a pipeline).
573 */
574
575int
576forkshell(jp, n, mode)
577	union node *n;
578	struct job *jp;
579	int mode;
580{
581	int pid;
582	int pgrp;
583
584	TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n,
585	    mode));
586	INTOFF;
587	pid = fork();
588	if (pid == -1) {
589		TRACE(("Fork failed, errno=%d\n", errno));
590		INTON;
591		error("Cannot fork");
592	}
593	if (pid == 0) {
594		struct job *p;
595		int wasroot;
596		int i;
597
598		TRACE(("Child shell %d\n", getpid()));
599		wasroot = rootshell;
600		rootshell = 0;
601		for (i = njobs, p = jobtab ; --i >= 0 ; p++)
602			if (p->used)
603				freejob(p);
604		closescript();
605		INTON;
606		clear_traps();
607#if JOBS
608		jobctl = 0;		/* do job control only in root shell */
609		if (wasroot && mode != FORK_NOJOB && mflag) {
610			if (jp == NULL || jp->nprocs == 0)
611				pgrp = getpid();
612			else
613				pgrp = jp->ps[0].pid;
614			if (setpgid(0, pgrp) == 0 && mode == FORK_FG) {
615				/*** this causes superfluous TIOCSPGRPS ***/
616#ifdef OLD_TTY_DRIVER
617				if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0)
618					error("TIOCSPGRP failed, errno=%d", errno);
619#else
620				if (tcsetpgrp(2, pgrp) < 0)
621					error("tcsetpgrp failed, errno=%d", errno);
622#endif
623			}
624			setsignal(SIGTSTP);
625			setsignal(SIGTTOU);
626		} else if (mode == FORK_BG) {
627			ignoresig(SIGINT);
628			ignoresig(SIGQUIT);
629			if ((jp == NULL || jp->nprocs == 0) &&
630			    ! fd0_redirected_p ()) {
631				close(0);
632				if (open("/dev/null", O_RDONLY) != 0)
633					error("Can't open /dev/null");
634			}
635		}
636#else
637		if (mode == FORK_BG) {
638			ignoresig(SIGINT);
639			ignoresig(SIGQUIT);
640			if ((jp == NULL || jp->nprocs == 0) &&
641			    ! fd0_redirected_p ()) {
642				close(0);
643				if (open("/dev/null", O_RDONLY) != 0)
644					error("Can't open /dev/null");
645			}
646		}
647#endif
648		if (wasroot && iflag) {
649			setsignal(SIGINT);
650			setsignal(SIGQUIT);
651			setsignal(SIGTERM);
652		}
653		return pid;
654	}
655	if (rootshell && mode != FORK_NOJOB && mflag) {
656		if (jp == NULL || jp->nprocs == 0)
657			pgrp = pid;
658		else
659			pgrp = jp->ps[0].pid;
660		setpgid(pid, pgrp);
661	}
662	if (mode == FORK_BG)
663		backgndpid = pid;		/* set $! */
664	if (jp) {
665		struct procstat *ps = &jp->ps[jp->nprocs++];
666		ps->pid = pid;
667		ps->status = -1;
668		ps->cmd = nullstr;
669		if (iflag && rootshell && n)
670			ps->cmd = commandtext(n);
671	}
672	INTON;
673	TRACE(("In parent shell:  child = %d\n", pid));
674	return pid;
675}
676
677
678
679/*
680 * Wait for job to finish.
681 *
682 * Under job control we have the problem that while a child process is
683 * running interrupts generated by the user are sent to the child but not
684 * to the shell.  This means that an infinite loop started by an inter-
685 * active user may be hard to kill.  With job control turned off, an
686 * interactive user may place an interactive program inside a loop.  If
687 * the interactive program catches interrupts, the user doesn't want
688 * these interrupts to also abort the loop.  The approach we take here
689 * is to have the shell ignore interrupt signals while waiting for a
690 * forground process to terminate, and then send itself an interrupt
691 * signal if the child process was terminated by an interrupt signal.
692 * Unfortunately, some programs want to do a bit of cleanup and then
693 * exit on interrupt; unless these processes terminate themselves by
694 * sending a signal to themselves (instead of calling exit) they will
695 * confuse this approach.
696 */
697
698int
699waitforjob(jp)
700	struct job *jp;
701	{
702#if JOBS
703	int mypgrp = getpgrp();
704#endif
705	int status;
706	int st;
707
708	INTOFF;
709	TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1));
710	while (jp->state == 0) {
711		dowait(1, jp);
712	}
713#if JOBS
714	if (jp->jobctl) {
715#ifdef OLD_TTY_DRIVER
716		if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0)
717			error("TIOCSPGRP failed, errno=%d\n", errno);
718#else
719		if (tcsetpgrp(2, mypgrp) < 0)
720			error("tcsetpgrp failed, errno=%d\n", errno);
721#endif
722	}
723	if (jp->state == JOBSTOPPED)
724		curjob = jp - jobtab + 1;
725#endif
726	status = jp->ps[jp->nprocs - 1].status;
727	/* convert to 8 bits */
728	if (WIFEXITED(status))
729		st = WEXITSTATUS(status);
730#if JOBS
731	else if (WIFSTOPPED(status))
732		st = WSTOPSIG(status) + 128;
733#endif
734	else
735		st = WTERMSIG(status) + 128;
736	if (! JOBS || jp->state == JOBDONE)
737		freejob(jp);
738	if (int_pending()) {
739		if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
740			kill(getpid(), SIGINT);
741		else
742			CLEAR_PENDING_INT;
743	}
744	INTON;
745	return st;
746}
747
748
749
750/*
751 * Wait for a process to terminate.
752 */
753
754STATIC int
755dowait(block, job)
756	int block;
757	struct job *job;
758{
759	int pid;
760	int status;
761	struct procstat *sp;
762	struct job *jp;
763	struct job *thisjob;
764	int done;
765	int stopped;
766	int core;
767	int sig;
768
769	TRACE(("dowait(%d) called\n", block));
770	do {
771		pid = waitproc(block, &status);
772		TRACE(("wait returns %d, status=%d\n", pid, status));
773	} while (pid == -1 && errno == EINTR && breakwaitcmd == 0);
774	if (breakwaitcmd != 0) {
775		breakwaitcmd = 0;
776		return -1;
777	}
778	if (pid <= 0)
779		return pid;
780	INTOFF;
781	thisjob = NULL;
782	for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
783		if (jp->used) {
784			done = 1;
785			stopped = 1;
786			for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
787				if (sp->pid == -1)
788					continue;
789				if (sp->pid == pid) {
790					TRACE(("Changing status of proc %d from 0x%x to 0x%x\n",
791						   pid, sp->status, status));
792					sp->status = status;
793					thisjob = jp;
794				}
795				if (sp->status == -1)
796					stopped = 0;
797				else if (WIFSTOPPED(sp->status))
798					done = 0;
799			}
800			if (stopped) {		/* stopped or done */
801				int state = done? JOBDONE : JOBSTOPPED;
802				if (jp->state != state) {
803					TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
804					jp->state = state;
805#if JOBS
806					if (done && curjob == jp - jobtab + 1)
807						curjob = 0;		/* no current job */
808#endif
809				}
810			}
811		}
812	}
813	INTON;
814	if (! rootshell || ! iflag || (job && thisjob == job)) {
815		core = WCOREDUMP(status);
816#if JOBS
817		if (WIFSTOPPED(status))
818			sig = WSTOPSIG(status);
819		else
820#endif
821			if (WIFEXITED(status))
822				sig = 0;
823			else
824				sig = WTERMSIG(status);
825
826		if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
827			if (thisjob != job)
828				outfmt(out2, "%d: ", pid);
829#if JOBS
830			if (sig == SIGTSTP && rootshell && iflag)
831				outfmt(out2, "%%%d ", job - jobtab + 1);
832#endif
833			if (sig < NSIG && sys_siglist[sig])
834				out2str(sys_siglist[sig]);
835			else
836				outfmt(out2, "Signal %d", sig);
837			if (core)
838				out2str(" - core dumped");
839			out2c('\n');
840			flushout(&errout);
841		} else {
842			TRACE(("Not printing status: status=%d, sig=%d\n",
843				   status, sig));
844		}
845	} else {
846		TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job));
847		if (thisjob)
848			thisjob->changed = 1;
849	}
850	return pid;
851}
852
853
854
855/*
856 * Do a wait system call.  If job control is compiled in, we accept
857 * stopped processes.  If block is zero, we return a value of zero
858 * rather than blocking.
859 *
860 * System V doesn't have a non-blocking wait system call.  It does
861 * have a SIGCLD signal that is sent to a process when one of it's
862 * children dies.  The obvious way to use SIGCLD would be to install
863 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
864 * was received, and have waitproc bump another counter when it got
865 * the status of a process.  Waitproc would then know that a wait
866 * system call would not block if the two counters were different.
867 * This approach doesn't work because if a process has children that
868 * have not been waited for, System V will send it a SIGCLD when it
869 * installs a signal handler for SIGCLD.  What this means is that when
870 * a child exits, the shell will be sent SIGCLD signals continuously
871 * until is runs out of stack space, unless it does a wait call before
872 * restoring the signal handler.  The code below takes advantage of
873 * this (mis)feature by installing a signal handler for SIGCLD and
874 * then checking to see whether it was called.  If there are any
875 * children to be waited for, it will be.
876 *
877 * If neither SYSV nor BSD is defined, we don't implement nonblocking
878 * waits at all.  In this case, the user will not be informed when
879 * a background process until the next time she runs a real program
880 * (as opposed to running a builtin command or just typing return),
881 * and the jobs command may give out of date information.
882 */
883
884#ifdef SYSV
885STATIC sig_atomic_t gotsigchild;
886
887STATIC int onsigchild() {
888	gotsigchild = 1;
889}
890#endif
891
892
893STATIC int
894waitproc(block, status)
895	int block;
896	int *status;
897{
898#ifdef BSD
899	int flags;
900
901#if JOBS
902	flags = WUNTRACED;
903#else
904	flags = 0;
905#endif
906	if (block == 0)
907		flags |= WNOHANG;
908	return wait3(status, flags, (struct rusage *)NULL);
909#else
910#ifdef SYSV
911	int (*save)();
912
913	if (block == 0) {
914		gotsigchild = 0;
915		save = signal(SIGCLD, onsigchild);
916		signal(SIGCLD, save);
917		if (gotsigchild == 0)
918			return 0;
919	}
920	return wait(status);
921#else
922	if (block == 0)
923		return 0;
924	return wait(status);
925#endif
926#endif
927}
928
929/*
930 * return 1 if there are stopped jobs, otherwise 0
931 */
932int job_warning = 0;
933int
934stoppedjobs()
935{
936	int jobno;
937	struct job *jp;
938
939	if (job_warning)
940		return (0);
941	for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
942		if (jp->used == 0)
943			continue;
944		if (jp->state == JOBSTOPPED) {
945			out2str("You have stopped jobs.\n");
946			job_warning = 2;
947			return (1);
948		}
949	}
950
951	return (0);
952}
953
954/*
955 * Return a string identifying a command (to be printed by the
956 * jobs command.
957 */
958
959STATIC char *cmdnextc;
960STATIC int cmdnleft;
961STATIC void cmdtxt(), cmdputs();
962#define MAXCMDTEXT	200
963
964char *
965commandtext(n)
966	union node *n;
967	{
968	char *name;
969
970	cmdnextc = name = ckmalloc(MAXCMDTEXT);
971	cmdnleft = MAXCMDTEXT - 4;
972	cmdtxt(n);
973	*cmdnextc = '\0';
974	return name;
975}
976
977
978STATIC void
979cmdtxt(n)
980	union node *n;
981	{
982	union node *np;
983	struct nodelist *lp;
984	char *p;
985	int i;
986	char s[2];
987
988	if (n == NULL)
989		return;
990	switch (n->type) {
991	case NSEMI:
992		cmdtxt(n->nbinary.ch1);
993		cmdputs("; ");
994		cmdtxt(n->nbinary.ch2);
995		break;
996	case NAND:
997		cmdtxt(n->nbinary.ch1);
998		cmdputs(" && ");
999		cmdtxt(n->nbinary.ch2);
1000		break;
1001	case NOR:
1002		cmdtxt(n->nbinary.ch1);
1003		cmdputs(" || ");
1004		cmdtxt(n->nbinary.ch2);
1005		break;
1006	case NPIPE:
1007		for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
1008			cmdtxt(lp->n);
1009			if (lp->next)
1010				cmdputs(" | ");
1011		}
1012		break;
1013	case NSUBSHELL:
1014		cmdputs("(");
1015		cmdtxt(n->nredir.n);
1016		cmdputs(")");
1017		break;
1018	case NREDIR:
1019	case NBACKGND:
1020		cmdtxt(n->nredir.n);
1021		break;
1022	case NIF:
1023		cmdputs("if ");
1024		cmdtxt(n->nif.test);
1025		cmdputs("; then ");
1026		cmdtxt(n->nif.ifpart);
1027		cmdputs("...");
1028		break;
1029	case NWHILE:
1030		cmdputs("while ");
1031		goto until;
1032	case NUNTIL:
1033		cmdputs("until ");
1034until:
1035		cmdtxt(n->nbinary.ch1);
1036		cmdputs("; do ");
1037		cmdtxt(n->nbinary.ch2);
1038		cmdputs("; done");
1039		break;
1040	case NFOR:
1041		cmdputs("for ");
1042		cmdputs(n->nfor.var);
1043		cmdputs(" in ...");
1044		break;
1045	case NCASE:
1046		cmdputs("case ");
1047		cmdputs(n->ncase.expr->narg.text);
1048		cmdputs(" in ...");
1049		break;
1050	case NDEFUN:
1051		cmdputs(n->narg.text);
1052		cmdputs("() ...");
1053		break;
1054	case NCMD:
1055		for (np = n->ncmd.args ; np ; np = np->narg.next) {
1056			cmdtxt(np);
1057			if (np->narg.next)
1058				cmdputs(" ");
1059		}
1060		for (np = n->ncmd.redirect ; np ; np = np->nfile.next) {
1061			cmdputs(" ");
1062			cmdtxt(np);
1063		}
1064		break;
1065	case NARG:
1066		cmdputs(n->narg.text);
1067		break;
1068	case NTO:
1069		p = ">";  i = 1;  goto redir;
1070	case NAPPEND:
1071		p = ">>";  i = 1;  goto redir;
1072	case NTOFD:
1073		p = ">&";  i = 1;  goto redir;
1074	case NFROM:
1075		p = "<";  i = 0;  goto redir;
1076	case NFROMFD:
1077		p = "<&";  i = 0;  goto redir;
1078redir:
1079		if (n->nfile.fd != i) {
1080			s[0] = n->nfile.fd + '0';
1081			s[1] = '\0';
1082			cmdputs(s);
1083		}
1084		cmdputs(p);
1085		if (n->type == NTOFD || n->type == NFROMFD) {
1086			s[0] = n->ndup.dupfd + '0';
1087			s[1] = '\0';
1088			cmdputs(s);
1089		} else {
1090			cmdtxt(n->nfile.fname);
1091		}
1092		break;
1093	case NHERE:
1094	case NXHERE:
1095		cmdputs("<<...");
1096		break;
1097	default:
1098		cmdputs("???");
1099		break;
1100	}
1101}
1102
1103
1104
1105STATIC void
1106cmdputs(s)
1107	char *s;
1108	{
1109	char *p, *q;
1110	char c;
1111	int subtype = 0;
1112
1113	if (cmdnleft <= 0)
1114		return;
1115	p = s;
1116	q = cmdnextc;
1117	while ((c = *p++) != '\0') {
1118		if (c == CTLESC)
1119			*q++ = *p++;
1120		else if (c == CTLVAR) {
1121			*q++ = '$';
1122			if (--cmdnleft > 0)
1123				*q++ = '{';
1124			subtype = *p++;
1125		} else if (c == '=' && subtype != 0) {
1126			*q++ = "}-+?="[(subtype & VSTYPE) - VSNORMAL];
1127			subtype = 0;
1128		} else if (c == CTLENDVAR) {
1129			*q++ = '}';
1130		} else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE)
1131			cmdnleft++;		/* ignore it */
1132		else
1133			*q++ = c;
1134		if (--cmdnleft <= 0) {
1135			*q++ = '.';
1136			*q++ = '.';
1137			*q++ = '.';
1138			break;
1139		}
1140	}
1141	cmdnextc = q;
1142}
1143