Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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