1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1982-2011 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12da2e3ebdSchin *                                                                      *
13da2e3ebdSchin *              Information and Software Systems Research               *
14da2e3ebdSchin *                            AT&T Research                             *
15da2e3ebdSchin *                           Florham Park NJ                            *
16da2e3ebdSchin *                                                                      *
17da2e3ebdSchin *                  David Korn <dgk@research.att.com>                   *
18da2e3ebdSchin *                                                                      *
19da2e3ebdSchin ***********************************************************************/
20da2e3ebdSchin #pragma prototyped
21da2e3ebdSchin #ifndef JOB_NFLAG
22da2e3ebdSchin /*
23da2e3ebdSchin  *	Interface to job control for shell
24da2e3ebdSchin  *	written by David Korn
25da2e3ebdSchin  *
26da2e3ebdSchin  */
28da2e3ebdSchin #define JOBTTY	2
30da2e3ebdSchin #include	<ast.h>
31da2e3ebdSchin #include	<sfio.h>
32da2e3ebdSchin #ifndef SIGINT
33da2e3ebdSchin #   include	<signal.h>
34da2e3ebdSchin #endif /* !SIGINT */
35da2e3ebdSchin #include	"FEATURE/options"
37*b30d1939SAndy Fiddaman #if SHOPT_COSHELL
38*b30d1939SAndy Fiddaman #   include	<coshell.h>
39*b30d1939SAndy Fiddaman #   define	COPID_BIT	(1L<<30)
40*b30d1939SAndy Fiddaman     struct cosh
41*b30d1939SAndy Fiddaman     {
42*b30d1939SAndy Fiddaman 	struct cosh	*next;
43*b30d1939SAndy Fiddaman 	Coshell_t	*coshell;
44*b30d1939SAndy Fiddaman 	Cojob_t		*cojob;
45*b30d1939SAndy Fiddaman 	char		*name;
46*b30d1939SAndy Fiddaman 	short		id;
47*b30d1939SAndy Fiddaman     };
48*b30d1939SAndy Fiddaman 
49*b30d1939SAndy Fiddaman     extern pid_t	sh_copid(struct cosh*);
50*b30d1939SAndy Fiddaman     extern char  	*sh_pid2str(Shell_t*,pid_t);
51*b30d1939SAndy Fiddaman #endif /* SHOPT_COSHELL */
52*b30d1939SAndy Fiddaman 
53da2e3ebdSchin #undef JOBS
54da2e3ebdSchin #if defined(SIGCLD) && !defined(SIGCHLD)
55da2e3ebdSchin #   define SIGCHLD	SIGCLD
56da2e3ebdSchin #endif
57da2e3ebdSchin #ifdef SIGCHLD
58da2e3ebdSchin #   define JOBS	1
59da2e3ebdSchin #   include	"terminal.h"
60da2e3ebdSchin #   ifdef FIOLOOKLD
61da2e3ebdSchin 	/* Ninth edition */
62da2e3ebdSchin 	extern int tty_ld, ntty_ld;
63da2e3ebdSchin #	define OTTYDISC	tty_ld
64da2e3ebdSchin #	define NTTYDISC	ntty_ld
65da2e3ebdSchin #   endif	/* FIOLOOKLD */
66da2e3ebdSchin #else
67da2e3ebdSchin #   undef SIGTSTP
68da2e3ebdSchin #   undef SH_MONITOR
69da2e3ebdSchin #   define SH_MONITOR	0
70da2e3ebdSchin #   define job_set(x)
71da2e3ebdSchin #   define job_reset(x)
72da2e3ebdSchin #endif
74da2e3ebdSchin struct process
75da2e3ebdSchin {
76da2e3ebdSchin 	struct process *p_nxtjob;	/* next job structure */
77da2e3ebdSchin 	struct process *p_nxtproc;	/* next process in current job */
78*b30d1939SAndy Fiddaman 	Shell_t		*p_shp;		/* shell that posted the job */
79*b30d1939SAndy Fiddaman #if SHOPT_COSHELL
80*b30d1939SAndy Fiddaman 	Cojob_t		*p_cojob;	/* coshell job */
81*b30d1939SAndy Fiddaman #endif /* SHOPT_COSHELL */
82*b30d1939SAndy Fiddaman 	int		*p_exitval;	/* place to store the exitval */
83da2e3ebdSchin 	pid_t		p_pid;		/* process id */
84da2e3ebdSchin 	pid_t		p_pgrp;		/* process group */
85da2e3ebdSchin 	pid_t		p_fgrp;		/* process group when stopped */
86da2e3ebdSchin 	short		p_job;		/* job number of process */
87da2e3ebdSchin 	unsigned short	p_exit;		/* exit value or signal number */
887c2fbfb3SApril Chin 	unsigned short	p_exitmin;	/* minimum exit value for xargs */
89da2e3ebdSchin 	unsigned short	p_flag;		/* flags - see below */
90da2e3ebdSchin 	int		p_env;		/* subshell environment number */
91da2e3ebdSchin #ifdef JOBS
92da2e3ebdSchin 	off_t		p_name;		/* history file offset for command */
93da2e3ebdSchin 	struct termios	p_stty;		/* terminal state for job */
94da2e3ebdSchin #endif /* JOBS */
95da2e3ebdSchin };
97da2e3ebdSchin struct jobs
98da2e3ebdSchin {
99da2e3ebdSchin 	struct process	*pwlist;	/* head of process list */
100*b30d1939SAndy Fiddaman 	int		*exitval;	/* pipe exit values */
101da2e3ebdSchin 	pid_t		curpgid;	/* current process gid id */
102da2e3ebdSchin 	pid_t		parent;		/* set by fork() */
103da2e3ebdSchin 	pid_t		mypid;		/* process id of shell */
104da2e3ebdSchin 	pid_t		mypgid;		/* process group id of shell */
105da2e3ebdSchin 	pid_t		mytgid;		/* terminal group id of shell */
106*b30d1939SAndy Fiddaman 	int		curjobid;
107da2e3ebdSchin 	unsigned int	in_critical;	/* >0 => in critical region */
108da2e3ebdSchin 	int		savesig;	/* active signal */
109da2e3ebdSchin 	int		numpost;	/* number of posted jobs */
11034f9b3eeSRoland Mainz #ifdef SHOPT_BGX
11134f9b3eeSRoland Mainz 	int		numbjob;	/* number of background jobs */
11234f9b3eeSRoland Mainz #endif /* SHOPT_BGX */
113da2e3ebdSchin 	short		fd;		/* tty descriptor number */
114da2e3ebdSchin #ifdef JOBS
115da2e3ebdSchin 	int		suspend;	/* suspend character */
116da2e3ebdSchin 	int		linedisc;	/* line dicipline */
117da2e3ebdSchin #endif /* JOBS */
118da2e3ebdSchin 	char		jobcontrol;	/* turned on for real job control */
119da2e3ebdSchin 	char		waitsafe;	/* wait will not block */
120da2e3ebdSchin 	char		waitall;	/* wait for all jobs in pipe */
121da2e3ebdSchin 	char		toclear;	/* job table needs clearing */
122da2e3ebdSchin 	unsigned char	*freejobs;	/* free jobs numbers */
123*b30d1939SAndy Fiddaman #if SHOPT_COSHELL
124*b30d1939SAndy Fiddaman 	struct cosh	*colist;	/* coshell job list */
125*b30d1939SAndy Fiddaman #endif /* SHOPT_COSHELL */
126da2e3ebdSchin };
128da2e3ebdSchin /* flags for joblist */
129da2e3ebdSchin #define JOB_LFLAG	1
130da2e3ebdSchin #define JOB_NFLAG	2
131da2e3ebdSchin #define JOB_PFLAG	4
132da2e3ebdSchin #define JOB_NLFLAG	8
134da2e3ebdSchin extern struct jobs job;
136da2e3ebdSchin #ifdef JOBS
1387c2fbfb3SApril Chin #if !_std_malloc
1397c2fbfb3SApril Chin #include <vmalloc.h>
140*b30d1939SAndy Fiddaman #ifdef vmlocked
141*b30d1939SAndy Fiddaman #define vmbusy()	vmlocked(Vmregion)
142*b30d1939SAndy Fiddaman #else
1437c2fbfb3SApril Chin #if VMALLOC_VERSION >= 20070911L
1447c2fbfb3SApril Chin #define vmbusy()	(vmstat(0,0)!=0)
1457c2fbfb3SApril Chin #endif
1467c2fbfb3SApril Chin #endif
147*b30d1939SAndy Fiddaman #endif
1487c2fbfb3SApril Chin #ifndef vmbusy
1497c2fbfb3SApril Chin #define vmbusy()	0
1507c2fbfb3SApril Chin #endif
1517c2fbfb3SApril Chin 
152da2e3ebdSchin #define job_lock()	(job.in_critical++)
15334f9b3eeSRoland Mainz #define job_unlock()	\
15434f9b3eeSRoland Mainz 	do { \
15534f9b3eeSRoland Mainz 		int	sig; \
15634f9b3eeSRoland Mainz 		if (!--job.in_critical && (sig = job.savesig)) \
15734f9b3eeSRoland Mainz 		{ \
15834f9b3eeSRoland Mainz 			if (!job.in_critical++ && !vmbusy()) \
15934f9b3eeSRoland Mainz 				job_reap(sig); \
16034f9b3eeSRoland Mainz 			job.in_critical--; \
16134f9b3eeSRoland Mainz 		} \
16234f9b3eeSRoland Mainz 	} while(0)
164da2e3ebdSchin extern const char	e_jobusage[];
165da2e3ebdSchin extern const char	e_done[];
166da2e3ebdSchin extern const char	e_running[];
167da2e3ebdSchin extern const char	e_coredump[];
168da2e3ebdSchin extern const char	e_no_proc[];
169da2e3ebdSchin extern const char	e_no_job[];
170*b30d1939SAndy Fiddaman extern const char	e_badpid[];
171da2e3ebdSchin extern const char	e_jobsrunning[];
172da2e3ebdSchin extern const char	e_nlspace[];
173da2e3ebdSchin extern const char	e_access[];
174da2e3ebdSchin extern const char	e_terminate[];
175da2e3ebdSchin extern const char	e_no_jctl[];
176da2e3ebdSchin extern const char	e_signo[];
177da2e3ebdSchin #ifdef SIGTSTP
178da2e3ebdSchin    extern const char	e_no_start[];
179da2e3ebdSchin #endif /* SIGTSTP */
180da2e3ebdSchin #ifdef NTTYDISC
181da2e3ebdSchin    extern const char	e_newtty[];
182da2e3ebdSchin    extern const char	e_oldtty[];
183da2e3ebdSchin #endif /* NTTYDISC */
184da2e3ebdSchin #endif	/* JOBS */
186da2e3ebdSchin /*
187da2e3ebdSchin  * The following are defined in jobs.c
188da2e3ebdSchin  */
190da2e3ebdSchin extern void	job_clear(void);
191da2e3ebdSchin extern void	job_bwait(char**);
192da2e3ebdSchin extern int	job_walk(Sfio_t*,int(*)(struct process*,int),int,char*[]);
193da2e3ebdSchin extern int	job_kill(struct process*,int);
1947c2fbfb3SApril Chin extern int	job_wait(pid_t);
195*b30d1939SAndy Fiddaman extern int	job_post(Shell_t*,pid_t,pid_t);
196da2e3ebdSchin extern void	*job_subsave(void);
197da2e3ebdSchin extern void	job_subrestore(void*);
19834f9b3eeSRoland Mainz #ifdef SHOPT_BGX
19934f9b3eeSRoland Mainz extern void	job_chldtrap(Shell_t*, const char*,int);
20034f9b3eeSRoland Mainz #endif /* SHOPT_BGX */
201da2e3ebdSchin #ifdef JOBS
2027c2fbfb3SApril Chin 	extern void	job_init(Shell_t*,int);
2037c2fbfb3SApril Chin 	extern int	job_close(Shell_t*);
204da2e3ebdSchin 	extern int	job_list(struct process*,int);
205da2e3ebdSchin 	extern int	job_terminate(struct process*,int);
206*b30d1939SAndy Fiddaman 	extern int	job_hup(struct process *, int);
207da2e3ebdSchin 	extern int	job_switch(struct process*,int);
208da2e3ebdSchin 	extern void	job_fork(pid_t);
209da2e3ebdSchin 	extern int	job_reap(int);
210da2e3ebdSchin #else
2117c2fbfb3SApril Chin #	define job_init(s,flag)
2127c2fbfb3SApril Chin #	define job_close(s)	(0)
213da2e3ebdSchin #	define job_fork(p)
214da2e3ebdSchin #endif	/* JOBS */
217da2e3ebdSchin #endif /* !JOB_NFLAG */