xref: /original-bsd/local/toolchest/ksh.2/sh/jobs.c (revision 0892692d)
1bfbe053bSmarc #define USE_OLD_TTY
2bfbe053bSmarc /*
3bfbe053bSmarc 
4bfbe053bSmarc  *      Copyright (c) 1984, 1985, 1986 AT&T
5bfbe053bSmarc  *      All Rights Reserved
6bfbe053bSmarc 
7bfbe053bSmarc  *      THIS IS UNPUBLISHED PROPRIETARY SOURCE
8bfbe053bSmarc  *      CODE OF AT&T.
9bfbe053bSmarc  *      The copyright notice above does not
10bfbe053bSmarc  *      evidence any actual or intended
11bfbe053bSmarc  *      publication of such source code.
12bfbe053bSmarc 
13bfbe053bSmarc  */
14bfbe053bSmarc /* @(#)jobs.c	1.1 */
15bfbe053bSmarc 
16bfbe053bSmarc /*
17bfbe053bSmarc  *  Job control for UNIX Shell
18bfbe053bSmarc  *
19bfbe053bSmarc  *   David Korn
20bfbe053bSmarc  *   AT&T Bell Laboratories
21bfbe053bSmarc  *   Room 5D-112
22bfbe053bSmarc  *   Murray Hill, N. J. 07974
23bfbe053bSmarc  *   Tel. x7975
24bfbe053bSmarc  *
25bfbe053bSmarc  *  Written October, 1982
26bfbe053bSmarc  */
27bfbe053bSmarc 
28bfbe053bSmarc 
29bfbe053bSmarc #include	<errno.h>
30bfbe053bSmarc 
31bfbe053bSmarc #ifdef BSD
32bfbe053bSmarc # ifdef BSD_4_2
33bfbe053bSmarc #include	<sys/wait.h>
34bfbe053bSmarc # else
35bfbe053bSmarc #include	<wait.h>
36bfbe053bSmarc # endif /* BSD_4_2 */
37bfbe053bSmarc #endif	/* BSD */
38bfbe053bSmarc 
39bfbe053bSmarc #ifdef SXT
40bfbe053bSmarc #define		SIGSTOP	20
41bfbe053bSmarc #define		SIGSTIN	21
42bfbe053bSmarc #include	<sys/types.h>
43bfbe053bSmarc #include	<sys/tty.h>
44bfbe053bSmarc #include	<sys/sxt.h>
45bfbe053bSmarc #include	<sys/stat.h>
46bfbe053bSmarc #endif	/* SXT */
47bfbe053bSmarc 
48bfbe053bSmarc #include	"defs.h"
49bfbe053bSmarc #include	"flags.h"
50bfbe053bSmarc #include	"shtype.h"
51bfbe053bSmarc #include	"jobs.h"
52bfbe053bSmarc #include	"brkincr.h"
53bfbe053bSmarc #include	"io.h"
54bfbe053bSmarc #include	"history.h"
55bfbe053bSmarc 
56bfbe053bSmarc #ifdef SXT
57bfbe053bSmarc #undef input
58bfbe053bSmarc static status_update();
59bfbe053bSmarc static int open_chan();
60bfbe053bSmarc static int fd_chan = -1;
61bfbe053bSmarc static char tinybuf;
62bfbe053bSmarc #endif	/* SXT */
63bfbe053bSmarc 
64bfbe053bSmarc #define LOBYTE	0377
65bfbe053bSmarc #define MAXMSG	25
66bfbe053bSmarc 
67bfbe053bSmarc void	await();
68bfbe053bSmarc void	postclr();
69bfbe053bSmarc 
70bfbe053bSmarc extern void	fault();
71bfbe053bSmarc extern long	hist_list();
72bfbe053bSmarc extern long	hist_position();
73bfbe053bSmarc extern char	*itos();
74bfbe053bSmarc extern char	*malloc();
75bfbe053bSmarc extern void	failed();
76bfbe053bSmarc extern void	free();
77bfbe053bSmarc extern void	p_str();
78bfbe053bSmarc extern void	p_prp();
79bfbe053bSmarc extern void	p_num();
80bfbe053bSmarc extern void	p_sub();
81bfbe053bSmarc extern void	p_nchr();
82bfbe053bSmarc extern void	p_flush();
83bfbe053bSmarc extern void	p_setout();
84bfbe053bSmarc 
85bfbe053bSmarc static int	set_ttygrp();
86bfbe053bSmarc static int	set_job();
87bfbe053bSmarc static int	reset_ttygrp();
88bfbe053bSmarc static struct process *next_proc();
89bfbe053bSmarc static struct process *jobbyname();
90bfbe053bSmarc static struct process *job_bynum();
91bfbe053bSmarc static struct process *job_bypid();
92bfbe053bSmarc static struct process *job_post();
93bfbe053bSmarc static struct process *unpost();
94bfbe053bSmarc static struct process *pgrp_jobs();
95bfbe053bSmarc static int get_job();
96bfbe053bSmarc static int match_jobname();
97bfbe053bSmarc static int unstop();
98bfbe053bSmarc static void free_job();
99bfbe053bSmarc static void pw_unlink();
100bfbe053bSmarc static struct process *freelist;
101bfbe053bSmarc #define	numrun	jobstat.p_numrun	/* number of running jobs */
102bfbe053bSmarc #define	numpost	jobstat.p_numpost	/* number of posted jobs */
103bfbe053bSmarc #define	pwlist	jobstat.p_pwlist
104bfbe053bSmarc #define freejobs jobstat.p_freejobs	/* free job numbers */
105bfbe053bSmarc static long pr_jobname();
106bfbe053bSmarc 
107bfbe053bSmarc #ifdef FIOLOOKLD
108bfbe053bSmarc #define version8	1
109bfbe053bSmarc extern int tty_ld, ntty_ld;
110bfbe053bSmarc #define OTTYDISC	tty_ld
111bfbe053bSmarc #define NTTYDISC	ntty_ld
112bfbe053bSmarc #endif	/* FIOLOOKLD */
113bfbe053bSmarc 
114bfbe053bSmarc 
115bfbe053bSmarc static int savepgrp;
116bfbe053bSmarc static int savetgrp;
117bfbe053bSmarc static BOOL old_driver;
118bfbe053bSmarc static BOOL beenhere;
119bfbe053bSmarc static int saveldisc;
120bfbe053bSmarc 
121bfbe053bSmarc #ifdef POSIX
122bfbe053bSmarc static struct termios my_stty;		/* terminal state for shell */
123bfbe053bSmarc #else
124bfbe053bSmarc # ifdef BSD
125bfbe053bSmarc static struct sgttyb my_stty;		/* terminal state for shell */
126bfbe053bSmarc # else
127bfbe053bSmarc static struct termio my_stty;		/* terminal state for shell */
128bfbe053bSmarc # endif	/* BSD */
129bfbe053bSmarc #endif /* !POSIX */
130bfbe053bSmarc 
131bfbe053bSmarc #ifdef BSD
132bfbe053bSmarc /*
133bfbe053bSmarc  * initialize job control
134bfbe053bSmarc  * if lflag is set the switching driver message will not print
135bfbe053bSmarc  */
136bfbe053bSmarc 
init_jobs(lflag)137bfbe053bSmarc int init_jobs(lflag)
138bfbe053bSmarc {
139bfbe053bSmarc 	int ldisc;
140bfbe053bSmarc 	register int ntry = 0;
141bfbe053bSmarc 	register int pid;
142bfbe053bSmarc 	jobstat.mypid = pid = getpid();
143bfbe053bSmarc 	savepgrp = getpgrp(pid);
144bfbe053bSmarc # ifdef version8
145bfbe053bSmarc 	if((ldisc = ioctl (2, FIOLOOKLD, 0)) <0)
146bfbe053bSmarc # else
147bfbe053bSmarc 	if(ioctl(2,TIOCGETD,&ldisc) !=0)
148bfbe053bSmarc # endif /* version8 */
149bfbe053bSmarc 		return(-1);
150bfbe053bSmarc 	if(ldisc!=NTTYDISC
151bfbe053bSmarc #ifdef notdef /*POSIX*/
152bfbe053bSmarc 	   && ldisc!=POSXDISC
153bfbe053bSmarc #endif
154bfbe053bSmarc 	   && ldisc!=OTTYDISC)
155bfbe053bSmarc 	{
156bfbe053bSmarc 		/* no job control when running with MPX */
157bfbe053bSmarc # ifdef VSH
158bfbe053bSmarc 		on_option(VIRAW);
159bfbe053bSmarc # endif /* VSH */
160bfbe053bSmarc 		return(-1);
161bfbe053bSmarc 	}
162bfbe053bSmarc retry:
163bfbe053bSmarc 	signal(SIGTTOU,SIG_IGN);
164bfbe053bSmarc 	if(ioctl(2,TIOCGPGRP,&savetgrp) !=0)
165bfbe053bSmarc 	{
166bfbe053bSmarc 		fputs(j_not_tty,output);
167bfbe053bSmarc 		return(-1);
168bfbe053bSmarc 	}
169bfbe053bSmarc 	/* This shell must be in foreground to change state */
170bfbe053bSmarc 	if(savetgrp != savepgrp)
171bfbe053bSmarc 	{
172bfbe053bSmarc 		signal(SIGTTOU,SIG_DFL);
173bfbe053bSmarc 		kill(pid,SIGTTOU);
174bfbe053bSmarc 		/* wait for continue and try again */
175bfbe053bSmarc 		if(ntry++ > 100)
176bfbe053bSmarc 		{
177bfbe053bSmarc 			fputs(j_no_start,output);
178bfbe053bSmarc 			return(-1);
179bfbe053bSmarc 		}
180bfbe053bSmarc 		goto retry;
181bfbe053bSmarc 	}
182bfbe053bSmarc #ifdef notdef /*POSIX*/
183bfbe053bSmarc 	if(ldisc != POSXDISC)
184bfbe053bSmarc 	{
185bfbe053bSmarc 		saveldisc = ldisc;
186bfbe053bSmarc 		ldisc = POSXDISC;
187bfbe053bSmarc #else
188bfbe053bSmarc 	if(ldisc == OTTYDISC)
189bfbe053bSmarc 	{
190bfbe053bSmarc 		ldisc = NTTYDISC;
191bfbe053bSmarc #endif
192bfbe053bSmarc # ifdef version8
193bfbe053bSmarc 		ioctl(2,TIOCGETP,&my_stty);
194bfbe053bSmarc 		if (ioctl(2, FIOPOPLD, 0) < 0)
195bfbe053bSmarc 			return(-1);
196bfbe053bSmarc 		if (ioctl(2, FIOPUSHLD, &ldisc, 0) < 0)
197bfbe053bSmarc 		{
198bfbe053bSmarc 			ldisc = OTTYDISC;
199bfbe053bSmarc 			 ioctl(2, FIOPUSHLD, &ldisc, 0);
200bfbe053bSmarc 			return(-1);
201bfbe053bSmarc 		}
202bfbe053bSmarc 		ioctl(2,TIOCSETN,&my_stty);
203bfbe053bSmarc # else
204bfbe053bSmarc 		if(ioctl(2,TIOCSETD,&ldisc) !=0)
205bfbe053bSmarc 			return(-1);
206bfbe053bSmarc # endif /* version8 */
207bfbe053bSmarc 		if(lflag==0)
208bfbe053bSmarc 		{
209bfbe053bSmarc 			fputs(j_newtty,output);
210bfbe053bSmarc 			old_driver++;
211bfbe053bSmarc 		}
212bfbe053bSmarc 	}
213bfbe053bSmarc 	on_option(MONITOR);
214bfbe053bSmarc 	signal(SIGCHLD,fault);
215bfbe053bSmarc 	signal(SIGTSTP,SIG_IGN);
216bfbe053bSmarc 	signal(SIGTTIN,SIG_IGN);
217*0892692dSmarc 	if (setpgrp(pid,pid) == -1) {
218*0892692dSmarc 		fputs(j_no_start,output);
219*0892692dSmarc 		return(-1);
220*0892692dSmarc 	}
221*0892692dSmarc 	if (set_ttygrp(pid) == -1) {
222*0892692dSmarc 		setpgrp(pid, savepgrp);	/* screwed if this fails */
223*0892692dSmarc 		fputs(j_no_start,output);
224*0892692dSmarc 		return(-1);
225*0892692dSmarc 	}
226*0892692dSmarc 
227bfbe053bSmarc 	return(0);
228bfbe053bSmarc }
229bfbe053bSmarc 
230bfbe053bSmarc 
231bfbe053bSmarc /*
232bfbe053bSmarc  * see if there are any stopped jobs
233bfbe053bSmarc  * restore tty driver and pgrp
234bfbe053bSmarc  */
235bfbe053bSmarc 
236bfbe053bSmarc int close_jobs()
237bfbe053bSmarc {
238bfbe053bSmarc 	register struct process *pw = pwlist;
239bfbe053bSmarc 	register int count = 0;
240bfbe053bSmarc 	int ldisc;
241bfbe053bSmarc 	if((states&MONITOR)==0)
242bfbe053bSmarc 		return(0);
243bfbe053bSmarc 	for(;pw;pw=pw->p_next)
244bfbe053bSmarc 	{
245bfbe053bSmarc 		if((pw->p_flag&P_STOPPED)==0)
246bfbe053bSmarc 			continue;
247bfbe053bSmarc 		if(beenhere)
248bfbe053bSmarc 			killpg(pw->p_pgrp,SIGTERM);
249bfbe053bSmarc 		count++;
250bfbe053bSmarc 	}
251bfbe053bSmarc 	if(beenhere++ == 0 && pwlist)
252bfbe053bSmarc 	{
253bfbe053bSmarc 		if(count)
254bfbe053bSmarc 		{
255bfbe053bSmarc 			fputs(j_terminate,output);
256bfbe053bSmarc 			return(-1);
257bfbe053bSmarc 		}
258bfbe053bSmarc 		else if(login_sh)
259bfbe053bSmarc 		{
260bfbe053bSmarc 			fputs(j_running,output);
261bfbe053bSmarc 			return(-1);
262bfbe053bSmarc 		}
263bfbe053bSmarc 	}
264bfbe053bSmarc 	set_ttygrp(savepgrp);
265bfbe053bSmarc 	if(old_driver)
266bfbe053bSmarc 	{
267bfbe053bSmarc 		/* restore old line discipline */
268bfbe053bSmarc #ifdef POSIX
269bfbe053bSmarc 		ldisc = saveldisc;
270bfbe053bSmarc #else
271bfbe053bSmarc 		ldisc = OTTYDISC;
272bfbe053bSmarc #endif
273bfbe053bSmarc # ifdef version8
274bfbe053bSmarc 		ioctl(2,TIOCGETP,&my_stty);
275bfbe053bSmarc 		if (ioctl(2, FIOPOPLD, 0) < 0)
276bfbe053bSmarc 			return(0);
277bfbe053bSmarc 		if (ioctl(2, FIOPUSHLD, &ldisc, 0) < 0)
278bfbe053bSmarc 		{
279bfbe053bSmarc 			ldisc = NTTYDISC;
280bfbe053bSmarc 			ioctl(2, FIOPUSHLD, &ldisc, 0);
281bfbe053bSmarc 			return(0);
282bfbe053bSmarc 		}
283bfbe053bSmarc 		ioctl(2,TIOCSETN,&my_stty);
284bfbe053bSmarc # else
285bfbe053bSmarc 		if(ioctl(2,TIOCSETD,&ldisc) !=0)
286bfbe053bSmarc 			return(0);
287bfbe053bSmarc # endif /* version8 */
288bfbe053bSmarc 		fputs(j_oldtty,output);
289bfbe053bSmarc 	}
290bfbe053bSmarc 	return(0);
291bfbe053bSmarc }
292bfbe053bSmarc 
293bfbe053bSmarc /*
294bfbe053bSmarc  * Set the ttygroup id to pid
295bfbe053bSmarc  */
296bfbe053bSmarc 
297bfbe053bSmarc static int set_ttygrp(pid)
298bfbe053bSmarc {
299bfbe053bSmarc 	if(ioctl(2,TIOCSPGRP,&pid) !=0)
300bfbe053bSmarc 		return(-1);
301bfbe053bSmarc 	return(0);
302bfbe053bSmarc }
303bfbe053bSmarc 
304bfbe053bSmarc /*
305bfbe053bSmarc  * Set the ttygroup id to a previously running job
306bfbe053bSmarc  */
307bfbe053bSmarc #else	/* !BSD */
308bfbe053bSmarc # ifdef SXT
309bfbe053bSmarc static char sxt[] = "/dev/sxt/000";
310bfbe053bSmarc static struct sxtblock status1,status2;
311bfbe053bSmarc 
312bfbe053bSmarc int init_jobs(lflag)
313bfbe053bSmarc {
314bfbe053bSmarc 	register int pid;
315bfbe053bSmarc 	register int dev;
316bfbe053bSmarc 	struct stat statbuf;
317bfbe053bSmarc 	jobstat.mypid = pid = getpid();
318bfbe053bSmarc 	savepgrp = getpgrp(pid);
319bfbe053bSmarc 	if(ioctl(2,SXTIOCSTAT,&status2) < 0)
320bfbe053bSmarc 		return(-1);
321bfbe053bSmarc 	if(ioctl(2,TCGETA,&my_stty) < 0)
322bfbe053bSmarc 		return(-1);
323bfbe053bSmarc 	if(fstat(2,&statbuf) < 0)
324bfbe053bSmarc 		return(-1);
325bfbe053bSmarc 	dev = statbuf.st_rdev&0xff;
326bfbe053bSmarc 	/* must be channel 0 */
327bfbe053bSmarc 	if(dev&07)
328bfbe053bSmarc 		return(-1);
329bfbe053bSmarc 	dev >>= 3;
330bfbe053bSmarc 	sxt[10] = '0' + (dev%10);
331bfbe053bSmarc 	sxt[9] = '0' + dev/10;
332bfbe053bSmarc 	my_stty.c_cc[VSWTCH] = CSWTCH;
333bfbe053bSmarc 	if(ioctl(2,TCSETAF,&my_stty) < 0)
334bfbe053bSmarc 		return(-1);
335bfbe053bSmarc 	setpgrp(pid,pid);
336bfbe053bSmarc 	jobstat.maxjob = MAXPCHAN;
337bfbe053bSmarc 	on_option(MONITOR);
338bfbe053bSmarc 	return(0);
339bfbe053bSmarc }
340bfbe053bSmarc #endif	/* SXT */
341bfbe053bSmarc 
342bfbe053bSmarc int close_jobs()
343bfbe053bSmarc {
344bfbe053bSmarc 	register struct process *pw = pwlist;
345bfbe053bSmarc 	register int count = 0;
346bfbe053bSmarc 	if((states&MONITOR)==0)
347bfbe053bSmarc 		return(0);
348bfbe053bSmarc # ifdef SXT
349bfbe053bSmarc 	for(;pw;pw=pw->p_next)
350bfbe053bSmarc 	{
351bfbe053bSmarc 		if((pw->p_flag&P_STOPPED)==0)
352bfbe053bSmarc 			continue;
353bfbe053bSmarc 		if(beenhere)
354bfbe053bSmarc 			kill(-pw->p_pgrp,SIGTERM);
355bfbe053bSmarc 		count++;
356bfbe053bSmarc 	}
357bfbe053bSmarc # endif /* SXT */
358bfbe053bSmarc 	if(beenhere++ == 0 && pwlist && login_sh)
359bfbe053bSmarc # ifdef SXT
360bfbe053bSmarc 	{
361bfbe053bSmarc 		if(count)
362bfbe053bSmarc 		{
363bfbe053bSmarc 			fputs(j_terminate,output);
364bfbe053bSmarc 			return(-1);
365bfbe053bSmarc 		}
366bfbe053bSmarc 		if(login_sh || jobstat.maxjob)
367bfbe053bSmarc # endif /* SXT */
368bfbe053bSmarc 		{
369bfbe053bSmarc 			fputs(j_running,output);
370bfbe053bSmarc 			return(-1);
371bfbe053bSmarc 		}
372bfbe053bSmarc # ifdef SXT
373bfbe053bSmarc 	}
374bfbe053bSmarc 	if(jobstat.maxjob)
375bfbe053bSmarc 		kill_all();
376bfbe053bSmarc # endif /* SXT */
377bfbe053bSmarc 	return(0);
378bfbe053bSmarc }
379bfbe053bSmarc 
380bfbe053bSmarc #endif	/* !BSD */
381bfbe053bSmarc 
382bfbe053bSmarc static int set_job(pw)
383bfbe053bSmarc register struct process *pw;
384bfbe053bSmarc {
385bfbe053bSmarc 	/* save current terminal state */
386bfbe053bSmarc #if defined(BSD) && !defined(POSIX)
387bfbe053bSmarc 	ioctl(2,TIOCGETP,&my_stty);
388bfbe053bSmarc #else
389bfbe053bSmarc 	ioctl(2,TCGETA,&my_stty);
390bfbe053bSmarc #endif	/* BSD */
391bfbe053bSmarc #ifdef SXT
392bfbe053bSmarc 	/* make sure child has opened channel */
393bfbe053bSmarc 	if(jobstat.pipe[0] > 0)
394bfbe053bSmarc 	{
395bfbe053bSmarc 		read(jobstat.pipe[0],&tinybuf,1);
396bfbe053bSmarc 		close(jobstat.pipe[0]);
397bfbe053bSmarc 		jobstat.pipe[0] = 0;
398bfbe053bSmarc 	}
399bfbe053bSmarc 	if(pw->p_job < jobstat.maxjob)
400bfbe053bSmarc 		if(ioctl(2,SXTIOCSWTCH,pw->p_job)!=0)
401bfbe053bSmarc 		{
402bfbe053bSmarc 			return(-1);
403bfbe053bSmarc 		}
404bfbe053bSmarc #endif	/* SXT */
405bfbe053bSmarc 	if(pw->p_flag&P_STTY)
406bfbe053bSmarc 	{
407bfbe053bSmarc 		/* restore terminal state for job */
408bfbe053bSmarc #if defined(BSD) && !defined(POSIX)
409bfbe053bSmarc 		ioctl(2,TIOCSETN,&pw->p_stty);
410bfbe053bSmarc #else
411bfbe053bSmarc 		ioctl(2,TCSETAF,&pw->p_stty);
412bfbe053bSmarc #endif	/* BSD */
413bfbe053bSmarc 	}
414bfbe053bSmarc #ifdef BSD
415bfbe053bSmarc 	if(ioctl(2,TIOCSPGRP,&pw->p_pgrp) !=0)
416bfbe053bSmarc 		return(-1);
417bfbe053bSmarc #endif	/* BSD */
418bfbe053bSmarc 	return(0);
419bfbe053bSmarc }
420bfbe053bSmarc 
421bfbe053bSmarc static int	reset_ttygrp(pw,flag)
422bfbe053bSmarc register struct process *pw;
423bfbe053bSmarc {
424bfbe053bSmarc 	/* save the terminal state for current job */
425bfbe053bSmarc #ifdef BSD
426bfbe053bSmarc 	if(ioctl(2,TIOCSPGRP,&jobstat.mypid) !=0)
427bfbe053bSmarc 	{
428bfbe053bSmarc 		return(-1);
429bfbe053bSmarc 	}
430bfbe053bSmarc #endif	/* BSD */
431bfbe053bSmarc #ifdef SXT
432bfbe053bSmarc 	if(pw && pw->p_job < jobstat.maxjob)
433bfbe053bSmarc 	{
434bfbe053bSmarc 		/* save the state of terminated process */
435bfbe053bSmarc 		if(flag==0 && fd_chan>=0)
436bfbe053bSmarc 		{
437bfbe053bSmarc 			if(ioctl(fd_chan,TCGETA,&pw->p_stty)==0)
438bfbe053bSmarc 			{
439bfbe053bSmarc 				my_stty = pw->p_stty;
440bfbe053bSmarc 				/* for timing problem */
441bfbe053bSmarc 				ioctl(fd_chan,TCSETAW,&my_stty);
442bfbe053bSmarc 			}
443bfbe053bSmarc 		}
444bfbe053bSmarc 		close(fd_chan);
445bfbe053bSmarc 		fd_chan = -1;
446bfbe053bSmarc 		/* grab control in channel 0 */
447bfbe053bSmarc 		ioctl(2,TCSETAW,&my_stty);
448bfbe053bSmarc 		if(ioctl(2,SXTIOCSWTCH,0)!=0)
449bfbe053bSmarc 		{
450bfbe053bSmarc 			return(-1);
451bfbe053bSmarc 		}
452bfbe053bSmarc 		if(flag==0)
453bfbe053bSmarc 			ioctl(2,TCSETAW,&my_stty);
454bfbe053bSmarc 		beenhere = 0;
455bfbe053bSmarc 		return(0);
456bfbe053bSmarc 	}
457bfbe053bSmarc #endif	/* SXT */
458bfbe053bSmarc 	if(pw && flag)
459bfbe053bSmarc 	{
460bfbe053bSmarc #if defined(BSD) && !defined(POSIX)
461bfbe053bSmarc 		if(ioctl(2,TIOCGETP,&pw->p_stty) == 0)
462bfbe053bSmarc #else
463bfbe053bSmarc 		if(ioctl(2,TCGETA,&pw->p_stty) == 0)
464bfbe053bSmarc #endif	/* BSD */
465bfbe053bSmarc 			pw->p_flag |= P_STTY;
466bfbe053bSmarc 		/* restore terminal state for job */
467bfbe053bSmarc #if defined(BSD) && !defined(POSIX)
468bfbe053bSmarc 		ioctl(2,TIOCSETN,&my_stty);
469bfbe053bSmarc #else
470bfbe053bSmarc 		ioctl(2,TCSETAF,&my_stty);
471bfbe053bSmarc #endif	/* BSD */
472bfbe053bSmarc 	}
473bfbe053bSmarc 	beenhere = 0;
474bfbe053bSmarc 	return(0);
475bfbe053bSmarc }
476bfbe053bSmarc 
477bfbe053bSmarc #if BSD || SXT
478bfbe053bSmarc 
479bfbe053bSmarc /*
480bfbe053bSmarc  * move job to foreground if bgflag == 0
481bfbe053bSmarc  * move job to background if bgflag != 0
482bfbe053bSmarc  */
483bfbe053bSmarc 
484bfbe053bSmarc switch_jobs(ajob,bgflag)
485bfbe053bSmarc register char *ajob;
486bfbe053bSmarc {
487bfbe053bSmarc 	register struct process *pw=NULL;
488bfbe053bSmarc 	register int pgrp;
489bfbe053bSmarc # ifdef SXT
490bfbe053bSmarc 	if(jobstat.maxjob==0)
491bfbe053bSmarc 		return(NULL);
492bfbe053bSmarc # endif /* SXT */
493bfbe053bSmarc 	if(*ajob)
494bfbe053bSmarc 		pw = pgrp_jobs(ajob);
495bfbe053bSmarc 	else if(pwlist)
496bfbe053bSmarc 		pw = job_bynum((int)pwlist->p_job);
497bfbe053bSmarc 	if(pw)
498bfbe053bSmarc 	{
499bfbe053bSmarc 		if(bgflag)
500bfbe053bSmarc 		{
501bfbe053bSmarc 			pgrp = pw->p_pgrp;
502bfbe053bSmarc 			if(pw->p_flag&P_STOPPED)
503bfbe053bSmarc 			{
504bfbe053bSmarc 				p_sub((int)pw->p_job,'\t');
505bfbe053bSmarc 				pr_jobname(pw,'&',0L);
506bfbe053bSmarc 				fputs(j_amp,output);
507bfbe053bSmarc 				unstop(pgrp);
508bfbe053bSmarc 			}
509bfbe053bSmarc 		}
510bfbe053bSmarc 		else
511bfbe053bSmarc 		{
512bfbe053bSmarc 			pw_unlink(pw);
513bfbe053bSmarc 			pw->p_next = pwlist;
514bfbe053bSmarc 			pwlist = pw;
515bfbe053bSmarc 			pr_jobname(pw,'&',0L);
516bfbe053bSmarc 			newline();
517bfbe053bSmarc 			await(pw->p_pid,3);
518bfbe053bSmarc 		}
519bfbe053bSmarc 	}
520bfbe053bSmarc 	return(pw!=NULL);
521bfbe053bSmarc }
522bfbe053bSmarc 
523bfbe053bSmarc /*
524bfbe053bSmarc  * list the current jobs
525bfbe053bSmarc  * flag L_FLAG for long listing
526bfbe053bSmarc  * flag N_FLAG for list only jobs marked for notification
527bfbe053bSmarc  */
528bfbe053bSmarc #endif	/* BSD */
529bfbe053bSmarc 
530bfbe053bSmarc list_jobs(flag)
531bfbe053bSmarc int flag;
532bfbe053bSmarc {
533bfbe053bSmarc 	register struct process *pw;
534bfbe053bSmarc 	register struct process *px;
535bfbe053bSmarc 	register int m;
536bfbe053bSmarc 	register struct process *py;
537bfbe053bSmarc 	int  n;
538bfbe053bSmarc 	long offset;
539bfbe053bSmarc 	int jobm = 0;
540bfbe053bSmarc 	register char *msg;
541bfbe053bSmarc 	int msize;
542bfbe053bSmarc 	if(pwlist==NULL)
543bfbe053bSmarc 		return;
544bfbe053bSmarc 	await(0,2);
545bfbe053bSmarc 	p_setout(standout);
546bfbe053bSmarc 	/* get job number corresponding to '-' */
547bfbe053bSmarc 	if(pw=pgrp_jobs("%-"))
548bfbe053bSmarc 		jobm = pw->p_job;
549bfbe053bSmarc 	for(pw=pwlist;pw;pw=py)
550bfbe053bSmarc 	{
551bfbe053bSmarc 		py = pw->p_next;
552bfbe053bSmarc 		if(pw->p_flag&P_PIPEJOB)
553bfbe053bSmarc 			continue;
554bfbe053bSmarc 		if((flag&N_FLAG) && (pw->p_flag&P_NOTIFY)==0)
555bfbe053bSmarc 			continue;
556bfbe053bSmarc 		n = pw->p_job;
557bfbe053bSmarc 		p_sub(n,' ');
558bfbe053bSmarc 		m = ' ';
559bfbe053bSmarc 		if(pw->p_job==pwlist->p_job)
560bfbe053bSmarc 			m = '+';
561bfbe053bSmarc 		else if(pw->p_job==jobm)
562bfbe053bSmarc 		{
563bfbe053bSmarc 			m = '-';
564bfbe053bSmarc 			jobm = 0;
565bfbe053bSmarc 		}
566bfbe053bSmarc 		putc(m,output);
567bfbe053bSmarc 		putc(' ',output);
568bfbe053bSmarc 		offset = 0;
569bfbe053bSmarc 		if(flag&L_FLAG)
570bfbe053bSmarc 			px = next_proc(pwlist,(int)pw->p_job);
571bfbe053bSmarc 		else
572bfbe053bSmarc 			px = pw;
573bfbe053bSmarc 		do
574bfbe053bSmarc 		{
575bfbe053bSmarc 			unsigned xitval = 0;
576bfbe053bSmarc 			if(flag&L_FLAG)
577bfbe053bSmarc 				p_num(px->p_pid,'\t');
578bfbe053bSmarc 			if(px->p_sig&0177)
579bfbe053bSmarc 				msg = sysmsg[px->p_sig&0177];
580bfbe053bSmarc 			else if(px->p_flag&P_NOTIFY)
581bfbe053bSmarc 			{
582bfbe053bSmarc 				msg = j_Done;
583bfbe053bSmarc 				xitval = px->p_sig>>8;
584bfbe053bSmarc 			}
585bfbe053bSmarc 			else
586bfbe053bSmarc 				msg = j_Running;
587bfbe053bSmarc 			fputs(msg,output);
588bfbe053bSmarc 			msize = strlen(msg);
589bfbe053bSmarc 			if(xitval)
590bfbe053bSmarc 			{
591bfbe053bSmarc 				putc('(',output);
592bfbe053bSmarc 				p_num((int)xitval,')');
593bfbe053bSmarc 				msize += (3+(xitval>10)+(xitval>100));
594bfbe053bSmarc 			}
595bfbe053bSmarc 			if(px->p_flag&P_COREDUMP)
596bfbe053bSmarc 			{
597bfbe053bSmarc 				fputs(j_coredump,output);
598bfbe053bSmarc 				msize += strlen(j_coredump);
599bfbe053bSmarc 			}
600bfbe053bSmarc 			p_nchr(SP,MAXMSG-msize);
601bfbe053bSmarc 			if(flag&L_FLAG)
602bfbe053bSmarc 				px = next_proc(px->p_next,(int)pw->p_job);
603bfbe053bSmarc 			else
604bfbe053bSmarc 				px = NULL;
605bfbe053bSmarc 			offset = pr_jobname(pw,(px?'|':0),offset);
606bfbe053bSmarc 			if(flag&L_FLAG)
607bfbe053bSmarc 			{
608bfbe053bSmarc 				if(px)
609bfbe053bSmarc 					fputs(j_space,output);
610bfbe053bSmarc 				else if(pw->p_pid == cpid)
611bfbe053bSmarc 					fputs(j_cpid,output);
612bfbe053bSmarc 			}
613bfbe053bSmarc 		}
614bfbe053bSmarc 		while(px);
615bfbe053bSmarc 		if(pw->p_flag&P_STOPPED)
616bfbe053bSmarc 			pw->p_flag &= ~P_NOTIFY;
617bfbe053bSmarc 		else if(pw->p_flag&P_NOTIFY)
618bfbe053bSmarc 		{
619bfbe053bSmarc 			unpost(pw);
620bfbe053bSmarc 			if(jobm && (px=pgrp_jobs("%-")))
621bfbe053bSmarc 				jobm = px->p_job;
622bfbe053bSmarc 		}
623bfbe053bSmarc 	}
624bfbe053bSmarc }
625bfbe053bSmarc 
626bfbe053bSmarc /*
627bfbe053bSmarc  * return the pointer of next process with given job number after slot px
628bfbe053bSmarc  */
629bfbe053bSmarc 
630bfbe053bSmarc static struct process * next_proc(pw,job)
631bfbe053bSmarc register struct process *pw;
632bfbe053bSmarc register int job;
633bfbe053bSmarc {
634bfbe053bSmarc 	for(;pw;pw=pw->p_next)
635bfbe053bSmarc 	{
636bfbe053bSmarc 		if(pw->p_job == job)
637bfbe053bSmarc 			return(pw);
638bfbe053bSmarc 	}
639bfbe053bSmarc 	return(NULL);
640bfbe053bSmarc }
641bfbe053bSmarc 
642bfbe053bSmarc /*
643bfbe053bSmarc  * print the command
644bfbe053bSmarc  * Stop the output if character <ch> encountered
645bfbe053bSmarc  */
646bfbe053bSmarc 
647bfbe053bSmarc static long pr_jobname(pw,ch,offset)
648bfbe053bSmarc register struct process *pw;
649bfbe053bSmarc register long offset;
650bfbe053bSmarc int ch;
651bfbe053bSmarc {
652bfbe053bSmarc 	if(fc_fix)
653bfbe053bSmarc 	{
654bfbe053bSmarc 		offset = hist_list(pw->p_name+offset,ch,";");
655bfbe053bSmarc 		offset -= pw->p_name;
656bfbe053bSmarc 	}
657bfbe053bSmarc 	return(++offset);
658bfbe053bSmarc }
659bfbe053bSmarc 
660bfbe053bSmarc /*
661bfbe053bSmarc  * get the process group given the job number
662bfbe053bSmarc  * This routine returns the process group number or -1
663bfbe053bSmarc  */
664bfbe053bSmarc 
665bfbe053bSmarc static struct process *pgrp_jobs(ajob)
666bfbe053bSmarc register char *ajob;
667bfbe053bSmarc {
668bfbe053bSmarc 	register struct process *pw;
669bfbe053bSmarc 	register int c;
670bfbe053bSmarc 	if(*ajob++ != '%' || pwlist==NULL)
671bfbe053bSmarc 		return(NULL);
672bfbe053bSmarc 	c = *ajob;
673bfbe053bSmarc 	if(isdigit(c))
674bfbe053bSmarc 		pw = job_bynum(atoi(ajob));
675bfbe053bSmarc 	else if(c=='+' || c=='%')
676bfbe053bSmarc 		pw = job_bynum((int)pwlist->p_job);
677bfbe053bSmarc 	else if(c=='-')
678bfbe053bSmarc 	{
679bfbe053bSmarc 		/* find the second jobnumber on the list */
680bfbe053bSmarc 		for(pw=pwlist->p_next;pw && pw->p_job==pwlist->p_job;pw=pw->p_next);
681bfbe053bSmarc 		if(pw==NULL)
682bfbe053bSmarc 			return(pw);
683bfbe053bSmarc 		pw = job_bynum((int)pw->p_job);
684bfbe053bSmarc 	}
685bfbe053bSmarc 	else
686bfbe053bSmarc 		pw = jobbyname(ajob);
687bfbe053bSmarc 	if(pw && pw->p_flag)
688bfbe053bSmarc 		return(pw);
689bfbe053bSmarc 	return(NULL);
690bfbe053bSmarc }
691bfbe053bSmarc 
692bfbe053bSmarc /*
693bfbe053bSmarc  * send a hang-up signal to each of the jobs
694bfbe053bSmarc  */
695bfbe053bSmarc int kill_all()
696bfbe053bSmarc {
697bfbe053bSmarc 	register struct process *pw = pwlist;
698bfbe053bSmarc 	for(;pw;pw=pw->p_next)
699bfbe053bSmarc 	{
700bfbe053bSmarc 		if(pw->p_pgrp == pw->p_pid)
701bfbe053bSmarc 		{
702bfbe053bSmarc #ifdef BSD
703bfbe053bSmarc 			unstop(pw->p_pgrp);
704bfbe053bSmarc 			killpg(pw->p_pgrp,SIGHUP);
705bfbe053bSmarc #else
706bfbe053bSmarc 			kill(-pw->p_pgrp,SIGHUP);
707bfbe053bSmarc #endif	/* BSD */
708bfbe053bSmarc 		}
709bfbe053bSmarc 	}
710bfbe053bSmarc }
711bfbe053bSmarc 
712bfbe053bSmarc /*
713bfbe053bSmarc  * Kill a job or process
714bfbe053bSmarc  */
715bfbe053bSmarc 
716bfbe053bSmarc int job_kill(job,sig)
717bfbe053bSmarc register char *job;
718bfbe053bSmarc int sig;
719bfbe053bSmarc {
720bfbe053bSmarc 	register char *rjob = job;
721bfbe053bSmarc 	register struct process *pw;
722bfbe053bSmarc 	register int pid;
723bfbe053bSmarc 	register int r;
724bfbe053bSmarc 	char *msg;
725bfbe053bSmarc 	if(*rjob == '%')
726bfbe053bSmarc 	{
727bfbe053bSmarc 		if(pw=pgrp_jobs(rjob))
728bfbe053bSmarc 		{
729bfbe053bSmarc #ifdef BSD
730bfbe053bSmarc 			r = unstop(pw->p_pgrp);
731bfbe053bSmarc 			if(sig!=SIGCONT || r < 0)
732bfbe053bSmarc 				r = killpg(pw->p_pgrp,sig);
733bfbe053bSmarc #else
734bfbe053bSmarc 			pid = pw->p_pgrp;
735bfbe053bSmarc 			if(states&MONITOR)
736bfbe053bSmarc 				pid = -pid;
737bfbe053bSmarc 			r = kill(pid,sig);
738bfbe053bSmarc #endif	/* BSD */
739bfbe053bSmarc 		}
740bfbe053bSmarc 		else
741bfbe053bSmarc 		{
742bfbe053bSmarc 			r = -1;
743bfbe053bSmarc 			errno = ESRCH;
744bfbe053bSmarc 		}
745bfbe053bSmarc 	}
746bfbe053bSmarc 	else
747bfbe053bSmarc 	{
748bfbe053bSmarc 		pid = atoi(rjob);
749bfbe053bSmarc 		if(pid==0 && *rjob != '0')
750bfbe053bSmarc 			failed(bkill,kill_usage);
751bfbe053bSmarc #ifdef BSD
752bfbe053bSmarc 		if(sig==SIGSTOP && pid==jobstat.mypid && (login_sh || ppid==1))
753bfbe053bSmarc 		{
754bfbe053bSmarc 		/* can't stop login shell */
755bfbe053bSmarc 			errno = EPERM;
756bfbe053bSmarc 			r = -1;
757bfbe053bSmarc 		}
758bfbe053bSmarc 		else
759bfbe053bSmarc 		{
760bfbe053bSmarc 			if((pw=job_bypid(pid)) && (pw->p_flag&P_STOPPED))
761bfbe053bSmarc 			{
762bfbe053bSmarc 				pw->p_flag &= ~P_STOPPED;
763bfbe053bSmarc 				numrun++;
764bfbe053bSmarc 				kill(pid,SIGCONT);
765bfbe053bSmarc 			}
766bfbe053bSmarc 			r = kill(pid,sig);
767bfbe053bSmarc 		}
768bfbe053bSmarc #else
769bfbe053bSmarc 		r = kill(pid,sig);
770bfbe053bSmarc #endif	/* BSD */
771bfbe053bSmarc 	}
772bfbe053bSmarc 	if(r<0)
773bfbe053bSmarc 	{
774bfbe053bSmarc 		p_setout(stderr);
775bfbe053bSmarc 		fputs(j_kill,output);
776bfbe053bSmarc 		if(*rjob == '%')
777bfbe053bSmarc 			msg = j_no_job;
778bfbe053bSmarc 		else
779bfbe053bSmarc 			msg = j_no_proc;
780bfbe053bSmarc 		p_str(rjob,':');
781bfbe053bSmarc 		if(errno == EPERM)
782bfbe053bSmarc 			msg = j_perm;
783bfbe053bSmarc 		p_str(msg,NL);
784bfbe053bSmarc 		r = 1;
785bfbe053bSmarc 	}
786bfbe053bSmarc 	return(r);
787bfbe053bSmarc }
788bfbe053bSmarc 
789bfbe053bSmarc /*
790bfbe053bSmarc  * Get process structure from job number
791bfbe053bSmarc  */
792bfbe053bSmarc 
793bfbe053bSmarc static struct process *job_bynum(num)
794bfbe053bSmarc register int num;
795bfbe053bSmarc {
796bfbe053bSmarc 	register struct process *pw = pwlist;
797bfbe053bSmarc 	for(;pw;pw=pw->p_next)
798bfbe053bSmarc 	{
799bfbe053bSmarc 		if((pw->p_flag&(P_PIPEJOB|P_WAITED)) == P_PIPEJOB)
800bfbe053bSmarc 			continue;
801bfbe053bSmarc 		if(pw->p_job == num)
802bfbe053bSmarc 			return(pw);
803bfbe053bSmarc 	}
804bfbe053bSmarc 	return(NULL);
805bfbe053bSmarc }
806bfbe053bSmarc 
807bfbe053bSmarc /*
808bfbe053bSmarc  * Get process structure from first letters of jobname
809bfbe053bSmarc  *
810bfbe053bSmarc  */
811bfbe053bSmarc 
812bfbe053bSmarc static struct process *jobbyname(name)
813bfbe053bSmarc char *name;
814bfbe053bSmarc {
815bfbe053bSmarc 	register struct process *pw = pwlist;
816bfbe053bSmarc 	register struct fixcmd *fp = fc_fix;
817bfbe053bSmarc 	if(fp==NULL)
818bfbe053bSmarc 		return(NULL);
819bfbe053bSmarc 	for(;pw;pw=pw->p_next)
820bfbe053bSmarc 	{
821bfbe053bSmarc 		if((pw->p_flag&(P_PIPEJOB|P_WAITED)) == P_PIPEJOB)
822bfbe053bSmarc 			continue;
823bfbe053bSmarc 		if(match_jobname(fp->fixfd,pw,name))
824bfbe053bSmarc 			goto retrn;
825bfbe053bSmarc 	}
826bfbe053bSmarc 	pw = NULL;
827bfbe053bSmarc retrn:
828bfbe053bSmarc 	return(pw);
829bfbe053bSmarc }
830bfbe053bSmarc 
831bfbe053bSmarc 
832bfbe053bSmarc /*
833bfbe053bSmarc  * match the name to the command starting with given name
834bfbe053bSmarc  */
835bfbe053bSmarc 
836bfbe053bSmarc static int	match_jobname(fdi,pw,name)
837bfbe053bSmarc FILE *fdi;
838bfbe053bSmarc register struct process *pw;
839bfbe053bSmarc char *name;
840bfbe053bSmarc {
841bfbe053bSmarc 	register int c;
842bfbe053bSmarc 	register char *sp;
843bfbe053bSmarc 	if(fdi && pw->p_name>0)
844bfbe053bSmarc 	{
845bfbe053bSmarc 		fseek(fdi,pw->p_name,0);
846bfbe053bSmarc 		for(sp=name;*sp;sp++)
847bfbe053bSmarc 		{
848bfbe053bSmarc 			c = getc(fdi);
849bfbe053bSmarc 			if(c != *sp)
850bfbe053bSmarc 				return(0);
851bfbe053bSmarc 		}
852bfbe053bSmarc 		return(1);
853bfbe053bSmarc 	}
854bfbe053bSmarc 	return(0);
855bfbe053bSmarc }
856bfbe053bSmarc 
857bfbe053bSmarc 
858bfbe053bSmarc 
859bfbe053bSmarc /*
860bfbe053bSmarc  * Initialize the process posting array
861bfbe053bSmarc  */
862bfbe053bSmarc 
863bfbe053bSmarc void	postclr()
864bfbe053bSmarc {
865bfbe053bSmarc 	register struct process *pw = pwlist;
866bfbe053bSmarc 	register struct process *px;
867bfbe053bSmarc 	register int j = JBYTES;
868bfbe053bSmarc 	for(;pw;pw=px)
869bfbe053bSmarc 	{
870bfbe053bSmarc 		px = pw->p_next;
871bfbe053bSmarc 		free((char*)pw);
872bfbe053bSmarc 	}
873bfbe053bSmarc 	pwlist = NULL;
874bfbe053bSmarc 	numpost=0;
875bfbe053bSmarc 	numrun = 0;
876bfbe053bSmarc 	while(--j >=0)
877bfbe053bSmarc 		freejobs[j]  = 0;
878bfbe053bSmarc }
879bfbe053bSmarc 
880bfbe053bSmarc /*
881bfbe053bSmarc  * put the process <pcsid> on the process list and return the job number
882bfbe053bSmarc  * turn on the specified flag bits.
883bfbe053bSmarc  */
884bfbe053bSmarc 
885bfbe053bSmarc int post(pid,flag)
886bfbe053bSmarc int pid;
887bfbe053bSmarc {
888bfbe053bSmarc 	register struct process *pw;
889bfbe053bSmarc 	if(pw=job_post(pid))
890bfbe053bSmarc 	{
891bfbe053bSmarc 		pw->p_flag |= flag;
892bfbe053bSmarc 		return(pw->p_job);
893bfbe053bSmarc 	}
894bfbe053bSmarc 	return(-1);
895bfbe053bSmarc }
896bfbe053bSmarc 
897bfbe053bSmarc /*
898bfbe053bSmarc  * internal version of post, this routine returns a process structure
899bfbe053bSmarc  */
900bfbe053bSmarc 
901bfbe053bSmarc static struct process *job_post(pcsid)
902bfbe053bSmarc int 	pcsid;
903bfbe053bSmarc {
904bfbe053bSmarc 	register struct process  *pw = pwlist;
905bfbe053bSmarc 	register struct process  *px=NULL;
906bfbe053bSmarc 	register struct fixcmd *fp = fc_fix;
907bfbe053bSmarc 	if(pcsid)
908bfbe053bSmarc 	{
909bfbe053bSmarc 		for(;pw;pw=pw->p_next)
910bfbe053bSmarc 		{
911bfbe053bSmarc 			if(pw->p_pid==pcsid)
912bfbe053bSmarc 				return(pw);
913bfbe053bSmarc 			if(pw->p_pgrp == jobstat.cur_pgrp)
914bfbe053bSmarc 				px = pw;
915bfbe053bSmarc 		}
916bfbe053bSmarc 		if(pw=freelist)
917bfbe053bSmarc 			freelist = pw->p_next;
918bfbe053bSmarc 		else if((pw=(struct process*)malloc(sizeof(struct process)))==NULL)
919bfbe053bSmarc 			error(nospace);
920bfbe053bSmarc 		numrun++;
921bfbe053bSmarc 		numpost++;
922bfbe053bSmarc 		if(px)
923bfbe053bSmarc 		{
924bfbe053bSmarc 			pw->p_next = px->p_next;
925bfbe053bSmarc 			px->p_next = pw;
926bfbe053bSmarc 			pw->p_job = px->p_job;
927bfbe053bSmarc 		}
928bfbe053bSmarc 		else
929bfbe053bSmarc 		{
930bfbe053bSmarc 			/* put at front of list */
931bfbe053bSmarc 			pw->p_next = pwlist;
932bfbe053bSmarc 			pw->p_job = get_job();
933bfbe053bSmarc 			pwlist = pw;
934bfbe053bSmarc 		}
935bfbe053bSmarc 		pw->p_pid = pcsid;
936bfbe053bSmarc 		pw->p_flag = P_RUNNING;
937bfbe053bSmarc 		pw->p_pgrp = jobstat.cur_pgrp;
938bfbe053bSmarc 		if(fp!=NULL)
939bfbe053bSmarc 			pw->p_name=hist_position(fp->fixind-1);
940bfbe053bSmarc 		else
941bfbe053bSmarc 			pw->p_name = -1;
942bfbe053bSmarc 		pw->p_sig = 0;
943bfbe053bSmarc 		if(numpost >= MAXJ-1)
944bfbe053bSmarc 			await(0,0);
945bfbe053bSmarc 		return(pw);
946bfbe053bSmarc 	}
947bfbe053bSmarc 	return(NULL);
948bfbe053bSmarc }
949bfbe053bSmarc 
950bfbe053bSmarc /*
951bfbe053bSmarc  * get job number given the process id
952bfbe053bSmarc  */
953bfbe053bSmarc 
954bfbe053bSmarc static struct process *job_bypid(pid)
955bfbe053bSmarc register int pid;
956bfbe053bSmarc {
957bfbe053bSmarc 	register struct process *pw;
958bfbe053bSmarc 	if(pid==0)
959bfbe053bSmarc 		return(NULL);
960bfbe053bSmarc 	for(pw=pwlist;pw;pw=pw->p_next)
961bfbe053bSmarc 	if(pw->p_pid == pid)
962bfbe053bSmarc 			break;
963bfbe053bSmarc 	return(pw);
964bfbe053bSmarc }
965bfbe053bSmarc 
966bfbe053bSmarc /*
967bfbe053bSmarc  * Wait for process i to complete
968bfbe053bSmarc  * flag=1 when wait builtin invoked so that it can be interrupted
969bfbe053bSmarc  * flag=2 to check for waiting processes and return
970bfbe053bSmarc  * flag=3 to resume job in foreground
971bfbe053bSmarc  * i=0 to wait for any process
972bfbe053bSmarc  * i=-1 to wait for all runing processes
973bfbe053bSmarc  */
974bfbe053bSmarc 
975bfbe053bSmarc void	await(i, flag)
976bfbe053bSmarc register int 	i;
977bfbe053bSmarc int 	flag;
978bfbe053bSmarc {
979bfbe053bSmarc 	int 	rc=0;
980bfbe053bSmarc 	int 	w;
981bfbe053bSmarc 	int my_job = -1;
982bfbe053bSmarc #ifdef BSD
983bfbe053bSmarc 	union wait wstat;
984bfbe053bSmarc #endif	/* BSD */
985bfbe053bSmarc 	register struct process *pw = NULL;
986bfbe053bSmarc 	struct process *px;
987bfbe053bSmarc 	if(i!= -1 && i)
988bfbe053bSmarc 	{
989bfbe053bSmarc 		if(flag)
990bfbe053bSmarc 		{
991bfbe053bSmarc 			pw = job_bypid(i);
992bfbe053bSmarc 			if(flag==3 && pw)
993bfbe053bSmarc 				flag = 0;
994bfbe053bSmarc 		}
995bfbe053bSmarc 		else
996bfbe053bSmarc 			pw = job_post(i);
997bfbe053bSmarc 		if(flag)
998bfbe053bSmarc 		{
999bfbe053bSmarc 			if(pw==0 || (pw->p_flag&P_STOPPED))
1000bfbe053bSmarc 			return;
1001bfbe053bSmarc 		}
1002bfbe053bSmarc 		my_job = pw->p_job;
1003bfbe053bSmarc 	}
1004bfbe053bSmarc 	if(flag==0 && (states&MONITOR) && pw)
1005bfbe053bSmarc 	{
1006bfbe053bSmarc 		set_job(pw);
1007bfbe053bSmarc 		/* if job is stopped, resume it in the background */
1008bfbe053bSmarc #if BSD || SXT
1009bfbe053bSmarc 		if(pw->p_flag&P_STOPPED)
1010bfbe053bSmarc 			unstop(pw->p_pgrp);
1011bfbe053bSmarc # ifdef SXT
1012bfbe053bSmarc 		if(pw->p_job < jobstat.maxjob)
1013bfbe053bSmarc 			open_chan(pw->p_job);
1014bfbe053bSmarc # endif /* SXT */
1015bfbe053bSmarc #endif	/* BSD */
1016bfbe053bSmarc 	}
1017bfbe053bSmarc 	p_flush();
1018bfbe053bSmarc 	while(numrun>0)
1019bfbe053bSmarc 	{
1020bfbe053bSmarc 		register int 	p;
1021bfbe053bSmarc 		register int 	sig;
1022bfbe053bSmarc 		register int 	w_hi;
1023bfbe053bSmarc #ifdef BSD
1024bfbe053bSmarc 		if(is_option(MONITOR) || flag==2)
1025bfbe053bSmarc 		{
1026bfbe053bSmarc 		retry:
1027bfbe053bSmarc 			errno = 0;
1028bfbe053bSmarc 			sig = sighold(SIGCHLD);
1029bfbe053bSmarc 			trapnote &= ~SIGJOBS;
1030bfbe053bSmarc 			p=wait3(&wstat,WNOHANG|WUNTRACED,0);
1031bfbe053bSmarc 			errno = 0;
1032bfbe053bSmarc 			if(p==0 && flag!=2)
1033bfbe053bSmarc 			{
1034bfbe053bSmarc # ifdef BSD_4_2
1035bfbe053bSmarc 				sigpause(sig&~(1<<(SIGCHLD-1)));
1036bfbe053bSmarc # else
1037bfbe053bSmarc 				sigpause(SIGCHLD);
1038bfbe053bSmarc # endif /* BSD_4_2 */
1039bfbe053bSmarc 				if(errno==EINTR && flag==1 && (trapnote&SIGJOBS)==0)
1040bfbe053bSmarc 					break;
1041bfbe053bSmarc 				goto retry;
1042bfbe053bSmarc 			}
1043bfbe053bSmarc 			trapnote &= ~SIGJOBS;
1044bfbe053bSmarc 			sigrelse(SIGCHLD);
1045bfbe053bSmarc 			if(p==0 || p== -1)
1046bfbe053bSmarc 				return;
1047bfbe053bSmarc 			w = wstat.w_status;
1048bfbe053bSmarc 			pw = job_bypid(p);
1049bfbe053bSmarc 			if(pw->p_job == my_job && (states&MONITOR))
1050bfbe053bSmarc 			{
1051bfbe053bSmarc 				register int ssig = wstat.w_S.w_Stopsig;
1052bfbe053bSmarc 				if(WIFSTOPPED(wstat) && (ssig==SIGTTIN||ssig==SIGTTOU))
1053bfbe053bSmarc 				{
1054bfbe053bSmarc 					/* job stopped before it got terminal */
1055bfbe053bSmarc 					killpg(pw->p_pgrp,SIGCONT);
1056bfbe053bSmarc 					continue;
1057bfbe053bSmarc 				}
1058bfbe053bSmarc 				if(p==i)
1059bfbe053bSmarc 					reset_ttygrp(pw,w&LOBYTE);
1060bfbe053bSmarc 			}
1061bfbe053bSmarc 		}
1062bfbe053bSmarc 		else
1063bfbe053bSmarc #endif	/* BSD */
1064bfbe053bSmarc 		{
1065bfbe053bSmarc #ifndef BSD
1066bfbe053bSmarc # ifdef SXT
1067bfbe053bSmarc 			if(jobstat.maxjob >0)
1068bfbe053bSmarc 			{
1069bfbe053bSmarc 				/* check for job status change */
1070bfbe053bSmarc 				status1 = status2;
1071bfbe053bSmarc 				status2.input = status2.output = 0;
1072bfbe053bSmarc 				if(ioctl(2,SXTIOCSTAT,&status2)!=0)
1073bfbe053bSmarc 				{
1074bfbe053bSmarc 					jobstat.maxjob = 0;
1075bfbe053bSmarc 				}
1076bfbe053bSmarc 				else if(status1.input != status2.input)
1077bfbe053bSmarc 				{
1078bfbe053bSmarc 					status_update(status2.input,status1.input,SIGSTIN);
1079bfbe053bSmarc 				}
1080bfbe053bSmarc 				else if(status1.output != status2.output)
1081bfbe053bSmarc 				{
1082bfbe053bSmarc 					status_update(status2.output,status1.output,SIGSTOP);
1083bfbe053bSmarc 				}
1084bfbe053bSmarc 			}
1085bfbe053bSmarc # endif /* SXT */
1086bfbe053bSmarc 			/* enable fault handler to see if there are any pending jobs */
1087bfbe053bSmarc 			if((trapnote&SIGJOBS)==0)
1088bfbe053bSmarc 				signal(SIGCLD,fault);
1089bfbe053bSmarc 			if(flag==2 && (trapnote&SIGJOBS)==0)
1090bfbe053bSmarc 				return;
1091bfbe053bSmarc # ifdef SXT
1092bfbe053bSmarc 			if(my_job>=0 && (trapnote&SIGJOBS)==0 && jobstat.maxjob)
1093bfbe053bSmarc 			{
1094bfbe053bSmarc 				errno = 0;
1095bfbe053bSmarc 		        	p = ioctl(2, SXTIOCWF, 0);
1096bfbe053bSmarc 				if(p==0)
1097bfbe053bSmarc 					/* job stopped */
1098bfbe053bSmarc 				{
1099bfbe053bSmarc        		         		ioctl(2, SXTIOCBLK, my_job);
1100bfbe053bSmarc 					if(fd_chan>=0)
1101bfbe053bSmarc 					{
1102bfbe053bSmarc 						if(ioctl(fd_chan,TCFLSH,2)!=0)
1103bfbe053bSmarc 						{
1104bfbe053bSmarc 							;
1105bfbe053bSmarc 						}
1106bfbe053bSmarc 					}
1107bfbe053bSmarc 					pw->p_flag |= (P_NOTIFY|P_STOPPED);
1108bfbe053bSmarc 					pw->p_sig = SIGSTOP;
1109bfbe053bSmarc 					reset_ttygrp(pw,1);
1110bfbe053bSmarc 					break;
1111bfbe053bSmarc 				}
1112bfbe053bSmarc 			}
1113bfbe053bSmarc # endif /* SXT */
1114bfbe053bSmarc #endif	/* BSD */
1115bfbe053bSmarc 			trapnote &= ~ SIGJOBS;
1116bfbe053bSmarc 			p=wait(&w);
1117bfbe053bSmarc 			if(p== -1)
1118bfbe053bSmarc 			{
1119bfbe053bSmarc 				if(errno==ECHILD)
1120bfbe053bSmarc 				{
1121bfbe053bSmarc 					postclr();
1122bfbe053bSmarc 					return;
1123bfbe053bSmarc 				}
1124bfbe053bSmarc 				else if(errno==EINTR)
1125bfbe053bSmarc 				{
1126bfbe053bSmarc 					if(trapnote&SIGJOBS)
1127bfbe053bSmarc 						continue;
1128bfbe053bSmarc 					if(flag)
1129bfbe053bSmarc 						break;
1130bfbe053bSmarc 				}
1131bfbe053bSmarc 				continue;
1132bfbe053bSmarc 			}
1133bfbe053bSmarc 			trapnote &= ~ SIGJOBS;
1134bfbe053bSmarc 			pw = job_bypid(p);
1135bfbe053bSmarc #ifdef SXT
1136bfbe053bSmarc 			pw->p_flag &= ~P_STOPPED;
1137bfbe053bSmarc #endif	/* SXT */
1138bfbe053bSmarc 			/* restore original tty state if jobs aborted */
1139bfbe053bSmarc 			if(p == i && (states&MONITOR))
1140bfbe053bSmarc 				reset_ttygrp(pw,w&LOBYTE);
1141bfbe053bSmarc 		}
1142bfbe053bSmarc 		if(pw)
1143bfbe053bSmarc 		{
1144bfbe053bSmarc 			numrun--;
1145bfbe053bSmarc 			pw->p_flag |= P_NOTIFY;
1146bfbe053bSmarc #ifdef BSD
1147bfbe053bSmarc 			if((states&MONITOR) && WIFSTOPPED(wstat))
1148bfbe053bSmarc 				pw->p_flag |= P_STOPPED;
1149bfbe053bSmarc 			else
1150bfbe053bSmarc #endif	/* BSD */
1151bfbe053bSmarc 			{
1152bfbe053bSmarc 				if(p==cpid)
1153bfbe053bSmarc 				{
1154bfbe053bSmarc 					cpid = 0;
1155bfbe053bSmarc 					cpipe[1] = NULL;
1156bfbe053bSmarc 				}
1157bfbe053bSmarc 				if(p==i || (states&MONITOR)==0)
1158bfbe053bSmarc 				{
1159bfbe053bSmarc 					if(px=unpost(pw))
1160bfbe053bSmarc 					{
1161bfbe053bSmarc 						if(i)
1162bfbe053bSmarc 						{
1163bfbe053bSmarc 							if(p==i && (states&MONITOR))
1164bfbe053bSmarc 								set_job(px);
1165bfbe053bSmarc 							i = px->p_pid;
1166bfbe053bSmarc 						}
1167bfbe053bSmarc 						continue;
1168bfbe053bSmarc 					}
1169bfbe053bSmarc 				}
1170bfbe053bSmarc 			}
1171bfbe053bSmarc 		}
1172bfbe053bSmarc 		sig = w&0177;
1173bfbe053bSmarc 		if(states&MONITOR)
1174bfbe053bSmarc 		{
1175bfbe053bSmarc #ifdef BSD
1176bfbe053bSmarc 			if(WIFSTOPPED(wstat))
1177bfbe053bSmarc 			{
1178bfbe053bSmarc 				if(pw)
1179bfbe053bSmarc 					pw->p_sig = wstat.w_S.w_Stopsig;
1180bfbe053bSmarc 				if(p == i)
1181bfbe053bSmarc 					break;
1182bfbe053bSmarc 				continue;
1183bfbe053bSmarc 			}
1184bfbe053bSmarc 			else if(p!=i)
1185bfbe053bSmarc #else
1186bfbe053bSmarc 			if(p!=i)
1187bfbe053bSmarc #endif	/* BSD */
1188bfbe053bSmarc 			{
1189bfbe053bSmarc 				if(pw)
1190bfbe053bSmarc 					pw->p_sig = w;
1191bfbe053bSmarc 				if(w&HIGHBIT)
1192bfbe053bSmarc 					pw->p_flag |= P_COREDUMP;
1193bfbe053bSmarc 				continue;
1194bfbe053bSmarc 			}
1195bfbe053bSmarc 			/* this is needed since child not in same process group */
1196bfbe053bSmarc 			else if(sig==SIGINT || sig==SIGQUIT || sig==SIGHUP)
1197bfbe053bSmarc 				fault(sig);
1198bfbe053bSmarc 		}
1199bfbe053bSmarc 		w_hi = (w>>8)&LOBYTE;
1200bfbe053bSmarc 		if(sig)
1201bfbe053bSmarc 		{
1202bfbe053bSmarc 			if(sig == 0177	/* ptrace! return */)
1203bfbe053bSmarc 			{
1204bfbe053bSmarc 				fputs(ptrace,output);
1205bfbe053bSmarc 				sig = w_hi;
1206bfbe053bSmarc 			}
1207bfbe053bSmarc 			if(sig!=SIGINT && sig!=SIGPIPE)
1208bfbe053bSmarc 			{
1209bfbe053bSmarc 				if(i!=p || (states&PROMPT)==0)
1210bfbe053bSmarc 					p_prp(itos(p),SP);
1211bfbe053bSmarc 				fputs(sysmsg[sig],output);
1212bfbe053bSmarc 				if(w&HIGHBIT)
1213bfbe053bSmarc 					fputs(coredump,output);
1214bfbe053bSmarc 			}
1215bfbe053bSmarc 			newline();
1216bfbe053bSmarc 		}
1217bfbe053bSmarc 		if(p == i)
1218bfbe053bSmarc 		{
1219bfbe053bSmarc 			rc = (sig ? sig|SIGFAIL : w_hi);
1220bfbe053bSmarc 			break;
1221bfbe053bSmarc 		}
1222bfbe053bSmarc 		if(i == 0)
1223bfbe053bSmarc 			break;
1224bfbe053bSmarc 	}
1225bfbe053bSmarc 	if(flag>=2)
1226bfbe053bSmarc 		return;
1227bfbe053bSmarc 	exitval=rc;
1228bfbe053bSmarc 	exitset();
1229bfbe053bSmarc }
1230bfbe053bSmarc 
1231bfbe053bSmarc #if BSD || SXT
1232bfbe053bSmarc /*
1233bfbe053bSmarc  * turn off STOP state of a process group
1234bfbe053bSmarc  */
1235bfbe053bSmarc 
1236bfbe053bSmarc static int unstop(grp)
1237bfbe053bSmarc register int grp;
1238bfbe053bSmarc {
1239bfbe053bSmarc 	register struct process *pw;
1240bfbe053bSmarc 	register int num = numrun;
1241bfbe053bSmarc 	for(pw=pwlist;pw;pw=pw->p_next)
1242bfbe053bSmarc 	{
1243bfbe053bSmarc 		if(pw->p_pgrp != grp)
1244bfbe053bSmarc 			continue;
1245bfbe053bSmarc 		if(pw->p_flag&P_STOPPED)
1246bfbe053bSmarc 		{
1247bfbe053bSmarc 			num++;
1248bfbe053bSmarc 			pw->p_flag &= ~P_STOPPED;
1249bfbe053bSmarc 			pw->p_sig = 0;
1250bfbe053bSmarc # ifdef SXT
1251bfbe053bSmarc 			break;
1252bfbe053bSmarc # endif /* SXT */
1253bfbe053bSmarc 		}
1254bfbe053bSmarc 	}
1255bfbe053bSmarc 	if(num!=numrun)
1256bfbe053bSmarc 	{
1257bfbe053bSmarc 		p_flush();
1258bfbe053bSmarc #ifdef BSD
1259bfbe053bSmarc 		numrun = num;
1260bfbe053bSmarc 		return(killpg(grp,SIGCONT));
1261bfbe053bSmarc #endif
1262bfbe053bSmarc 	}
1263bfbe053bSmarc 	return(-1);
1264bfbe053bSmarc }
1265bfbe053bSmarc #endif	/* BSD */
1266bfbe053bSmarc 
1267bfbe053bSmarc /*
1268bfbe053bSmarc  * remove a process group from table
1269bfbe053bSmarc  * If all the processes have not completed then unpost returns
1270bfbe053bSmarc  * the structure pointer  of an unfinished process.
1271bfbe053bSmarc  * Otherwise NULL is returned.
1272bfbe053bSmarc  */
1273bfbe053bSmarc 
1274bfbe053bSmarc static struct process *unpost(pwtop)
1275bfbe053bSmarc struct process *pwtop;
1276bfbe053bSmarc {
1277bfbe053bSmarc 	register struct process *pw;
1278bfbe053bSmarc 	register struct process *px=NULL;
1279bfbe053bSmarc 	register int job = pwtop->p_job;
1280bfbe053bSmarc 	register struct process *py;
1281bfbe053bSmarc 	/* look for unfinished processes */
1282bfbe053bSmarc 	for(pw=pwlist;pw;pw=pw->p_next)
1283bfbe053bSmarc 	{
1284bfbe053bSmarc 		if(pw->p_job != job)
1285bfbe053bSmarc 			continue;
1286bfbe053bSmarc 		if((pw->p_flag&P_NOTIFY)==0)
1287bfbe053bSmarc 			px = pw;
1288bfbe053bSmarc 	}
1289bfbe053bSmarc 	if(px)
1290bfbe053bSmarc 	{
1291bfbe053bSmarc 		px->p_flag &= ~P_PIPEJOB;
1292bfbe053bSmarc 		px->p_flag |= P_WAITED;
1293bfbe053bSmarc 		return(px);
1294bfbe053bSmarc 	}
1295bfbe053bSmarc 	/* all processes complete, unpost job */
1296bfbe053bSmarc 	for(pw=pwlist;pw;pw=py)
1297bfbe053bSmarc 	{
1298bfbe053bSmarc 		py = pw->p_next;
1299bfbe053bSmarc 		if(pw->p_job != job)
1300bfbe053bSmarc 		{
1301bfbe053bSmarc 			px = pw;
1302bfbe053bSmarc 			continue;
1303bfbe053bSmarc 		}
1304bfbe053bSmarc 		numpost--;
1305bfbe053bSmarc 		if(px==NULL)
1306bfbe053bSmarc 			pwlist = py;
1307bfbe053bSmarc 		else
1308bfbe053bSmarc 			px->p_next = py;
1309bfbe053bSmarc 		pw->p_next = freelist;
1310bfbe053bSmarc 		freelist = pw;
1311bfbe053bSmarc 	}
1312bfbe053bSmarc 	free_job((int)pwtop->p_job);
1313bfbe053bSmarc 	return(NULL);
1314bfbe053bSmarc }
1315bfbe053bSmarc 
1316bfbe053bSmarc /*
1317bfbe053bSmarc  * unlink a process form the process list
1318bfbe053bSmarc  */
1319bfbe053bSmarc 
1320bfbe053bSmarc static void pw_unlink(pw)
1321bfbe053bSmarc register struct process *pw;
1322bfbe053bSmarc {
1323bfbe053bSmarc 	register struct process *px;
1324bfbe053bSmarc 	if(pw==pwlist)
1325bfbe053bSmarc 	{
1326bfbe053bSmarc 		pwlist = pw->p_next;
1327bfbe053bSmarc 		return;
1328bfbe053bSmarc 	}
1329bfbe053bSmarc 	for(px=pwlist;px;px=px->p_next)
1330bfbe053bSmarc 		if(px->p_next == pw)
1331bfbe053bSmarc 		{
1332bfbe053bSmarc 			px->p_next = pw->p_next;
1333bfbe053bSmarc 			return;
1334bfbe053bSmarc 		}
1335bfbe053bSmarc }
1336bfbe053bSmarc 
1337bfbe053bSmarc /*
1338bfbe053bSmarc  * get an unused job number
1339bfbe053bSmarc  * freejobs is a bit vector, 0 is unused
1340bfbe053bSmarc  */
1341bfbe053bSmarc 
1342bfbe053bSmarc static int get_job()
1343bfbe053bSmarc {
1344bfbe053bSmarc 	register int j=0;
1345bfbe053bSmarc 	register unsigned mask = 1;
1346bfbe053bSmarc 	register unsigned char *freeword;
1347bfbe053bSmarc 	/* skip to first word with a free slot */
1348bfbe053bSmarc 	while(freejobs[j] == 0xff)
1349bfbe053bSmarc 		j++;
1350bfbe053bSmarc 	freeword = &freejobs[j];
1351bfbe053bSmarc 	j *= 8;
1352bfbe053bSmarc 	for(j++;mask&(*freeword);j++,mask <<=1);
1353bfbe053bSmarc 	*freeword  |=mask;
1354bfbe053bSmarc 	return(j);
1355bfbe053bSmarc }
1356bfbe053bSmarc 
1357bfbe053bSmarc /*
1358bfbe053bSmarc  * return a job number
1359bfbe053bSmarc  */
1360bfbe053bSmarc 
1361bfbe053bSmarc static void free_job(n)
1362bfbe053bSmarc register int n;
1363bfbe053bSmarc {
1364bfbe053bSmarc 	register int j = (--n)/8;
1365bfbe053bSmarc 	register unsigned mask;
1366bfbe053bSmarc 	n -= j*8;
1367bfbe053bSmarc 	mask = 1 << n;
1368bfbe053bSmarc 	freejobs[j]  &= ~mask;
1369bfbe053bSmarc }
1370bfbe053bSmarc 
1371bfbe053bSmarc #ifdef SXT
1372bfbe053bSmarc /*
1373bfbe053bSmarc  * open up the input streams for a new channel
1374bfbe053bSmarc  */
1375bfbe053bSmarc 
1376bfbe053bSmarc static char *open_mode[3] = {"r","w","w+"};
1377bfbe053bSmarc j_new_chan()
1378bfbe053bSmarc {
1379bfbe053bSmarc 	register FILE* fd;
1380bfbe053bSmarc 	register int i;
1381bfbe053bSmarc 	sxt[11] = '0' + jobstat.cur_job;
1382bfbe053bSmarc 	close(jobstat.pipe[0]);
1383bfbe053bSmarc 	fd = fopen(sxt,"r+");
1384bfbe053bSmarc 	if(ioctl(fileno(fd),TCSETA,&my_stty)<0 || fd==NULL)
1385bfbe053bSmarc 	{
1386bfbe053bSmarc 		close(jobstat.pipe[1]);
1387bfbe053bSmarc 		return(0);
1388bfbe053bSmarc 	}
1389bfbe053bSmarc 	for(i=0;i<3;i++)
1390bfbe053bSmarc 	{
1391bfbe053bSmarc 		if(isatty(i))
1392bfbe053bSmarc 		{
1393bfbe053bSmarc 			fclose(file_fd(i));
1394bfbe053bSmarc 			fdopen(dup(fileno(fd)),open_mode[i]);
1395bfbe053bSmarc 		}
1396bfbe053bSmarc 	}
1397bfbe053bSmarc 	fclose(fd);
1398bfbe053bSmarc 	write(jobstat.pipe[1],nullstr,1);
1399bfbe053bSmarc 	close(jobstat.pipe[1]);
1400bfbe053bSmarc 	return(1);
1401bfbe053bSmarc }
1402bfbe053bSmarc 
1403bfbe053bSmarc int next_job()
1404bfbe053bSmarc {
1405bfbe053bSmarc 	register int i = get_job();
1406bfbe053bSmarc 	free_job(i);
1407bfbe053bSmarc 	return(i);
1408bfbe053bSmarc }
1409bfbe053bSmarc 
1410bfbe053bSmarc static status_update(mask2,mask1,sigval)
1411bfbe053bSmarc {
1412bfbe053bSmarc 	register int i,j;
1413bfbe053bSmarc 	register struct process *pw;
1414bfbe053bSmarc 	for(i = 1; i < MAXPCHAN; i++)
1415bfbe053bSmarc 	{
1416bfbe053bSmarc 		j = 1<<i;
1417bfbe053bSmarc 		if((mask1&j)==0 && (mask2&j))
1418bfbe053bSmarc 		{
1419bfbe053bSmarc 			if(pw = job_bynum(i))
1420bfbe053bSmarc 				pw->p_sig = sigval;
1421bfbe053bSmarc 		}
1422bfbe053bSmarc 		else if((mask2&j)==0 && (mask1&j))
1423bfbe053bSmarc 		{
1424bfbe053bSmarc 			if(pw = job_bynum(i))
1425bfbe053bSmarc 				pw->p_sig = 0;
1426bfbe053bSmarc 		}
1427bfbe053bSmarc 	}
1428bfbe053bSmarc }
1429bfbe053bSmarc 
1430bfbe053bSmarc static int open_chan(j)
1431bfbe053bSmarc {
1432bfbe053bSmarc 	sxt[11] = '0' + j;
1433bfbe053bSmarc 	if(fd_chan>=0)
1434bfbe053bSmarc 	{
1435bfbe053bSmarc 		return;
1436bfbe053bSmarc 	}
1437bfbe053bSmarc 	fd_chan = open(sxt,2);
1438bfbe053bSmarc }
1439bfbe053bSmarc #endif	/* SXT */
1440bfbe053bSmarc 
1441bfbe053bSmarc /* XXX */
1442bfbe053bSmarc #ifdef POSIX
1443bfbe053bSmarc cfgetospeed(t)
1444bfbe053bSmarc 	struct termios *t;
1445bfbe053bSmarc {
1446bfbe053bSmarc 	return(t->c_ospeed);
1447bfbe053bSmarc }
1448bfbe053bSmarc #endif
1449