1.5.1
by Matthias Klose
Import upstream version 4.3~rc1 |
1 |
/* jobs.h -- structures and definitions used by the jobs.c file. */
|
2 |
||
3 |
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
|
|
4 |
||
5 |
This file is part of GNU Bash, the Bourne Again SHell.
|
|
6 |
||
7 |
Bash is free software: you can redistribute it and/or modify
|
|
8 |
it under the terms of the GNU General Public License as published by
|
|
9 |
the Free Software Foundation, either version 3 of the License, or
|
|
10 |
(at your option) any later version.
|
|
11 |
||
12 |
Bash is distributed in the hope that it will be useful,
|
|
13 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 |
GNU General Public License for more details.
|
|
16 |
||
17 |
You should have received a copy of the GNU General Public License
|
|
18 |
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
|
19 |
*/
|
|
20 |
||
21 |
#if !defined (_JOBS_H_)
|
|
22 |
# define _JOBS_H_
|
|
23 |
||
24 |
#include "quit.h" |
|
25 |
#include "siglist.h" |
|
26 |
||
27 |
#include "stdc.h" |
|
28 |
||
29 |
#include "posixwait.h" |
|
30 |
||
31 |
/* Defines controlling the fashion in which jobs are listed. */
|
|
32 |
#define JLIST_STANDARD 0
|
|
33 |
#define JLIST_LONG 1
|
|
34 |
#define JLIST_PID_ONLY 2
|
|
35 |
#define JLIST_CHANGED_ONLY 3
|
|
36 |
#define JLIST_NONINTERACTIVE 4
|
|
37 |
||
38 |
/* I looked it up. For pretty_print_job (). The real answer is 24. */
|
|
39 |
#define LONGEST_SIGNAL_DESC 24
|
|
40 |
||
41 |
/* The max time to sleep while retrying fork() on EAGAIN failure */
|
|
42 |
#define FORKSLEEP_MAX 16
|
|
43 |
||
44 |
/* We keep an array of jobs. Each entry in the array is a linked list
|
|
45 |
of processes that are piped together. The first process encountered is
|
|
46 |
the group leader. */
|
|
47 |
||
48 |
/* Values for the `running' field of a struct process. */
|
|
49 |
#define PS_DONE 0
|
|
50 |
#define PS_RUNNING 1
|
|
51 |
#define PS_STOPPED 2
|
|
52 |
#define PS_RECYCLED 4
|
|
53 |
||
54 |
/* Each child of the shell is remembered in a STRUCT PROCESS. A circular
|
|
55 |
chain of such structures is a pipeline. */
|
|
56 |
typedef struct process { |
|
57 |
struct process *next; /* Next process in the pipeline. A circular chain. */ |
|
58 |
pid_t pid; /* Process ID. */ |
|
59 |
WAIT status; /* The status of this command as returned by wait. */ |
|
60 |
int running; /* Non-zero if this process is running. */ |
|
61 |
char *command; /* The particular program that is running. */ |
|
62 |
} PROCESS; |
|
63 |
||
64 |
/* PALIVE really means `not exited' */
|
|
65 |
#define PSTOPPED(p) (WIFSTOPPED((p)->status))
|
|
66 |
#define PRUNNING(p) ((p)->running == PS_RUNNING)
|
|
67 |
#define PALIVE(p) (PRUNNING(p) || PSTOPPED(p))
|
|
68 |
||
69 |
#define PEXITED(p) ((p)->running == PS_DONE)
|
|
70 |
#if defined (RECYCLES_PIDS)
|
|
71 |
# define PRECYCLED(p) ((p)->running == PS_RECYCLED)
|
|
72 |
#else
|
|
73 |
# define PRECYCLED(p) (0)
|
|
74 |
#endif
|
|
75 |
#define PDEADPROC(p) (PEXITED(p) || PRECYCLED(p))
|
|
76 |
||
77 |
#define get_job_by_jid(ind) (jobs[(ind)])
|
|
78 |
||
79 |
/* A description of a pipeline's state. */
|
|
80 |
typedef enum { JNONE = -1, JRUNNING = 1, JSTOPPED = 2, JDEAD = 4, JMIXED = 8 } JOB_STATE; |
|
81 |
#define JOBSTATE(job) (jobs[(job)]->state)
|
|
82 |
#define J_JOBSTATE(j) ((j)->state)
|
|
83 |
||
84 |
#define STOPPED(j) (jobs[(j)]->state == JSTOPPED)
|
|
85 |
#define RUNNING(j) (jobs[(j)]->state == JRUNNING)
|
|
86 |
#define DEADJOB(j) (jobs[(j)]->state == JDEAD)
|
|
87 |
||
88 |
#define INVALID_JOB(j) ((j) < 0 || (j) >= js.j_jobslots || get_job_by_jid(j) == 0)
|
|
89 |
||
90 |
/* Values for the FLAGS field in the JOB struct below. */
|
|
91 |
#define J_FOREGROUND 0x01 /* Non-zero if this is running in the foreground. */ |
|
92 |
#define J_NOTIFIED 0x02 /* Non-zero if already notified about job state. */ |
|
93 |
#define J_JOBCONTROL 0x04 /* Non-zero if this job started under job control. */ |
|
94 |
#define J_NOHUP 0x08 /* Don't send SIGHUP to job if shell gets SIGHUP. */ |
|
95 |
#define J_STATSAVED 0x10 /* A process in this job had had status saved via $! */ |
|
96 |
#define J_ASYNC 0x20 /* Job was started asynchronously */ |
|
97 |
||
98 |
#define IS_FOREGROUND(j) ((jobs[j]->flags & J_FOREGROUND) != 0)
|
|
99 |
#define IS_NOTIFIED(j) ((jobs[j]->flags & J_NOTIFIED) != 0)
|
|
100 |
#define IS_JOBCONTROL(j) ((jobs[j]->flags & J_JOBCONTROL) != 0)
|
|
101 |
#define IS_ASYNC(j) ((jobs[j]->flags & J_ASYNC) != 0)
|
|
102 |
||
103 |
typedef struct job { |
|
104 |
char *wd; /* The working directory at time of invocation. */ |
|
105 |
PROCESS *pipe; /* The pipeline of processes that make up this job. */ |
|
106 |
pid_t pgrp; /* The process ID of the process group (necessary). */ |
|
107 |
JOB_STATE state; /* The state that this job is in. */ |
|
108 |
int flags; /* Flags word: J_NOTIFIED, J_FOREGROUND, or J_JOBCONTROL. */ |
|
109 |
#if defined (JOB_CONTROL)
|
|
110 |
COMMAND *deferred; /* Commands that will execute when this job is done. */ |
|
111 |
sh_vptrfunc_t *j_cleanup; /* Cleanup function to call when job marked JDEAD */ |
|
112 |
PTR_T cleanarg; /* Argument passed to (*j_cleanup)() */ |
|
113 |
#endif /* JOB_CONTROL */ |
|
114 |
} JOB; |
|
115 |
||
116 |
struct jobstats { |
|
117 |
/* limits */
|
|
118 |
long c_childmax; |
|
119 |
/* child process statistics */
|
|
120 |
int c_living; /* running or stopped child processes */ |
|
121 |
int c_reaped; /* exited child processes still in jobs list */ |
|
122 |
int c_injobs; /* total number of child processes in jobs list */ |
|
123 |
/* child process totals */
|
|
124 |
int c_totforked; /* total number of children this shell has forked */ |
|
125 |
int c_totreaped; /* total number of children this shell has reaped */ |
|
126 |
/* job counters and indices */
|
|
127 |
int j_jobslots; /* total size of jobs array */ |
|
128 |
int j_lastj; /* last (newest) job allocated */ |
|
129 |
int j_firstj; /* first (oldest) job allocated */ |
|
130 |
int j_njobs; /* number of non-NULL jobs in jobs array */ |
|
131 |
int j_ndead; /* number of JDEAD jobs in jobs array */ |
|
132 |
/* */
|
|
133 |
int j_current; /* current job */ |
|
134 |
int j_previous; /* previous job */ |
|
135 |
/* */
|
|
136 |
JOB *j_lastmade; /* last job allocated by stop_pipeline */ |
|
137 |
JOB *j_lastasync; /* last async job allocated by stop_pipeline */ |
|
138 |
};
|
|
139 |
||
140 |
struct pidstat { |
|
141 |
struct pidstat *next; |
|
142 |
pid_t pid; |
|
143 |
int status; |
|
144 |
};
|
|
145 |
||
146 |
struct bgpids { |
|
147 |
struct pidstat *list; |
|
148 |
struct pidstat *end; |
|
149 |
int npid; |
|
150 |
};
|
|
151 |
||
152 |
#define NO_JOB -1 /* An impossible job array index. */ |
|
153 |
#define DUP_JOB -2 /* A possible return value for get_job_spec (). */ |
|
154 |
#define BAD_JOBSPEC -3 /* Bad syntax for job spec. */ |
|
155 |
||
156 |
/* A value which cannot be a process ID. */
|
|
157 |
#define NO_PID (pid_t)-1
|
|
158 |
||
159 |
#define ANY_PID (pid_t)-1
|
|
160 |
||
161 |
/* System calls. */
|
|
162 |
#if !defined (HAVE_UNISTD_H)
|
|
163 |
extern pid_t fork (), getpid (), getpgrp (); |
|
164 |
#endif /* !HAVE_UNISTD_H */ |
|
165 |
||
166 |
/* Stuff from the jobs.c file. */
|
|
167 |
extern struct jobstats js; |
|
168 |
||
169 |
extern pid_t original_pgrp, shell_pgrp, pipeline_pgrp; |
|
170 |
extern volatile pid_t last_made_pid, last_asynchronous_pid; |
|
171 |
extern int asynchronous_notification; |
|
172 |
||
173 |
extern JOB **jobs; |
|
174 |
||
175 |
extern void making_children __P((void)); |
|
176 |
extern void stop_making_children __P((void)); |
|
177 |
extern void cleanup_the_pipeline __P((void)); |
|
178 |
extern void save_pipeline __P((int)); |
|
179 |
extern void restore_pipeline __P((int)); |
|
180 |
extern void start_pipeline __P((void)); |
|
181 |
extern int stop_pipeline __P((int, COMMAND *)); |
|
182 |
extern void append_process __P((char *, pid_t, int, int)); |
|
183 |
||
184 |
extern void delete_job __P((int, int)); |
|
185 |
extern void nohup_job __P((int)); |
|
186 |
extern void delete_all_jobs __P((int)); |
|
187 |
extern void nohup_all_jobs __P((int)); |
|
188 |
||
189 |
extern int count_all_jobs __P((void)); |
|
190 |
||
191 |
extern void terminate_current_pipeline __P((void)); |
|
192 |
extern void terminate_stopped_jobs __P((void)); |
|
193 |
extern void hangup_all_jobs __P((void)); |
|
194 |
extern void kill_current_pipeline __P((void)); |
|
195 |
||
196 |
#if defined (__STDC__) && defined (pid_t)
|
|
197 |
extern int get_job_by_pid __P((int, int)); |
|
198 |
extern void describe_pid __P((int)); |
|
199 |
#else
|
|
200 |
extern int get_job_by_pid __P((pid_t, int)); |
|
201 |
extern void describe_pid __P((pid_t)); |
|
202 |
#endif
|
|
203 |
||
204 |
extern void list_one_job __P((JOB *, int, int, int)); |
|
205 |
extern void list_all_jobs __P((int)); |
|
206 |
extern void list_stopped_jobs __P((int)); |
|
207 |
extern void list_running_jobs __P((int)); |
|
208 |
||
209 |
extern pid_t make_child __P((char *, int)); |
|
210 |
||
211 |
extern int get_tty_state __P((void)); |
|
212 |
extern int set_tty_state __P((void)); |
|
213 |
||
214 |
extern int job_exit_status __P((int)); |
|
215 |
extern int job_exit_signal __P((int)); |
|
216 |
||
217 |
extern int wait_for_single_pid __P((pid_t)); |
|
218 |
extern void wait_for_background_pids __P((void)); |
|
219 |
extern int wait_for __P((pid_t)); |
|
220 |
extern int wait_for_job __P((int)); |
|
221 |
extern int wait_for_any_job __P((void)); |
|
222 |
||
223 |
extern void notify_and_cleanup __P((void)); |
|
224 |
extern void reap_dead_jobs __P((void)); |
|
225 |
extern int start_job __P((int, int)); |
|
226 |
extern int kill_pid __P((pid_t, int, int)); |
|
227 |
extern int initialize_job_control __P((int)); |
|
228 |
extern void initialize_job_signals __P((void)); |
|
229 |
extern int give_terminal_to __P((pid_t, int)); |
|
230 |
||
231 |
extern void run_sigchld_trap __P((int)); |
|
232 |
||
233 |
extern void freeze_jobs_list __P((void)); |
|
234 |
extern void unfreeze_jobs_list __P((void)); |
|
235 |
extern int set_job_control __P((int)); |
|
236 |
extern void without_job_control __P((void)); |
|
237 |
extern void end_job_control __P((void)); |
|
238 |
extern void restart_job_control __P((void)); |
|
239 |
extern void set_sigchld_handler __P((void)); |
|
240 |
extern void ignore_tty_job_signals __P((void)); |
|
241 |
extern void default_tty_job_signals __P((void)); |
|
242 |
||
243 |
extern void init_job_stats __P((void)); |
|
244 |
||
245 |
extern void close_pgrp_pipe __P((void)); |
|
246 |
extern void save_pgrp_pipe __P((int *, int)); |
|
247 |
extern void restore_pgrp_pipe __P((int *)); |
|
248 |
||
249 |
extern void set_maxchild __P((int)); |
|
250 |
||
251 |
extern int job_control; /* set to 0 in nojobs.c */ |
|
252 |
||
253 |
#endif /* _JOBS_H_ */ |