Home | History | Annotate | Download | only in src
      1 /*	$OpenBSD: jobs.c,v 1.38 2009/12/12 04:28:44 deraadt Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012
      5  *	Thorsten Glaser <tg (at) mirbsd.org>
      6  *
      7  * Provided that these terms and disclaimer and all copyright notices
      8  * are retained or reproduced in an accompanying document, permission
      9  * is granted to deal in this work without restriction, including un-
     10  * limited rights to use, publicly perform, distribute, sell, modify,
     11  * merge, give away, or sublicence.
     12  *
     13  * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
     14  * the utmost extent permitted by applicable law, neither express nor
     15  * implied; without malicious intent or gross negligence. In no event
     16  * may a licensor, author or contributor be held liable for indirect,
     17  * direct, other damage, loss, or other issues arising in any way out
     18  * of dealing in the work, even if advised of the possibility of such
     19  * damage or existence of a defect, except proven that it results out
     20  * of said person's immediate fault when using the work as intended.
     21  */
     22 
     23 #include "sh.h"
     24 
     25 __RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.94 2012/12/28 02:28:36 tg Exp $");
     26 
     27 #if HAVE_KILLPG
     28 #define mksh_killpg		killpg
     29 #else
     30 /* cross fingers and hope kill is killpg-endowed */
     31 #define mksh_killpg(p,s)	kill(-(p), (s))
     32 #endif
     33 
     34 /* Order important! */
     35 #define PRUNNING	0
     36 #define PEXITED		1
     37 #define PSIGNALLED	2
     38 #define PSTOPPED	3
     39 
     40 typedef struct proc Proc;
     41 struct proc {
     42 	Proc *next;		/* next process in pipeline (if any) */
     43 	pid_t pid;		/* process id */
     44 	int state;
     45 	int status;		/* wait status */
     46 	/* process command string from vistree */
     47 	char command[64 - (ALLOC_SIZE + sizeof(Proc *) + sizeof(pid_t) +
     48 	    2 * sizeof(int))];
     49 };
     50 
     51 /* Notify/print flag - j_print() argument */
     52 #define JP_NONE		0	/* don't print anything */
     53 #define JP_SHORT	1	/* print signals processes were killed by */
     54 #define JP_MEDIUM	2	/* print [job-num] -/+ command */
     55 #define JP_LONG		3	/* print [job-num] -/+ pid command */
     56 #define JP_PGRP		4	/* print pgrp */
     57 
     58 /* put_job() flags */
     59 #define PJ_ON_FRONT	0	/* at very front */
     60 #define PJ_PAST_STOPPED	1	/* just past any stopped jobs */
     61 
     62 /* Job.flags values */
     63 #define JF_STARTED	0x001	/* set when all processes in job are started */
     64 #define JF_WAITING	0x002	/* set if j_waitj() is waiting on job */
     65 #define JF_W_ASYNCNOTIFY 0x004	/* set if waiting and async notification ok */
     66 #define JF_XXCOM	0x008	/* set for $(command) jobs */
     67 #define JF_FG		0x010	/* running in foreground (also has tty pgrp) */
     68 #define JF_SAVEDTTY	0x020	/* j->ttystat is valid */
     69 #define JF_CHANGED	0x040	/* process has changed state */
     70 #define JF_KNOWN	0x080	/* $! referenced */
     71 #define JF_ZOMBIE	0x100	/* known, unwaited process */
     72 #define JF_REMOVE	0x200	/* flagged for removal (j_jobs()/j_noityf()) */
     73 #define JF_USETTYMODE	0x400	/* tty mode saved if process exits normally */
     74 #define JF_SAVEDTTYPGRP	0x800	/* j->saved_ttypgrp is valid */
     75 
     76 typedef struct job Job;
     77 struct job {
     78 	Job *next;		/* next job in list */
     79 	Proc *proc_list;	/* process list */
     80 	Proc *last_proc;	/* last process in list */
     81 	struct timeval systime;	/* system time used by job */
     82 	struct timeval usrtime;	/* user time used by job */
     83 	pid_t pgrp;		/* process group of job */
     84 	pid_t ppid;		/* pid of process that forked job */
     85 	int job;		/* job number: %n */
     86 	int flags;		/* see JF_* */
     87 	volatile int state;	/* job state */
     88 	int status;		/* exit status of last process */
     89 	int32_t	age;		/* number of jobs started */
     90 	Coproc_id coproc_id;	/* 0 or id of coprocess output pipe */
     91 #ifndef MKSH_UNEMPLOYED
     92 	mksh_ttyst ttystat;	/* saved tty state for stopped jobs */
     93 	pid_t saved_ttypgrp;	/* saved tty process group for stopped jobs */
     94 #endif
     95 };
     96 
     97 /* Flags for j_waitj() */
     98 #define JW_NONE		0x00
     99 #define JW_INTERRUPT	0x01	/* ^C will stop the wait */
    100 #define JW_ASYNCNOTIFY	0x02	/* asynchronous notification during wait ok */
    101 #define JW_STOPPEDWAIT	0x04	/* wait even if job stopped */
    102 #define JW_PIPEST	0x08	/* want PIPESTATUS */
    103 
    104 /* Error codes for j_lookup() */
    105 #define JL_OK		0
    106 #define JL_NOSUCH	1	/* no such job */
    107 #define JL_AMBIG	2	/* %foo or %?foo is ambiguous */
    108 #define JL_INVALID	3	/* non-pid, non-% job id */
    109 
    110 static const char * const lookup_msgs[] = {
    111 	null,
    112 	"no such job",
    113 	"ambiguous",
    114 	"argument must be %job or process id",
    115 	NULL
    116 };
    117 
    118 static Job *job_list;		/* job list */
    119 static Job *last_job;
    120 static Job *async_job;
    121 static pid_t async_pid;
    122 
    123 static int nzombie;		/* # of zombies owned by this process */
    124 static int32_t njobs;		/* # of jobs started */
    125 
    126 #ifndef CHILD_MAX
    127 #define CHILD_MAX	25
    128 #endif
    129 
    130 #ifndef MKSH_NOPROSPECTOFWORK
    131 /* held_sigchld is set if sigchld occurs before a job is completely started */
    132 static volatile sig_atomic_t held_sigchld;
    133 #endif
    134 
    135 #ifndef MKSH_UNEMPLOYED
    136 static struct shf	*shl_j;
    137 static bool		ttypgrp_ok;	/* set if can use tty pgrps */
    138 static pid_t		restore_ttypgrp = -1;
    139 static int const	tt_sigs[] = { SIGTSTP, SIGTTIN, SIGTTOU };
    140 #endif
    141 
    142 static void		j_set_async(Job *);
    143 static void		j_startjob(Job *);
    144 static int		j_waitj(Job *, int, const char *);
    145 static void		j_sigchld(int);
    146 static void		j_print(Job *, int, struct shf *);
    147 static Job		*j_lookup(const char *, int *);
    148 static Job		*new_job(void);
    149 static Proc		*new_proc(void);
    150 static void		check_job(Job *);
    151 static void		put_job(Job *, int);
    152 static void		remove_job(Job *, const char *);
    153 static int		kill_job(Job *, int);
    154 
    155 static void tty_init_talking(void);
    156 static void tty_init_state(void);
    157 
    158 /* initialise job control */
    159 void
    160 j_init(void)
    161 {
    162 #ifndef MKSH_UNEMPLOYED
    163 	bool mflagset = Flag(FMONITOR) != 127;
    164 
    165 	Flag(FMONITOR) = 0;
    166 #endif
    167 
    168 #ifndef MKSH_NOPROSPECTOFWORK
    169 	(void)sigemptyset(&sm_default);
    170 	sigprocmask(SIG_SETMASK, &sm_default, NULL);
    171 
    172 	(void)sigemptyset(&sm_sigchld);
    173 	(void)sigaddset(&sm_sigchld, SIGCHLD);
    174 
    175 	setsig(&sigtraps[SIGCHLD], j_sigchld,
    176 	    SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP);
    177 #else
    178 	/* Make sure SIGCHLD isn't ignored - can do odd things under SYSV */
    179 	setsig(&sigtraps[SIGCHLD], SIG_DFL, SS_RESTORE_ORIG|SS_FORCE);
    180 #endif
    181 
    182 #ifndef MKSH_UNEMPLOYED
    183 	if (!mflagset && Flag(FTALKING))
    184 		Flag(FMONITOR) = 1;
    185 
    186 	/*
    187 	 * shl_j is used to do asynchronous notification (used in
    188 	 * an interrupt handler, so need a distinct shf)
    189 	 */
    190 	shl_j = shf_fdopen(2, SHF_WR, NULL);
    191 
    192 	if (Flag(FMONITOR) || Flag(FTALKING)) {
    193 		int i;
    194 
    195 		/*
    196 		 * the TF_SHELL_USES test is a kludge that lets us know if
    197 		 * if the signals have been changed by the shell.
    198 		 */
    199 		for (i = NELEM(tt_sigs); --i >= 0; ) {
    200 			sigtraps[tt_sigs[i]].flags |= TF_SHELL_USES;
    201 			/* j_change() sets this to SS_RESTORE_DFL if FMONITOR */
    202 			setsig(&sigtraps[tt_sigs[i]], SIG_IGN,
    203 			    SS_RESTORE_IGN|SS_FORCE);
    204 		}
    205 	}
    206 
    207 	/* j_change() calls tty_init_talking() and tty_init_state() */
    208 	if (Flag(FMONITOR))
    209 		j_change();
    210 	else
    211 #endif
    212 	  if (Flag(FTALKING)) {
    213 		tty_init_talking();
    214 		tty_init_state();
    215 	}
    216 }
    217 
    218 static int
    219 proc_errorlevel(Proc *p)
    220 {
    221 	switch (p->state) {
    222 	case PEXITED:
    223 		return (WEXITSTATUS(p->status));
    224 	case PSIGNALLED:
    225 		return (128 + WTERMSIG(p->status));
    226 	default:
    227 		return (0);
    228 	}
    229 }
    230 
    231 /* job cleanup before shell exit */
    232 void
    233 j_exit(void)
    234 {
    235 	/* kill stopped, and possibly running, jobs */
    236 	Job *j;
    237 	bool killed = false;
    238 
    239 	for (j = job_list; j != NULL; j = j->next) {
    240 		if (j->ppid == procpid &&
    241 		    (j->state == PSTOPPED ||
    242 		    (j->state == PRUNNING &&
    243 		    ((j->flags & JF_FG) ||
    244 		    (Flag(FLOGIN) && !Flag(FNOHUP) && procpid == kshpid))))) {
    245 			killed = true;
    246 			if (j->pgrp == 0)
    247 				kill_job(j, SIGHUP);
    248 			else
    249 				mksh_killpg(j->pgrp, SIGHUP);
    250 #ifndef MKSH_UNEMPLOYED
    251 			if (j->state == PSTOPPED) {
    252 				if (j->pgrp == 0)
    253 					kill_job(j, SIGCONT);
    254 				else
    255 					mksh_killpg(j->pgrp, SIGCONT);
    256 			}
    257 #endif
    258 		}
    259 	}
    260 	if (killed)
    261 		sleep(1);
    262 	j_notify();
    263 
    264 #ifndef MKSH_UNEMPLOYED
    265 	if (kshpid == procpid && restore_ttypgrp >= 0) {
    266 		/*
    267 		 * Need to restore the tty pgrp to what it was when the
    268 		 * shell started up, so that the process that started us
    269 		 * will be able to access the tty when we are done.
    270 		 * Also need to restore our process group in case we are
    271 		 * about to do an exec so that both our parent and the
    272 		 * process we are to become will be able to access the tty.
    273 		 */
    274 		tcsetpgrp(tty_fd, restore_ttypgrp);
    275 		setpgid(0, restore_ttypgrp);
    276 	}
    277 	if (Flag(FMONITOR)) {
    278 		Flag(FMONITOR) = 0;
    279 		j_change();
    280 	}
    281 #endif
    282 }
    283 
    284 #ifndef MKSH_UNEMPLOYED
    285 /* turn job control on or off according to Flag(FMONITOR) */
    286 void
    287 j_change(void)
    288 {
    289 	int i;
    290 
    291 	if (Flag(FMONITOR)) {
    292 		bool use_tty = Flag(FTALKING);
    293 
    294 		/* don't call mksh_tcget until we own the tty process group */
    295 		if (use_tty)
    296 			tty_init_talking();
    297 
    298 		/* no controlling tty, no SIGT* */
    299 		if ((ttypgrp_ok = (use_tty && tty_fd >= 0 && tty_devtty))) {
    300 			setsig(&sigtraps[SIGTTIN], SIG_DFL,
    301 			    SS_RESTORE_ORIG|SS_FORCE);
    302 			/* wait to be given tty (POSIX.1, B.2, job control) */
    303 			while (/* CONSTCOND */ 1) {
    304 				pid_t ttypgrp;
    305 
    306 				if ((ttypgrp = tcgetpgrp(tty_fd)) < 0) {
    307 					warningf(false, "%s: %s %s: %s",
    308 					    "j_init", "tcgetpgrp", "failed",
    309 					    cstrerror(errno));
    310 					ttypgrp_ok = false;
    311 					break;
    312 				}
    313 				if (ttypgrp == kshpgrp)
    314 					break;
    315 				kill(0, SIGTTIN);
    316 			}
    317 		}
    318 		for (i = NELEM(tt_sigs); --i >= 0; )
    319 			setsig(&sigtraps[tt_sigs[i]], SIG_IGN,
    320 			    SS_RESTORE_DFL|SS_FORCE);
    321 		if (ttypgrp_ok && kshpgrp != kshpid) {
    322 			if (setpgid(0, kshpid) < 0) {
    323 				warningf(false, "%s: %s %s: %s", "j_init",
    324 				    "setpgid", "failed", cstrerror(errno));
    325 				ttypgrp_ok = false;
    326 			} else {
    327 				if (tcsetpgrp(tty_fd, kshpid) < 0) {
    328 					warningf(false, "%s: %s %s: %s",
    329 					    "j_init", "tcsetpgrp", "failed",
    330 					    cstrerror(errno));
    331 					ttypgrp_ok = false;
    332 				} else
    333 					restore_ttypgrp = kshpgrp;
    334 				kshpgrp = kshpid;
    335 			}
    336 		}
    337 #ifndef MKSH_DISABLE_TTY_WARNING
    338 		if (use_tty && !ttypgrp_ok)
    339 			warningf(false, "%s: %s", "warning",
    340 			    "won't have full job control");
    341 #endif
    342 	} else {
    343 		ttypgrp_ok = false;
    344 		if (Flag(FTALKING))
    345 			for (i = NELEM(tt_sigs); --i >= 0; )
    346 				setsig(&sigtraps[tt_sigs[i]], SIG_IGN,
    347 				    SS_RESTORE_IGN|SS_FORCE);
    348 		else
    349 			for (i = NELEM(tt_sigs); --i >= 0; ) {
    350 				if (sigtraps[tt_sigs[i]].flags &
    351 				    (TF_ORIG_IGN | TF_ORIG_DFL))
    352 					setsig(&sigtraps[tt_sigs[i]],
    353 					    (sigtraps[tt_sigs[i]].flags & TF_ORIG_IGN) ?
    354 					    SIG_IGN : SIG_DFL,
    355 					    SS_RESTORE_ORIG|SS_FORCE);
    356 			}
    357 	}
    358 	tty_init_state();
    359 }
    360 #endif
    361 
    362 #if HAVE_NICE
    363 /* run nice(3) and ignore the result */
    364 static void
    365 ksh_nice(int ness)
    366 {
    367 #if defined(__USE_FORTIFY_LEVEL) && (__USE_FORTIFY_LEVEL > 0)
    368 	int eno;
    369 
    370 	errno = 0;
    371 	/* this is gonna annoy users; complain to your distro, people! */
    372 	if (nice(ness) == -1 && (eno = errno) != 0)
    373 		warningf(false, "%s: %s", "bgnice", cstrerror(eno));
    374 #else
    375 	(void)nice(ness);
    376 #endif
    377 }
    378 #endif
    379 
    380 /* execute tree in child subprocess */
    381 int
    382 exchild(struct op *t, int flags,
    383     volatile int *xerrok,
    384     /* used if XPCLOSE or XCCLOSE */
    385     int close_fd)
    386 {
    387 	/* for pipelines */
    388 	static Proc *last_proc;
    389 
    390 	int rv = 0, forksleep, jwflags = JW_NONE;
    391 #ifndef MKSH_NOPROSPECTOFWORK
    392 	sigset_t omask;
    393 #endif
    394 	Proc *p;
    395 	Job *j;
    396 	pid_t cldpid;
    397 
    398 	if (flags & XPIPEST) {
    399 		flags &= ~XPIPEST;
    400 		jwflags |= JW_PIPEST;
    401 	}
    402 
    403 	if (flags & XEXEC)
    404 		/*
    405 		 * Clear XFORK|XPCLOSE|XCCLOSE|XCOPROC|XPIPEO|XPIPEI|XXCOM|XBGND
    406 		 * (also done in another execute() below)
    407 		 */
    408 		return (execute(t, flags & (XEXEC | XERROK), xerrok));
    409 
    410 #ifndef MKSH_NOPROSPECTOFWORK
    411 	/* no SIGCHLDs while messing with job and process lists */
    412 	sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
    413 #endif
    414 
    415 	p = new_proc();
    416 	p->next = NULL;
    417 	p->state = PRUNNING;
    418 	p->status = 0;
    419 	p->pid = 0;
    420 
    421 	/* link process into jobs list */
    422 	if (flags & XPIPEI) {
    423 		/* continuing with a pipe */
    424 		if (!last_job)
    425 			internal_errorf("%s %d",
    426 			    "exchild: XPIPEI and no last_job - pid",
    427 			    (int)procpid);
    428 		j = last_job;
    429 		if (last_proc)
    430 			last_proc->next = p;
    431 		last_proc = p;
    432 	} else {
    433 		/* fills in j->job */
    434 		j = new_job();
    435 		/*
    436 		 * we don't consider XXCOMs foreground since they don't get
    437 		 * tty process group and we don't save or restore tty modes.
    438 		 */
    439 		j->flags = (flags & XXCOM) ? JF_XXCOM :
    440 		    ((flags & XBGND) ? 0 : (JF_FG|JF_USETTYMODE));
    441 		timerclear(&j->usrtime);
    442 		timerclear(&j->systime);
    443 		j->state = PRUNNING;
    444 		j->pgrp = 0;
    445 		j->ppid = procpid;
    446 		j->age = ++njobs;
    447 		j->proc_list = p;
    448 		j->coproc_id = 0;
    449 		last_job = j;
    450 		last_proc = p;
    451 		put_job(j, PJ_PAST_STOPPED);
    452 	}
    453 
    454 	vistree(p->command, sizeof(p->command), t);
    455 
    456 	/* create child process */
    457 	forksleep = 1;
    458 	while ((cldpid = fork()) < 0 && errno == EAGAIN && forksleep < 32) {
    459 		if (intrsig)
    460 			/* allow user to ^C out... */
    461 			break;
    462 		sleep(forksleep);
    463 		forksleep <<= 1;
    464 	}
    465 	/* ensure $RANDOM changes between parent and child */
    466 	rndset((long)cldpid);
    467 	/* fork failed? */
    468 	if (cldpid < 0) {
    469 		kill_job(j, SIGKILL);
    470 		remove_job(j, "fork failed");
    471 #ifndef MKSH_NOPROSPECTOFWORK
    472 		sigprocmask(SIG_SETMASK, &omask, NULL);
    473 #endif
    474 		errorf("can't fork - try again");
    475 	}
    476 	p->pid = cldpid ? cldpid : (procpid = getpid());
    477 
    478 #ifndef MKSH_UNEMPLOYED
    479 	/* job control set up */
    480 	if (Flag(FMONITOR) && !(flags&XXCOM)) {
    481 		bool dotty = false;
    482 
    483 		if (j->pgrp == 0) {
    484 			/* First process */
    485 			j->pgrp = p->pid;
    486 			dotty = true;
    487 		}
    488 
    489 		/*
    490 		 * set pgrp in both parent and child to deal with race
    491 		 * condition
    492 		 */
    493 		setpgid(p->pid, j->pgrp);
    494 		if (ttypgrp_ok && dotty && !(flags & XBGND))
    495 			tcsetpgrp(tty_fd, j->pgrp);
    496 	}
    497 #endif
    498 
    499 	/* used to close pipe input fd */
    500 	if (close_fd >= 0 && (((flags & XPCLOSE) && cldpid) ||
    501 	    ((flags & XCCLOSE) && !cldpid)))
    502 		close(close_fd);
    503 	if (!cldpid) {
    504 		/* child */
    505 
    506 		/* Do this before restoring signal */
    507 		if (flags & XCOPROC)
    508 			coproc_cleanup(false);
    509 #ifndef MKSH_NOPROSPECTOFWORK
    510 		sigprocmask(SIG_SETMASK, &omask, NULL);
    511 #endif
    512 		cleanup_parents_env();
    513 #ifndef MKSH_UNEMPLOYED
    514 		/*
    515 		 * If FMONITOR or FTALKING is set, these signals are ignored,
    516 		 * if neither FMONITOR nor FTALKING are set, the signals have
    517 		 * their inherited values.
    518 		 */
    519 		if (Flag(FMONITOR) && !(flags & XXCOM)) {
    520 			for (forksleep = NELEM(tt_sigs); --forksleep >= 0; )
    521 				setsig(&sigtraps[tt_sigs[forksleep]], SIG_DFL,
    522 				    SS_RESTORE_DFL|SS_FORCE);
    523 		}
    524 #endif
    525 #if HAVE_NICE
    526 		if (Flag(FBGNICE) && (flags & XBGND))
    527 			ksh_nice(4);
    528 #endif
    529 		if ((flags & XBGND)
    530 #ifndef MKSH_UNEMPLOYED
    531 		    && !Flag(FMONITOR)
    532 #endif
    533 		    ) {
    534 			setsig(&sigtraps[SIGINT], SIG_IGN,
    535 			    SS_RESTORE_IGN|SS_FORCE);
    536 			setsig(&sigtraps[SIGQUIT], SIG_IGN,
    537 			    SS_RESTORE_IGN|SS_FORCE);
    538 			if ((!(flags & (XPIPEI | XCOPROC))) &&
    539 			    ((forksleep = open("/dev/null", 0)) > 0)) {
    540 				(void)ksh_dup2(forksleep, 0, true);
    541 				close(forksleep);
    542 			}
    543 		}
    544 		/* in case of $(jobs) command */
    545 		remove_job(j, "child");
    546 		nzombie = 0;
    547 #ifndef MKSH_UNEMPLOYED
    548 		ttypgrp_ok = false;
    549 		Flag(FMONITOR) = 0;
    550 #endif
    551 		Flag(FTALKING) = 0;
    552 		cleartraps();
    553 		/* no return */
    554 		execute(t, (flags & XERROK) | XEXEC, NULL);
    555 #ifndef MKSH_SMALL
    556 		if (t->type == TPIPE)
    557 			unwind(LLEAVE);
    558 		internal_warningf("%s: %s", "exchild", "execute() returned");
    559 		fptreef(shl_out, 8, "%s: tried to execute {\n\t%T\n}\n",
    560 		    "exchild", t);
    561 		shf_flush(shl_out);
    562 #endif
    563 		unwind(LLEAVE);
    564 		/* NOTREACHED */
    565 	}
    566 
    567 	/* shell (parent) stuff */
    568 	if (!(flags & XPIPEO)) {
    569 		/* last process in a job */
    570 		j_startjob(j);
    571 		if (flags & XCOPROC) {
    572 			j->coproc_id = coproc.id;
    573 			/* n jobs using co-process output */
    574 			coproc.njobs++;
    575 			/* j using co-process input */
    576 			coproc.job = (void *)j;
    577 		}
    578 		if (flags & XBGND) {
    579 			j_set_async(j);
    580 			if (Flag(FTALKING)) {
    581 				shf_fprintf(shl_out, "[%d]", j->job);
    582 				for (p = j->proc_list; p; p = p->next)
    583 					shf_fprintf(shl_out, " %d",
    584 					    (int)p->pid);
    585 				shf_putchar('\n', shl_out);
    586 				shf_flush(shl_out);
    587 			}
    588 		} else
    589 			rv = j_waitj(j, jwflags, "jw:last proc");
    590 	}
    591 
    592 #ifndef MKSH_NOPROSPECTOFWORK
    593 	sigprocmask(SIG_SETMASK, &omask, NULL);
    594 #endif
    595 
    596 	return (rv);
    597 }
    598 
    599 /* start the last job: only used for $(command) jobs */
    600 void
    601 startlast(void)
    602 {
    603 #ifndef MKSH_NOPROSPECTOFWORK
    604 	sigset_t omask;
    605 
    606 	sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
    607 #endif
    608 
    609 	/* no need to report error - waitlast() will do it */
    610 	if (last_job) {
    611 		/* ensure it isn't removed by check_job() */
    612 		last_job->flags |= JF_WAITING;
    613 		j_startjob(last_job);
    614 	}
    615 #ifndef MKSH_NOPROSPECTOFWORK
    616 	sigprocmask(SIG_SETMASK, &omask, NULL);
    617 #endif
    618 }
    619 
    620 /* wait for last job: only used for $(command) jobs */
    621 int
    622 waitlast(void)
    623 {
    624 	int rv;
    625 	Job *j;
    626 #ifndef MKSH_NOPROSPECTOFWORK
    627 	sigset_t omask;
    628 
    629 	sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
    630 #endif
    631 
    632 	j = last_job;
    633 	if (!j || !(j->flags & JF_STARTED)) {
    634 		if (!j)
    635 			warningf(true, "%s: %s", "waitlast", "no last job");
    636 		else
    637 			internal_warningf("%s: %s", "waitlast", "not started");
    638 #ifndef MKSH_NOPROSPECTOFWORK
    639 		sigprocmask(SIG_SETMASK, &omask, NULL);
    640 #endif
    641 		/* not so arbitrary, non-zero value */
    642 		return (125);
    643 	}
    644 
    645 	rv = j_waitj(j, JW_NONE, "waitlast");
    646 
    647 #ifndef MKSH_NOPROSPECTOFWORK
    648 	sigprocmask(SIG_SETMASK, &omask, NULL);
    649 #endif
    650 
    651 	return (rv);
    652 }
    653 
    654 /* wait for child, interruptable. */
    655 int
    656 waitfor(const char *cp, int *sigp)
    657 {
    658 	int rv, ecode, flags = JW_INTERRUPT|JW_ASYNCNOTIFY;
    659 	Job *j;
    660 #ifndef MKSH_NOPROSPECTOFWORK
    661 	sigset_t omask;
    662 
    663 	sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
    664 #endif
    665 
    666 	*sigp = 0;
    667 
    668 	if (cp == NULL) {
    669 		/*
    670 		 * wait for an unspecified job - always returns 0, so
    671 		 * don't have to worry about exited/signaled jobs
    672 		 */
    673 		for (j = job_list; j; j = j->next)
    674 			/* AT&T ksh will wait for stopped jobs - we don't */
    675 			if (j->ppid == procpid && j->state == PRUNNING)
    676 				break;
    677 		if (!j) {
    678 #ifndef MKSH_NOPROSPECTOFWORK
    679 			sigprocmask(SIG_SETMASK, &omask, NULL);
    680 #endif
    681 			return (-1);
    682 		}
    683 	} else if ((j = j_lookup(cp, &ecode))) {
    684 		/* don't report normal job completion */
    685 		flags &= ~JW_ASYNCNOTIFY;
    686 		if (j->ppid != procpid) {
    687 #ifndef MKSH_NOPROSPECTOFWORK
    688 			sigprocmask(SIG_SETMASK, &omask, NULL);
    689 #endif
    690 			return (-1);
    691 		}
    692 	} else {
    693 #ifndef MKSH_NOPROSPECTOFWORK
    694 		sigprocmask(SIG_SETMASK, &omask, NULL);
    695 #endif
    696 		if (ecode != JL_NOSUCH)
    697 			bi_errorf("%s: %s", cp, lookup_msgs[ecode]);
    698 		return (-1);
    699 	}
    700 
    701 	/* AT&T ksh will wait for stopped jobs - we don't */
    702 	rv = j_waitj(j, flags, "jw:waitfor");
    703 
    704 #ifndef MKSH_NOPROSPECTOFWORK
    705 	sigprocmask(SIG_SETMASK, &omask, NULL);
    706 #endif
    707 
    708 	if (rv < 0)
    709 		/* we were interrupted */
    710 		*sigp = 128 + -rv;
    711 
    712 	return (rv);
    713 }
    714 
    715 /* kill (built-in) a job */
    716 int
    717 j_kill(const char *cp, int sig)
    718 {
    719 	Job *j;
    720 	int rv = 0, ecode;
    721 #ifndef MKSH_NOPROSPECTOFWORK
    722 	sigset_t omask;
    723 
    724 	sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
    725 #endif
    726 
    727 	if ((j = j_lookup(cp, &ecode)) == NULL) {
    728 #ifndef MKSH_NOPROSPECTOFWORK
    729 		sigprocmask(SIG_SETMASK, &omask, NULL);
    730 #endif
    731 		bi_errorf("%s: %s", cp, lookup_msgs[ecode]);
    732 		return (1);
    733 	}
    734 
    735 	if (j->pgrp == 0) {
    736 		/* started when !Flag(FMONITOR) */
    737 		if (kill_job(j, sig) < 0) {
    738 			bi_errorf("%s: %s", cp, cstrerror(errno));
    739 			rv = 1;
    740 		}
    741 	} else {
    742 #ifndef MKSH_UNEMPLOYED
    743 		if (j->state == PSTOPPED && (sig == SIGTERM || sig == SIGHUP))
    744 			mksh_killpg(j->pgrp, SIGCONT);
    745 #endif
    746 		if (mksh_killpg(j->pgrp, sig) < 0) {
    747 			bi_errorf("%s: %s", cp, cstrerror(errno));
    748 			rv = 1;
    749 		}
    750 	}
    751 
    752 #ifndef MKSH_NOPROSPECTOFWORK
    753 	sigprocmask(SIG_SETMASK, &omask, NULL);
    754 #endif
    755 
    756 	return (rv);
    757 }
    758 
    759 #ifndef MKSH_UNEMPLOYED
    760 /* fg and bg built-ins: called only if Flag(FMONITOR) set */
    761 int
    762 j_resume(const char *cp, int bg)
    763 {
    764 	Job *j;
    765 	Proc *p;
    766 	int ecode, rv = 0;
    767 	bool running;
    768 	sigset_t omask;
    769 
    770 	sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
    771 
    772 	if ((j = j_lookup(cp, &ecode)) == NULL) {
    773 		sigprocmask(SIG_SETMASK, &omask, NULL);
    774 		bi_errorf("%s: %s", cp, lookup_msgs[ecode]);
    775 		return (1);
    776 	}
    777 
    778 	if (j->pgrp == 0) {
    779 		sigprocmask(SIG_SETMASK, &omask, NULL);
    780 		bi_errorf("job not job-controlled");
    781 		return (1);
    782 	}
    783 
    784 	if (bg)
    785 		shprintf("[%d] ", j->job);
    786 
    787 	running = false;
    788 	for (p = j->proc_list; p != NULL; p = p->next) {
    789 		if (p->state == PSTOPPED) {
    790 			p->state = PRUNNING;
    791 			p->status = 0;
    792 			running = true;
    793 		}
    794 		shf_puts(p->command, shl_stdout);
    795 		if (p->next)
    796 			shf_puts("| ", shl_stdout);
    797 	}
    798 	shf_putc('\n', shl_stdout);
    799 	shf_flush(shl_stdout);
    800 	if (running)
    801 		j->state = PRUNNING;
    802 
    803 	put_job(j, PJ_PAST_STOPPED);
    804 	if (bg)
    805 		j_set_async(j);
    806 	else {
    807 		/* attach tty to job */
    808 		if (j->state == PRUNNING) {
    809 			if (ttypgrp_ok && (j->flags & JF_SAVEDTTY))
    810 				mksh_tcset(tty_fd, &j->ttystat);
    811 			/* See comment in j_waitj regarding saved_ttypgrp. */
    812 			if (ttypgrp_ok &&
    813 			    tcsetpgrp(tty_fd, (j->flags & JF_SAVEDTTYPGRP) ?
    814 			    j->saved_ttypgrp : j->pgrp) < 0) {
    815 				rv = errno;
    816 				if (j->flags & JF_SAVEDTTY)
    817 					mksh_tcset(tty_fd, &tty_state);
    818 				sigprocmask(SIG_SETMASK, &omask, NULL);
    819 				bi_errorf("%s %s(%d, %ld) %s: %s",
    820 				    "1st", "tcsetpgrp", tty_fd,
    821 				    (long)((j->flags & JF_SAVEDTTYPGRP) ?
    822 				    j->saved_ttypgrp : j->pgrp), "failed",
    823 				    cstrerror(rv));
    824 				return (1);
    825 			}
    826 		}
    827 		j->flags |= JF_FG;
    828 		j->flags &= ~JF_KNOWN;
    829 		if (j == async_job)
    830 			async_job = NULL;
    831 	}
    832 
    833 	if (j->state == PRUNNING && mksh_killpg(j->pgrp, SIGCONT) < 0) {
    834 		int eno = errno;
    835 
    836 		if (!bg) {
    837 			j->flags &= ~JF_FG;
    838 			if (ttypgrp_ok && (j->flags & JF_SAVEDTTY))
    839 				mksh_tcset(tty_fd, &tty_state);
    840 			if (ttypgrp_ok && tcsetpgrp(tty_fd, kshpgrp) < 0)
    841 				warningf(true, "%s %s(%d, %ld) %s: %s",
    842 				    "fg: 2nd", "tcsetpgrp", tty_fd,
    843 				    (long)kshpgrp, "failed", cstrerror(errno));
    844 		}
    845 		sigprocmask(SIG_SETMASK, &omask, NULL);
    846 		bi_errorf("%s %s %s", "can't continue job",
    847 		    cp, cstrerror(eno));
    848 		return (1);
    849 	}
    850 	if (!bg) {
    851 		if (ttypgrp_ok) {
    852 			j->flags &= ~(JF_SAVEDTTY | JF_SAVEDTTYPGRP);
    853 		}
    854 		rv = j_waitj(j, JW_NONE, "jw:resume");
    855 	}
    856 	sigprocmask(SIG_SETMASK, &omask, NULL);
    857 	return (rv);
    858 }
    859 #endif
    860 
    861 /* are there any running or stopped jobs ? */
    862 int
    863 j_stopped_running(void)
    864 {
    865 	Job *j;
    866 	int which = 0;
    867 
    868 	for (j = job_list; j != NULL; j = j->next) {
    869 #ifndef MKSH_UNEMPLOYED
    870 		if (j->ppid == procpid && j->state == PSTOPPED)
    871 			which |= 1;
    872 #endif
    873 		if (Flag(FLOGIN) && !Flag(FNOHUP) && procpid == kshpid &&
    874 		    j->ppid == procpid && j->state == PRUNNING)
    875 			which |= 2;
    876 	}
    877 	if (which) {
    878 		shellf("You have %s%s%s jobs\n",
    879 		    which & 1 ? "stopped" : "",
    880 		    which == 3 ? " and " : "",
    881 		    which & 2 ? "running" : "");
    882 		return (1);
    883 	}
    884 
    885 	return (0);
    886 }
    887 
    888 
    889 /* list jobs for jobs built-in */
    890 int
    891 j_jobs(const char *cp, int slp,
    892     /* 0: short, 1: long, 2: pgrp */
    893     int nflag)
    894 {
    895 	Job *j, *tmp;
    896 	int how, zflag = 0;
    897 #ifndef MKSH_NOPROSPECTOFWORK
    898 	sigset_t omask;
    899 
    900 	sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
    901 #endif
    902 
    903 	if (nflag < 0) {
    904 		/* kludge: print zombies */
    905 		nflag = 0;
    906 		zflag = 1;
    907 	}
    908 	if (cp) {
    909 		int	ecode;
    910 
    911 		if ((j = j_lookup(cp, &ecode)) == NULL) {
    912 #ifndef MKSH_NOPROSPECTOFWORK
    913 			sigprocmask(SIG_SETMASK, &omask, NULL);
    914 #endif
    915 			bi_errorf("%s: %s", cp, lookup_msgs[ecode]);
    916 			return (1);
    917 		}
    918 	} else
    919 		j = job_list;
    920 	how = slp == 0 ? JP_MEDIUM : (slp == 1 ? JP_LONG : JP_PGRP);
    921 	for (; j; j = j->next) {
    922 		if ((!(j->flags & JF_ZOMBIE) || zflag) &&
    923 		    (!nflag || (j->flags & JF_CHANGED))) {
    924 			j_print(j, how, shl_stdout);
    925 			if (j->state == PEXITED || j->state == PSIGNALLED)
    926 				j->flags |= JF_REMOVE;
    927 		}
    928 		if (cp)
    929 			break;
    930 	}
    931 	/* Remove jobs after printing so there won't be multiple + or - jobs */
    932 	for (j = job_list; j; j = tmp) {
    933 		tmp = j->next;
    934 		if (j->flags & JF_REMOVE)
    935 			remove_job(j, "jobs");
    936 	}
    937 #ifndef MKSH_NOPROSPECTOFWORK
    938 	sigprocmask(SIG_SETMASK, &omask, NULL);
    939 #endif
    940 	return (0);
    941 }
    942 
    943 /* list jobs for top-level notification */
    944 void
    945 j_notify(void)
    946 {
    947 	Job *j, *tmp;
    948 #ifndef MKSH_NOPROSPECTOFWORK
    949 	sigset_t omask;
    950 
    951 	sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
    952 #endif
    953 	for (j = job_list; j; j = j->next) {
    954 #ifndef MKSH_UNEMPLOYED
    955 		if (Flag(FMONITOR) && (j->flags & JF_CHANGED))
    956 			j_print(j, JP_MEDIUM, shl_out);
    957 #endif
    958 		/*
    959 		 * Remove job after doing reports so there aren't
    960 		 * multiple +/- jobs.
    961 		 */
    962 		if (j->state == PEXITED || j->state == PSIGNALLED)
    963 			j->flags |= JF_REMOVE;
    964 	}
    965 	for (j = job_list; j; j = tmp) {
    966 		tmp = j->next;
    967 		if (j->flags & JF_REMOVE)
    968 			remove_job(j, "notify");
    969 	}
    970 	shf_flush(shl_out);
    971 #ifndef MKSH_NOPROSPECTOFWORK
    972 	sigprocmask(SIG_SETMASK, &omask, NULL);
    973 #endif
    974 }
    975 
    976 /* Return pid of last process in last asynchronous job */
    977 pid_t
    978 j_async(void)
    979 {
    980 #ifndef MKSH_NOPROSPECTOFWORK
    981 	sigset_t omask;
    982 
    983 	sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
    984 #endif
    985 
    986 	if (async_job)
    987 		async_job->flags |= JF_KNOWN;
    988 
    989 #ifndef MKSH_NOPROSPECTOFWORK
    990 	sigprocmask(SIG_SETMASK, &omask, NULL);
    991 #endif
    992 
    993 	return (async_pid);
    994 }
    995 
    996 /*
    997  * Make j the last async process
    998  *
    999  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1000  */
   1001 static void
   1002 j_set_async(Job *j)
   1003 {
   1004 	Job	*jl, *oldest;
   1005 
   1006 	if (async_job && (async_job->flags & (JF_KNOWN|JF_ZOMBIE)) == JF_ZOMBIE)
   1007 		remove_job(async_job, "async");
   1008 	if (!(j->flags & JF_STARTED)) {
   1009 		internal_warningf("%s: %s", "j_async", "job not started");
   1010 		return;
   1011 	}
   1012 	async_job = j;
   1013 	async_pid = j->last_proc->pid;
   1014 	while (nzombie > CHILD_MAX) {
   1015 		oldest = NULL;
   1016 		for (jl = job_list; jl; jl = jl->next)
   1017 			if (jl != async_job && (jl->flags & JF_ZOMBIE) &&
   1018 			    (!oldest || jl->age < oldest->age))
   1019 				oldest = jl;
   1020 		if (!oldest) {
   1021 			/* XXX debugging */
   1022 			if (!(async_job->flags & JF_ZOMBIE) || nzombie != 1) {
   1023 				internal_warningf("%s: bad nzombie (%d)",
   1024 				    "j_async", nzombie);
   1025 				nzombie = 0;
   1026 			}
   1027 			break;
   1028 		}
   1029 		remove_job(oldest, "zombie");
   1030 	}
   1031 }
   1032 
   1033 /*
   1034  * Start a job: set STARTED, check for held signals and set j->last_proc
   1035  *
   1036  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1037  */
   1038 static void
   1039 j_startjob(Job *j)
   1040 {
   1041 	Proc	*p;
   1042 
   1043 	j->flags |= JF_STARTED;
   1044 	for (p = j->proc_list; p->next; p = p->next)
   1045 		;
   1046 	j->last_proc = p;
   1047 
   1048 #ifndef MKSH_NOPROSPECTOFWORK
   1049 	if (held_sigchld) {
   1050 		held_sigchld = 0;
   1051 		/* Don't call j_sigchld() as it may remove job... */
   1052 		kill(procpid, SIGCHLD);
   1053 	}
   1054 #endif
   1055 }
   1056 
   1057 /*
   1058  * wait for job to complete or change state
   1059  *
   1060  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1061  */
   1062 static int
   1063 j_waitj(Job *j,
   1064     /* see JW_* */
   1065     int flags,
   1066     const char *where)
   1067 {
   1068 	int rv;
   1069 #ifdef MKSH_NO_SIGSUSPEND
   1070 	sigset_t omask;
   1071 #endif
   1072 
   1073 	/*
   1074 	 * No auto-notify on the job we are waiting on.
   1075 	 */
   1076 	j->flags |= JF_WAITING;
   1077 	if (flags & JW_ASYNCNOTIFY)
   1078 		j->flags |= JF_W_ASYNCNOTIFY;
   1079 
   1080 #ifndef MKSH_UNEMPLOYED
   1081 	if (!Flag(FMONITOR))
   1082 #endif
   1083 		flags |= JW_STOPPEDWAIT;
   1084 
   1085 	while (j->state == PRUNNING ||
   1086 	    ((flags & JW_STOPPEDWAIT) && j->state == PSTOPPED)) {
   1087 #ifndef MKSH_NOPROSPECTOFWORK
   1088 #ifdef MKSH_NO_SIGSUSPEND
   1089 		sigprocmask(SIG_SETMASK, &sm_default, &omask);
   1090 		pause();
   1091 		/* note that handlers may run here so they need to know */
   1092 		sigprocmask(SIG_SETMASK, &omask, NULL);
   1093 #else
   1094 		sigsuspend(&sm_default);
   1095 #endif
   1096 #else
   1097 		j_sigchld(SIGCHLD);
   1098 #endif
   1099 		if (fatal_trap) {
   1100 			int oldf = j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY);
   1101 			j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
   1102 			runtraps(TF_FATAL);
   1103 			/* not reached... */
   1104 			j->flags |= oldf;
   1105 		}
   1106 		if ((flags & JW_INTERRUPT) && (rv = trap_pending())) {
   1107 			j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
   1108 			return (-rv);
   1109 		}
   1110 	}
   1111 	j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
   1112 
   1113 	if (j->flags & JF_FG) {
   1114 		j->flags &= ~JF_FG;
   1115 #ifndef MKSH_UNEMPLOYED
   1116 		if (Flag(FMONITOR) && ttypgrp_ok && j->pgrp) {
   1117 			/*
   1118 			 * Save the tty's current pgrp so it can be restored
   1119 			 * when the job is foregrounded. This is to
   1120 			 * deal with things like the GNU su which does
   1121 			 * a fork/exec instead of an exec (the fork means
   1122 			 * the execed shell gets a different pid from its
   1123 			 * pgrp, so naturally it sets its pgrp and gets hosed
   1124 			 * when it gets foregrounded by the parent shell which
   1125 			 * has restored the tty's pgrp to that of the su
   1126 			 * process).
   1127 			 */
   1128 			if (j->state == PSTOPPED &&
   1129 			    (j->saved_ttypgrp = tcgetpgrp(tty_fd)) >= 0)
   1130 				j->flags |= JF_SAVEDTTYPGRP;
   1131 			if (tcsetpgrp(tty_fd, kshpgrp) < 0)
   1132 				warningf(true, "%s %s(%d, %ld) %s: %s",
   1133 				    "j_waitj:", "tcsetpgrp", tty_fd,
   1134 				    (long)kshpgrp, "failed", cstrerror(errno));
   1135 			if (j->state == PSTOPPED) {
   1136 				j->flags |= JF_SAVEDTTY;
   1137 				mksh_tcget(tty_fd, &j->ttystat);
   1138 			}
   1139 		}
   1140 #endif
   1141 		if (tty_hasstate) {
   1142 			/*
   1143 			 * Only restore tty settings if job was originally
   1144 			 * started in the foreground. Problems can be
   1145 			 * caused by things like 'more foobar &' which will
   1146 			 * typically get and save the shell's vi/emacs tty
   1147 			 * settings before setting up the tty for itself;
   1148 			 * when more exits, it restores the 'original'
   1149 			 * settings, and things go down hill from there...
   1150 			 */
   1151 			if (j->state == PEXITED && j->status == 0 &&
   1152 			    (j->flags & JF_USETTYMODE)) {
   1153 				mksh_tcget(tty_fd, &tty_state);
   1154 			} else {
   1155 				mksh_tcset(tty_fd, &tty_state);
   1156 				/*-
   1157 				 * Don't use tty mode if job is stopped and
   1158 				 * later restarted and exits. Consider
   1159 				 * the sequence:
   1160 				 *	vi foo (stopped)
   1161 				 *	...
   1162 				 *	stty something
   1163 				 *	...
   1164 				 *	fg (vi; ZZ)
   1165 				 * mode should be that of the stty, not what
   1166 				 * was before the vi started.
   1167 				 */
   1168 				if (j->state == PSTOPPED)
   1169 					j->flags &= ~JF_USETTYMODE;
   1170 			}
   1171 		}
   1172 #ifndef MKSH_UNEMPLOYED
   1173 		/*
   1174 		 * If it looks like user hit ^C to kill a job, pretend we got
   1175 		 * one too to break out of for loops, etc. (AT&T ksh does this
   1176 		 * even when not monitoring, but this doesn't make sense since
   1177 		 * a tty generated ^C goes to the whole process group)
   1178 		 */
   1179 		{
   1180 			int status;
   1181 
   1182 			status = j->last_proc->status;
   1183 			if (Flag(FMONITOR) && j->state == PSIGNALLED &&
   1184 			    WIFSIGNALED(status) &&
   1185 			    (sigtraps[WTERMSIG(status)].flags & TF_TTY_INTR))
   1186 				trapsig(WTERMSIG(status));
   1187 		}
   1188 #endif
   1189 	}
   1190 
   1191 	j_usrtime = j->usrtime;
   1192 	j_systime = j->systime;
   1193 	rv = j->status;
   1194 
   1195 	if ((flags & JW_PIPEST) && (j->proc_list != NULL)) {
   1196 		uint32_t num = 0;
   1197 		Proc *p = j->proc_list;
   1198 		struct tbl *vp;
   1199 
   1200 		unset(vp_pipest, 1);
   1201 		vp = vp_pipest;
   1202 		vp->flag = DEFINED | ISSET | INTEGER | RDONLY | ARRAY | INT_U;
   1203 		goto got_array;
   1204 
   1205 		while (p != NULL) {
   1206 			{
   1207 				struct tbl *vq;
   1208 
   1209 				/* strlen(vp_pipest->name) == 10 */
   1210 				vq = alloc(offsetof(struct tbl, name[0]) + 11,
   1211 				    vp_pipest->areap);
   1212 				memset(vq, 0, offsetof(struct tbl, name[0]));
   1213 				memcpy(vq->name, vp_pipest->name, 11);
   1214 				vp->u.array = vq;
   1215 				vp = vq;
   1216 			}
   1217 			vp->areap = vp_pipest->areap;
   1218 			vp->ua.index = ++num;
   1219 			vp->flag = DEFINED | ISSET | INTEGER | RDONLY |
   1220 			    ARRAY | INT_U | AINDEX;
   1221  got_array:
   1222 			vp->val.i = proc_errorlevel(p);
   1223 			p = p->next;
   1224 		}
   1225 	}
   1226 
   1227 	if (!(flags & JW_ASYNCNOTIFY)
   1228 #ifndef MKSH_UNEMPLOYED
   1229 	    && (!Flag(FMONITOR) || j->state != PSTOPPED)
   1230 #endif
   1231 	    ) {
   1232 		j_print(j, JP_SHORT, shl_out);
   1233 		shf_flush(shl_out);
   1234 	}
   1235 	if (j->state != PSTOPPED
   1236 #ifndef MKSH_UNEMPLOYED
   1237 	    && (!Flag(FMONITOR) || !(flags & JW_ASYNCNOTIFY))
   1238 #endif
   1239 	    )
   1240 		remove_job(j, where);
   1241 
   1242 	return (rv);
   1243 }
   1244 
   1245 /*
   1246  * SIGCHLD handler to reap children and update job states
   1247  *
   1248  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1249  */
   1250 /* ARGSUSED */
   1251 static void
   1252 j_sigchld(int sig MKSH_A_UNUSED)
   1253 {
   1254 	/* this runs inside interrupt context, with errno saved */
   1255 
   1256 	Job *j;
   1257 	Proc *p = NULL;
   1258 	pid_t pid;
   1259 	int status;
   1260 	struct rusage ru0, ru1;
   1261 #ifdef MKSH_NO_SIGSUSPEND
   1262 	sigset_t omask;
   1263 
   1264 	/* this handler can run while SIGCHLD is not blocked, so block it now */
   1265 	sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
   1266 #endif
   1267 
   1268 #ifndef MKSH_NOPROSPECTOFWORK
   1269 	/*
   1270 	 * Don't wait for any processes if a job is partially started.
   1271 	 * This is so we don't do away with the process group leader
   1272 	 * before all the processes in a pipe line are started (so the
   1273 	 * setpgid() won't fail)
   1274 	 */
   1275 	for (j = job_list; j; j = j->next)
   1276 		if (j->ppid == procpid && !(j->flags & JF_STARTED)) {
   1277 			held_sigchld = 1;
   1278 			goto j_sigchld_out;
   1279 		}
   1280 #endif
   1281 
   1282 	getrusage(RUSAGE_CHILDREN, &ru0);
   1283 	do {
   1284 #ifndef MKSH_NOPROSPECTOFWORK
   1285 		pid = waitpid(-1, &status, (WNOHANG|WUNTRACED));
   1286 #else
   1287 		pid = wait(&status);
   1288 #endif
   1289 
   1290 		/*
   1291 		 * return if this would block (0) or no children
   1292 		 * or interrupted (-1)
   1293 		 */
   1294 		if (pid <= 0)
   1295 			goto j_sigchld_out;
   1296 
   1297 		getrusage(RUSAGE_CHILDREN, &ru1);
   1298 
   1299 		/* find job and process structures for this pid */
   1300 		for (j = job_list; j != NULL; j = j->next)
   1301 			for (p = j->proc_list; p != NULL; p = p->next)
   1302 				if (p->pid == pid)
   1303 					goto found;
   1304  found:
   1305 		if (j == NULL) {
   1306 			/* Can occur if process has kids, then execs shell
   1307 			warningf(true, "bad process waited for (pid = %d)",
   1308 				pid);
   1309 			 */
   1310 			ru0 = ru1;
   1311 			continue;
   1312 		}
   1313 
   1314 		timeradd(&j->usrtime, &ru1.ru_utime, &j->usrtime);
   1315 		timersub(&j->usrtime, &ru0.ru_utime, &j->usrtime);
   1316 		timeradd(&j->systime, &ru1.ru_stime, &j->systime);
   1317 		timersub(&j->systime, &ru0.ru_stime, &j->systime);
   1318 		ru0 = ru1;
   1319 		p->status = status;
   1320 #ifndef MKSH_UNEMPLOYED
   1321 		if (WIFSTOPPED(status))
   1322 			p->state = PSTOPPED;
   1323 		else
   1324 #endif
   1325 		  if (WIFSIGNALED(status))
   1326 			p->state = PSIGNALLED;
   1327 		else
   1328 			p->state = PEXITED;
   1329 
   1330 		/* check to see if entire job is done */
   1331 		check_job(j);
   1332 	}
   1333 #ifndef MKSH_NOPROSPECTOFWORK
   1334 	    while (/* CONSTCOND */ 1);
   1335 #else
   1336 	    while (/* CONSTCOND */ 0);
   1337 #endif
   1338 
   1339  j_sigchld_out:
   1340 #ifdef MKSH_NO_SIGSUSPEND
   1341 	sigprocmask(SIG_SETMASK, &omask, NULL);
   1342 #endif
   1343 	/* nothing */;
   1344 }
   1345 
   1346 /*
   1347  * Called only when a process in j has exited/stopped (ie, called only
   1348  * from j_sigchld()). If no processes are running, the job status
   1349  * and state are updated, asynchronous job notification is done and,
   1350  * if unneeded, the job is removed.
   1351  *
   1352  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1353  */
   1354 static void
   1355 check_job(Job *j)
   1356 {
   1357 	int	jstate;
   1358 	Proc	*p;
   1359 
   1360 	/* XXX debugging (nasty - interrupt routine using shl_out) */
   1361 	if (!(j->flags & JF_STARTED)) {
   1362 		internal_warningf("check_job: job started (flags 0x%x)",
   1363 		    j->flags);
   1364 		return;
   1365 	}
   1366 
   1367 	jstate = PRUNNING;
   1368 	for (p=j->proc_list; p != NULL; p = p->next) {
   1369 		if (p->state == PRUNNING)
   1370 			/* some processes still running */
   1371 			return;
   1372 		if (p->state > jstate)
   1373 			jstate = p->state;
   1374 	}
   1375 	j->state = jstate;
   1376 	j->status = proc_errorlevel(j->last_proc);
   1377 
   1378 	/*
   1379 	 * Note when co-process dies: can't be done in j_wait() nor
   1380 	 * remove_job() since neither may be called for non-interactive
   1381 	 * shells.
   1382 	 */
   1383 	if (j->state == PEXITED || j->state == PSIGNALLED) {
   1384 		/*
   1385 		 * No need to keep co-process input any more
   1386 		 * (at least, this is what ksh93d thinks)
   1387 		 */
   1388 		if (coproc.job == j) {
   1389 			coproc.job = NULL;
   1390 			/*
   1391 			 * XXX would be nice to get the closes out of here
   1392 			 * so they aren't done in the signal handler.
   1393 			 * Would mean a check in coproc_getfd() to
   1394 			 * do "if job == 0 && write >= 0, close write".
   1395 			 */
   1396 			coproc_write_close(coproc.write);
   1397 		}
   1398 		/* Do we need to keep the output? */
   1399 		if (j->coproc_id && j->coproc_id == coproc.id &&
   1400 		    --coproc.njobs == 0)
   1401 			coproc_readw_close(coproc.read);
   1402 	}
   1403 
   1404 	j->flags |= JF_CHANGED;
   1405 #ifndef MKSH_UNEMPLOYED
   1406 	if (Flag(FMONITOR) && !(j->flags & JF_XXCOM)) {
   1407 		/*
   1408 		 * Only put stopped jobs at the front to avoid confusing
   1409 		 * the user (don't want finished jobs effecting %+ or %-)
   1410 		 */
   1411 		if (j->state == PSTOPPED)
   1412 			put_job(j, PJ_ON_FRONT);
   1413 		if (Flag(FNOTIFY) &&
   1414 		    (j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY)) != JF_WAITING) {
   1415 			/* Look for the real file descriptor 2 */
   1416 			{
   1417 				struct env *ep;
   1418 				int fd = 2;
   1419 
   1420 				for (ep = e; ep; ep = ep->oenv)
   1421 					if (ep->savefd && ep->savefd[2])
   1422 						fd = ep->savefd[2];
   1423 				shf_reopen(fd, SHF_WR, shl_j);
   1424 			}
   1425 			/*
   1426 			 * Can't call j_notify() as it removes jobs. The job
   1427 			 * must stay in the job list as j_waitj() may be
   1428 			 * running with this job.
   1429 			 */
   1430 			j_print(j, JP_MEDIUM, shl_j);
   1431 			shf_flush(shl_j);
   1432 			if (!(j->flags & JF_WAITING) && j->state != PSTOPPED)
   1433 				remove_job(j, "notify");
   1434 		}
   1435 	}
   1436 #endif
   1437 	if (
   1438 #ifndef MKSH_UNEMPLOYED
   1439 	    !Flag(FMONITOR) &&
   1440 #endif
   1441 	    !(j->flags & (JF_WAITING|JF_FG)) &&
   1442 	    j->state != PSTOPPED) {
   1443 		if (j == async_job || (j->flags & JF_KNOWN)) {
   1444 			j->flags |= JF_ZOMBIE;
   1445 			j->job = -1;
   1446 			nzombie++;
   1447 		} else
   1448 			remove_job(j, "checkjob");
   1449 	}
   1450 }
   1451 
   1452 /*
   1453  * Print job status in either short, medium or long format.
   1454  *
   1455  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1456  */
   1457 static void
   1458 j_print(Job *j, int how, struct shf *shf)
   1459 {
   1460 	Proc	*p;
   1461 	int	state;
   1462 	int	status;
   1463 	int	coredumped;
   1464 	char	jobchar = ' ';
   1465 	char	buf[64];
   1466 	const char *filler;
   1467 	int	output = 0;
   1468 
   1469 	if (how == JP_PGRP) {
   1470 		/*
   1471 		 * POSIX doesn't say what to do it there is no process
   1472 		 * group leader (ie, !FMONITOR). We arbitrarily return
   1473 		 * last pid (which is what $! returns).
   1474 		 */
   1475 		shf_fprintf(shf, "%d\n", (int)(j->pgrp ? j->pgrp :
   1476 		    (j->last_proc ? j->last_proc->pid : 0)));
   1477 		return;
   1478 	}
   1479 	j->flags &= ~JF_CHANGED;
   1480 	filler = j->job > 10 ? "\n       " : "\n      ";
   1481 	if (j == job_list)
   1482 		jobchar = '+';
   1483 	else if (j == job_list->next)
   1484 		jobchar = '-';
   1485 
   1486 	for (p = j->proc_list; p != NULL;) {
   1487 		coredumped = 0;
   1488 		switch (p->state) {
   1489 		case PRUNNING:
   1490 			memcpy(buf, "Running", 8);
   1491 			break;
   1492 		case PSTOPPED:
   1493 			strlcpy(buf, sigtraps[WSTOPSIG(p->status)].mess,
   1494 			    sizeof(buf));
   1495 			break;
   1496 		case PEXITED:
   1497 			if (how == JP_SHORT)
   1498 				buf[0] = '\0';
   1499 			else if (WEXITSTATUS(p->status) == 0)
   1500 				memcpy(buf, "Done", 5);
   1501 			else
   1502 				shf_snprintf(buf, sizeof(buf), "Done (%d)",
   1503 				    WEXITSTATUS(p->status));
   1504 			break;
   1505 		case PSIGNALLED:
   1506 #ifdef WCOREDUMP
   1507 			if (WCOREDUMP(p->status))
   1508 				coredumped = 1;
   1509 #endif
   1510 			/*
   1511 			 * kludge for not reporting 'normal termination
   1512 			 * signals' (i.e. SIGINT, SIGPIPE)
   1513 			 */
   1514 			if (how == JP_SHORT && !coredumped &&
   1515 			    (WTERMSIG(p->status) == SIGINT ||
   1516 			    WTERMSIG(p->status) == SIGPIPE)) {
   1517 				buf[0] = '\0';
   1518 			} else
   1519 				strlcpy(buf, sigtraps[WTERMSIG(p->status)].mess,
   1520 				    sizeof(buf));
   1521 			break;
   1522 		default:
   1523 			buf[0] = '\0';
   1524 		}
   1525 
   1526 		if (how != JP_SHORT) {
   1527 			if (p == j->proc_list)
   1528 				shf_fprintf(shf, "[%d] %c ", j->job, jobchar);
   1529 			else
   1530 				shf_puts(filler, shf);
   1531 		}
   1532 
   1533 		if (how == JP_LONG)
   1534 			shf_fprintf(shf, "%5d ", (int)p->pid);
   1535 
   1536 		if (how == JP_SHORT) {
   1537 			if (buf[0]) {
   1538 				output = 1;
   1539 				shf_fprintf(shf, "%s%s ",
   1540 				    buf, coredumped ? " (core dumped)" : null);
   1541 			}
   1542 		} else {
   1543 			output = 1;
   1544 			shf_fprintf(shf, "%-20s %s%s%s", buf, p->command,
   1545 			    p->next ? "|" : null,
   1546 			    coredumped ? " (core dumped)" : null);
   1547 		}
   1548 
   1549 		state = p->state;
   1550 		status = p->status;
   1551 		p = p->next;
   1552 		while (p && p->state == state && p->status == status) {
   1553 			if (how == JP_LONG)
   1554 				shf_fprintf(shf, "%s%5d %-20s %s%s", filler,
   1555 				    (int)p->pid, " ", p->command,
   1556 				    p->next ? "|" : null);
   1557 			else if (how == JP_MEDIUM)
   1558 				shf_fprintf(shf, " %s%s", p->command,
   1559 				    p->next ? "|" : null);
   1560 			p = p->next;
   1561 		}
   1562 	}
   1563 	if (output)
   1564 		shf_putc('\n', shf);
   1565 }
   1566 
   1567 /*
   1568  * Convert % sequence to job
   1569  *
   1570  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1571  */
   1572 static Job *
   1573 j_lookup(const char *cp, int *ecodep)
   1574 {
   1575 	Job *j, *last_match;
   1576 	Proc *p;
   1577 	size_t len;
   1578 	int job = 0;
   1579 
   1580 	if (ksh_isdigit(*cp)) {
   1581 		getn(cp, &job);
   1582 		/* Look for last_proc->pid (what $! returns) first... */
   1583 		for (j = job_list; j != NULL; j = j->next)
   1584 			if (j->last_proc && j->last_proc->pid == job)
   1585 				return (j);
   1586 		/*
   1587 		 * ...then look for process group (this is non-POSIX,
   1588 		 * but should not break anything
   1589 		 */
   1590 		for (j = job_list; j != NULL; j = j->next)
   1591 			if (j->pgrp && j->pgrp == job)
   1592 				return (j);
   1593 		if (ecodep)
   1594 			*ecodep = JL_NOSUCH;
   1595 		return (NULL);
   1596 	}
   1597 	if (*cp != '%') {
   1598 		if (ecodep)
   1599 			*ecodep = JL_INVALID;
   1600 		return (NULL);
   1601 	}
   1602 	switch (*++cp) {
   1603 	case '\0': /* non-standard */
   1604 	case '+':
   1605 	case '%':
   1606 		if (job_list != NULL)
   1607 			return (job_list);
   1608 		break;
   1609 
   1610 	case '-':
   1611 		if (job_list != NULL && job_list->next)
   1612 			return (job_list->next);
   1613 		break;
   1614 
   1615 	case '0': case '1': case '2': case '3': case '4':
   1616 	case '5': case '6': case '7': case '8': case '9':
   1617 		getn(cp, &job);
   1618 		for (j = job_list; j != NULL; j = j->next)
   1619 			if (j->job == job)
   1620 				return (j);
   1621 		break;
   1622 
   1623 	/* %?string */
   1624 	case '?':
   1625 		last_match = NULL;
   1626 		for (j = job_list; j != NULL; j = j->next)
   1627 			for (p = j->proc_list; p != NULL; p = p->next)
   1628 				if (strstr(p->command, cp+1) != NULL) {
   1629 					if (last_match) {
   1630 						if (ecodep)
   1631 							*ecodep = JL_AMBIG;
   1632 						return (NULL);
   1633 					}
   1634 					last_match = j;
   1635 				}
   1636 		if (last_match)
   1637 			return (last_match);
   1638 		break;
   1639 
   1640 	/* %string */
   1641 	default:
   1642 		len = strlen(cp);
   1643 		last_match = NULL;
   1644 		for (j = job_list; j != NULL; j = j->next)
   1645 			if (strncmp(cp, j->proc_list->command, len) == 0) {
   1646 				if (last_match) {
   1647 					if (ecodep)
   1648 						*ecodep = JL_AMBIG;
   1649 					return (NULL);
   1650 				}
   1651 				last_match = j;
   1652 			}
   1653 		if (last_match)
   1654 			return (last_match);
   1655 		break;
   1656 	}
   1657 	if (ecodep)
   1658 		*ecodep = JL_NOSUCH;
   1659 	return (NULL);
   1660 }
   1661 
   1662 static Job	*free_jobs;
   1663 static Proc	*free_procs;
   1664 
   1665 /*
   1666  * allocate a new job and fill in the job number.
   1667  *
   1668  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1669  */
   1670 static Job *
   1671 new_job(void)
   1672 {
   1673 	int	i;
   1674 	Job	*newj, *j;
   1675 
   1676 	if (free_jobs != NULL) {
   1677 		newj = free_jobs;
   1678 		free_jobs = free_jobs->next;
   1679 	} else
   1680 		newj = alloc(sizeof(Job), APERM);
   1681 
   1682 	/* brute force method */
   1683 	for (i = 1; ; i++) {
   1684 		for (j = job_list; j && j->job != i; j = j->next)
   1685 			;
   1686 		if (j == NULL)
   1687 			break;
   1688 	}
   1689 	newj->job = i;
   1690 
   1691 	return (newj);
   1692 }
   1693 
   1694 /*
   1695  * Allocate new process struct
   1696  *
   1697  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1698  */
   1699 static Proc *
   1700 new_proc(void)
   1701 {
   1702 	Proc	*p;
   1703 
   1704 	if (free_procs != NULL) {
   1705 		p = free_procs;
   1706 		free_procs = free_procs->next;
   1707 	} else
   1708 		p = alloc(sizeof(Proc), APERM);
   1709 
   1710 	return (p);
   1711 }
   1712 
   1713 /*
   1714  * Take job out of job_list and put old structures into free list.
   1715  * Keeps nzombies, last_job and async_job up to date.
   1716  *
   1717  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1718  */
   1719 static void
   1720 remove_job(Job *j, const char *where)
   1721 {
   1722 	Proc	*p, *tmp;
   1723 	Job	**prev, *curr;
   1724 
   1725 	mkssert(j != NULL);
   1726 	prev = &job_list;
   1727 	curr = job_list;
   1728 	while (curr && curr != j) {
   1729 		prev = &curr->next;
   1730 		curr = *prev;
   1731 	}
   1732 	if (curr != j) {
   1733 		internal_warningf("remove_job: job %s (%s)", "not found", where);
   1734 		return;
   1735 	}
   1736 	*prev = curr->next;
   1737 
   1738 	/* free up proc structures */
   1739 	for (p = j->proc_list; p != NULL; ) {
   1740 		tmp = p;
   1741 		p = p->next;
   1742 		tmp->next = free_procs;
   1743 		free_procs = tmp;
   1744 	}
   1745 
   1746 	if ((j->flags & JF_ZOMBIE) && j->ppid == procpid)
   1747 		--nzombie;
   1748 	j->next = free_jobs;
   1749 	free_jobs = j;
   1750 
   1751 	if (j == last_job)
   1752 		last_job = NULL;
   1753 	if (j == async_job)
   1754 		async_job = NULL;
   1755 }
   1756 
   1757 /*
   1758  * put j in a particular location (taking it out job_list if it is there
   1759  * already)
   1760  *
   1761  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1762  */
   1763 static void
   1764 put_job(Job *j, int where)
   1765 {
   1766 	Job	**prev, *curr;
   1767 
   1768 	mkssert(j != NULL);
   1769 	/* Remove job from list (if there) */
   1770 	prev = &job_list;
   1771 	curr = job_list;
   1772 	while (curr && curr != j) {
   1773 		prev = &curr->next;
   1774 		curr = *prev;
   1775 	}
   1776 	if (curr == j)
   1777 		*prev = curr->next;
   1778 
   1779 	switch (where) {
   1780 	case PJ_ON_FRONT:
   1781 		j->next = job_list;
   1782 		job_list = j;
   1783 		break;
   1784 
   1785 	case PJ_PAST_STOPPED:
   1786 		prev = &job_list;
   1787 		curr = job_list;
   1788 		for (; curr && curr->state == PSTOPPED; prev = &curr->next,
   1789 		    curr = *prev)
   1790 			;
   1791 		j->next = curr;
   1792 		*prev = j;
   1793 		break;
   1794 	}
   1795 }
   1796 
   1797 /*
   1798  * nuke a job (called when unable to start full job).
   1799  *
   1800  * If jobs are compiled in then this routine expects sigchld to be blocked.
   1801  */
   1802 static int
   1803 kill_job(Job *j, int sig)
   1804 {
   1805 	Proc	*p;
   1806 	int	rval = 0;
   1807 
   1808 	for (p = j->proc_list; p != NULL; p = p->next)
   1809 		if (p->pid != 0)
   1810 			if (kill(p->pid, sig) < 0)
   1811 				rval = -1;
   1812 	return (rval);
   1813 }
   1814 
   1815 static void
   1816 tty_init_talking(void)
   1817 {
   1818 	switch (tty_init_fd()) {
   1819 	case 0:
   1820 		break;
   1821 	case 1:
   1822 #ifndef MKSH_DISABLE_TTY_WARNING
   1823 		warningf(false, "%s: %s %s: %s",
   1824 		    "No controlling tty", "open", "/dev/tty",
   1825 		    cstrerror(errno));
   1826 #endif
   1827 		break;
   1828 	case 2:
   1829 #ifndef MKSH_DISABLE_TTY_WARNING
   1830 		warningf(false, "%s: %s", "can't find tty fd", cstrerror(errno));
   1831 #endif
   1832 		break;
   1833 	case 3:
   1834 		warningf(false, "%s: %s %s: %s", "j_ttyinit",
   1835 		    "dup of tty fd", "failed", cstrerror(errno));
   1836 		break;
   1837 	case 4:
   1838 		warningf(false, "%s: %s: %s", "j_ttyinit",
   1839 		    "can't set close-on-exec flag", cstrerror(errno));
   1840 		break;
   1841 	}
   1842 }
   1843 
   1844 static void
   1845 tty_init_state(void)
   1846 {
   1847 	if (tty_fd >= 0) {
   1848 		mksh_tcget(tty_fd, &tty_state);
   1849 		tty_hasstate = true;
   1850 	}
   1851 }
   1852