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