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