]>
Commit | Line | Data |
---|---|---|
3185942a | 1 | /* jobs.h -- structures and definitions used by the jobs.c file. */ |
726f6388 | 2 | |
74091dd4 | 3 | /* Copyright (C) 1993-2022 Free Software Foundation, Inc. |
726f6388 JA |
4 | |
5 | This file is part of GNU Bash, the Bourne Again SHell. | |
6 | ||
3185942a JA |
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. | |
726f6388 | 11 | |
3185942a JA |
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. | |
726f6388 | 16 | |
3185942a JA |
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 | */ | |
726f6388 | 20 | |
ccc6cda3 JA |
21 | #if !defined (_JOBS_H_) |
22 | # define _JOBS_H_ | |
726f6388 JA |
23 | |
24 | #include "quit.h" | |
25 | #include "siglist.h" | |
26 | ||
27 | #include "stdc.h" | |
28 | ||
d166f048 JA |
29 | #include "posixwait.h" |
30 | ||
726f6388 | 31 | /* Defines controlling the fashion in which jobs are listed. */ |
ccc6cda3 JA |
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 | ||
726f6388 JA |
38 | /* I looked it up. For pretty_print_job (). The real answer is 24. */ |
39 | #define LONGEST_SIGNAL_DESC 24 | |
40 | ||
8868edaf CR |
41 | /* Defines for the wait_for_* functions and for the wait builtin to use */ |
42 | #define JWAIT_PERROR (1 << 0) | |
43 | #define JWAIT_FORCE (1 << 1) | |
44 | #define JWAIT_NOWAIT (1 << 2) /* don't waitpid(), just return status if already exited */ | |
45 | #define JWAIT_WAITING (1 << 3) /* wait for jobs marked J_WAITING only */ | |
46 | ||
47 | /* flags for wait_for */ | |
48 | #define JWAIT_NOTERM (1 << 8) /* wait_for doesn't give terminal away */ | |
d233b485 | 49 | |
3185942a JA |
50 | /* The max time to sleep while retrying fork() on EAGAIN failure */ |
51 | #define FORKSLEEP_MAX 16 | |
52 | ||
726f6388 JA |
53 | /* We keep an array of jobs. Each entry in the array is a linked list |
54 | of processes that are piped together. The first process encountered is | |
55 | the group leader. */ | |
56 | ||
f73dda09 JA |
57 | /* Values for the `running' field of a struct process. */ |
58 | #define PS_DONE 0 | |
59 | #define PS_RUNNING 1 | |
60 | #define PS_STOPPED 2 | |
95732b49 | 61 | #define PS_RECYCLED 4 |
f73dda09 | 62 | |
95732b49 JA |
63 | /* Each child of the shell is remembered in a STRUCT PROCESS. A circular |
64 | chain of such structures is a pipeline. */ | |
726f6388 JA |
65 | typedef struct process { |
66 | struct process *next; /* Next process in the pipeline. A circular chain. */ | |
67 | pid_t pid; /* Process ID. */ | |
68 | WAIT status; /* The status of this command as returned by wait. */ | |
69 | int running; /* Non-zero if this process is running. */ | |
70 | char *command; /* The particular program that is running. */ | |
71 | } PROCESS; | |
72 | ||
a0c0a00f CR |
73 | struct pipeline_saver { |
74 | struct process *pipeline; | |
75 | struct pipeline_saver *next; | |
76 | }; | |
77 | ||
95732b49 | 78 | /* PALIVE really means `not exited' */ |
7117c2d2 | 79 | #define PSTOPPED(p) (WIFSTOPPED((p)->status)) |
95732b49 JA |
80 | #define PRUNNING(p) ((p)->running == PS_RUNNING) |
81 | #define PALIVE(p) (PRUNNING(p) || PSTOPPED(p)) | |
82 | ||
83 | #define PEXITED(p) ((p)->running == PS_DONE) | |
84 | #if defined (RECYCLES_PIDS) | |
85 | # define PRECYCLED(p) ((p)->running == PS_RECYCLED) | |
86 | #else | |
87 | # define PRECYCLED(p) (0) | |
88 | #endif | |
89 | #define PDEADPROC(p) (PEXITED(p) || PRECYCLED(p)) | |
90 | ||
91 | #define get_job_by_jid(ind) (jobs[(ind)]) | |
7117c2d2 | 92 | |
726f6388 | 93 | /* A description of a pipeline's state. */ |
3185942a | 94 | typedef enum { JNONE = -1, JRUNNING = 1, JSTOPPED = 2, JDEAD = 4, JMIXED = 8 } JOB_STATE; |
95732b49 JA |
95 | #define JOBSTATE(job) (jobs[(job)]->state) |
96 | #define J_JOBSTATE(j) ((j)->state) | |
726f6388 | 97 | |
ccc6cda3 JA |
98 | #define STOPPED(j) (jobs[(j)]->state == JSTOPPED) |
99 | #define RUNNING(j) (jobs[(j)]->state == JRUNNING) | |
100 | #define DEADJOB(j) (jobs[(j)]->state == JDEAD) | |
101 | ||
95732b49 JA |
102 | #define INVALID_JOB(j) ((j) < 0 || (j) >= js.j_jobslots || get_job_by_jid(j) == 0) |
103 | ||
726f6388 JA |
104 | /* Values for the FLAGS field in the JOB struct below. */ |
105 | #define J_FOREGROUND 0x01 /* Non-zero if this is running in the foreground. */ | |
106 | #define J_NOTIFIED 0x02 /* Non-zero if already notified about job state. */ | |
107 | #define J_JOBCONTROL 0x04 /* Non-zero if this job started under job control. */ | |
ccc6cda3 | 108 | #define J_NOHUP 0x08 /* Don't send SIGHUP to job if shell gets SIGHUP. */ |
8868edaf | 109 | #define J_STATSAVED 0x10 /* A process in this job had status saved via $! */ |
95732b49 | 110 | #define J_ASYNC 0x20 /* Job was started asynchronously */ |
d233b485 | 111 | #define J_PIPEFAIL 0x40 /* pipefail set when job was started */ |
8868edaf | 112 | #define J_WAITING 0x80 /* one of a list of jobs for which we are waiting */ |
ccc6cda3 JA |
113 | |
114 | #define IS_FOREGROUND(j) ((jobs[j]->flags & J_FOREGROUND) != 0) | |
115 | #define IS_NOTIFIED(j) ((jobs[j]->flags & J_NOTIFIED) != 0) | |
116 | #define IS_JOBCONTROL(j) ((jobs[j]->flags & J_JOBCONTROL) != 0) | |
95732b49 | 117 | #define IS_ASYNC(j) ((jobs[j]->flags & J_ASYNC) != 0) |
8868edaf | 118 | #define IS_WAITING(j) ((jobs[j]->flags & J_WAITING) != 0) |
726f6388 JA |
119 | |
120 | typedef struct job { | |
121 | char *wd; /* The working directory at time of invocation. */ | |
122 | PROCESS *pipe; /* The pipeline of processes that make up this job. */ | |
123 | pid_t pgrp; /* The process ID of the process group (necessary). */ | |
124 | JOB_STATE state; /* The state that this job is in. */ | |
125 | int flags; /* Flags word: J_NOTIFIED, J_FOREGROUND, or J_JOBCONTROL. */ | |
126 | #if defined (JOB_CONTROL) | |
127 | COMMAND *deferred; /* Commands that will execute when this job is done. */ | |
f73dda09 | 128 | sh_vptrfunc_t *j_cleanup; /* Cleanup function to call when job marked JDEAD */ |
ccc6cda3 | 129 | PTR_T cleanarg; /* Argument passed to (*j_cleanup)() */ |
726f6388 JA |
130 | #endif /* JOB_CONTROL */ |
131 | } JOB; | |
132 | ||
95732b49 JA |
133 | struct jobstats { |
134 | /* limits */ | |
135 | long c_childmax; | |
136 | /* child process statistics */ | |
137 | int c_living; /* running or stopped child processes */ | |
138 | int c_reaped; /* exited child processes still in jobs list */ | |
139 | int c_injobs; /* total number of child processes in jobs list */ | |
140 | /* child process totals */ | |
141 | int c_totforked; /* total number of children this shell has forked */ | |
142 | int c_totreaped; /* total number of children this shell has reaped */ | |
143 | /* job counters and indices */ | |
144 | int j_jobslots; /* total size of jobs array */ | |
145 | int j_lastj; /* last (newest) job allocated */ | |
146 | int j_firstj; /* first (oldest) job allocated */ | |
147 | int j_njobs; /* number of non-NULL jobs in jobs array */ | |
148 | int j_ndead; /* number of JDEAD jobs in jobs array */ | |
149 | /* */ | |
150 | int j_current; /* current job */ | |
151 | int j_previous; /* previous job */ | |
152 | /* */ | |
153 | JOB *j_lastmade; /* last job allocated by stop_pipeline */ | |
154 | JOB *j_lastasync; /* last async job allocated by stop_pipeline */ | |
155 | }; | |
156 | ||
a0c0a00f CR |
157 | /* Revised to accommodate new hash table bgpids implementation. */ |
158 | typedef pid_t ps_index_t; | |
159 | ||
95732b49 | 160 | struct pidstat { |
a0c0a00f CR |
161 | ps_index_t bucket_next; |
162 | ps_index_t bucket_prev; | |
163 | ||
164 | pid_t pid; | |
165 | bits16_t status; /* only 8 bits really needed */ | |
95732b49 JA |
166 | }; |
167 | ||
168 | struct bgpids { | |
a0c0a00f CR |
169 | struct pidstat *storage; /* storage arena */ |
170 | ||
171 | ps_index_t head; | |
172 | ps_index_t nalloc; | |
173 | ||
95732b49 JA |
174 | int npid; |
175 | }; | |
176 | ||
a0c0a00f CR |
177 | #define NO_PIDSTAT (ps_index_t)-1 |
178 | ||
8868edaf CR |
179 | /* standalone process status struct, without bgpids indexes */ |
180 | struct procstat { | |
181 | pid_t pid; | |
182 | bits16_t status; | |
183 | }; | |
184 | ||
185 | /* A standalone singly-linked list of PROCESS *, used in various places | |
186 | including keeping track of process substitutions. */ | |
187 | struct procchain { | |
188 | PROCESS *head; | |
189 | PROCESS *end; | |
190 | int nproc; | |
191 | }; | |
192 | ||
726f6388 JA |
193 | #define NO_JOB -1 /* An impossible job array index. */ |
194 | #define DUP_JOB -2 /* A possible return value for get_job_spec (). */ | |
b80f6443 | 195 | #define BAD_JOBSPEC -3 /* Bad syntax for job spec. */ |
726f6388 JA |
196 | |
197 | /* A value which cannot be a process ID. */ | |
198 | #define NO_PID (pid_t)-1 | |
199 | ||
ac50fbac CR |
200 | #define ANY_PID (pid_t)-1 |
201 | ||
8868edaf CR |
202 | /* flags for make_child () */ |
203 | #define FORK_SYNC 0 /* normal synchronous process */ | |
204 | #define FORK_ASYNC 1 /* background process */ | |
205 | #define FORK_NOJOB 2 /* don't put process in separate pgrp */ | |
206 | #define FORK_NOTERM 4 /* don't give terminal to any pgrp */ | |
207 | ||
726f6388 | 208 | /* System calls. */ |
ccc6cda3 | 209 | #if !defined (HAVE_UNISTD_H) |
726f6388 | 210 | extern pid_t fork (), getpid (), getpgrp (); |
ccc6cda3 | 211 | #endif /* !HAVE_UNISTD_H */ |
726f6388 JA |
212 | |
213 | /* Stuff from the jobs.c file. */ | |
95732b49 JA |
214 | extern struct jobstats js; |
215 | ||
bb70624e | 216 | extern pid_t original_pgrp, shell_pgrp, pipeline_pgrp; |
ac50fbac | 217 | extern volatile pid_t last_made_pid, last_asynchronous_pid; |
726f6388 | 218 | extern int asynchronous_notification; |
95732b49 | 219 | |
d233b485 CR |
220 | extern int already_making_children; |
221 | extern int running_in_background; | |
222 | ||
223 | extern PROCESS *last_procsub_child; | |
224 | ||
726f6388 | 225 | extern JOB **jobs; |
726f6388 | 226 | |
8868edaf CR |
227 | extern void making_children PARAMS((void)); |
228 | extern void stop_making_children PARAMS((void)); | |
229 | extern void cleanup_the_pipeline PARAMS((void)); | |
230 | extern void discard_last_procsub_child PARAMS((void)); | |
231 | extern void save_pipeline PARAMS((int)); | |
232 | extern PROCESS *restore_pipeline PARAMS((int)); | |
233 | extern void start_pipeline PARAMS((void)); | |
234 | extern int stop_pipeline PARAMS((int, COMMAND *)); | |
235 | extern int discard_pipeline PARAMS((PROCESS *)); | |
236 | extern void append_process PARAMS((char *, pid_t, int, int)); | |
237 | ||
238 | extern void save_proc_status PARAMS((pid_t, int)); | |
239 | ||
240 | extern PROCESS *procsub_add PARAMS((PROCESS *)); | |
241 | extern PROCESS *procsub_search PARAMS((pid_t)); | |
242 | extern PROCESS *procsub_delete PARAMS((pid_t)); | |
243 | extern int procsub_waitpid PARAMS((pid_t)); | |
244 | extern void procsub_waitall PARAMS((void)); | |
245 | extern void procsub_clear PARAMS((void)); | |
246 | extern void procsub_prune PARAMS((void)); | |
247 | ||
248 | extern void delete_job PARAMS((int, int)); | |
249 | extern void nohup_job PARAMS((int)); | |
250 | extern void delete_all_jobs PARAMS((int)); | |
251 | extern void nohup_all_jobs PARAMS((int)); | |
252 | ||
253 | extern int count_all_jobs PARAMS((void)); | |
254 | ||
255 | extern void terminate_current_pipeline PARAMS((void)); | |
256 | extern void terminate_stopped_jobs PARAMS((void)); | |
257 | extern void hangup_all_jobs PARAMS((void)); | |
258 | extern void kill_current_pipeline PARAMS((void)); | |
726f6388 JA |
259 | |
260 | #if defined (__STDC__) && defined (pid_t) | |
8868edaf CR |
261 | extern int get_job_by_pid PARAMS((int, int, PROCESS **)); |
262 | extern void describe_pid PARAMS((int)); | |
726f6388 | 263 | #else |
8868edaf CR |
264 | extern int get_job_by_pid PARAMS((pid_t, int, PROCESS **)); |
265 | extern void describe_pid PARAMS((pid_t)); | |
726f6388 JA |
266 | #endif |
267 | ||
8868edaf CR |
268 | extern void list_one_job PARAMS((JOB *, int, int, int)); |
269 | extern void list_all_jobs PARAMS((int)); | |
270 | extern void list_stopped_jobs PARAMS((int)); | |
271 | extern void list_running_jobs PARAMS((int)); | |
726f6388 | 272 | |
8868edaf | 273 | extern pid_t make_child PARAMS((char *, int)); |
bb70624e | 274 | |
8868edaf CR |
275 | extern int get_tty_state PARAMS((void)); |
276 | extern int set_tty_state PARAMS((void)); | |
726f6388 | 277 | |
8868edaf CR |
278 | extern int job_exit_status PARAMS((int)); |
279 | extern int job_exit_signal PARAMS((int)); | |
495aee44 | 280 | |
8868edaf | 281 | extern int wait_for_single_pid PARAMS((pid_t, int)); |
74091dd4 | 282 | extern int wait_for_background_pids PARAMS((struct procstat *)); |
8868edaf CR |
283 | extern int wait_for PARAMS((pid_t, int)); |
284 | extern int wait_for_job PARAMS((int, int, struct procstat *)); | |
285 | extern int wait_for_any_job PARAMS((int, struct procstat *)); | |
726f6388 | 286 | |
8868edaf | 287 | extern void wait_sigint_cleanup PARAMS((void)); |
a0c0a00f | 288 | |
8868edaf CR |
289 | extern void notify_and_cleanup PARAMS((void)); |
290 | extern void reap_dead_jobs PARAMS((void)); | |
291 | extern int start_job PARAMS((int, int)); | |
292 | extern int kill_pid PARAMS((pid_t, int, int)); | |
293 | extern int initialize_job_control PARAMS((int)); | |
294 | extern void initialize_job_signals PARAMS((void)); | |
295 | extern int give_terminal_to PARAMS((pid_t, int)); | |
726f6388 | 296 | |
8868edaf | 297 | extern void run_sigchld_trap PARAMS((int)); |
3185942a | 298 | |
8868edaf CR |
299 | extern int freeze_jobs_list PARAMS((void)); |
300 | extern void unfreeze_jobs_list PARAMS((void)); | |
301 | extern void set_jobs_list_frozen PARAMS((int)); | |
302 | extern int set_job_control PARAMS((int)); | |
303 | extern void without_job_control PARAMS((void)); | |
304 | extern void end_job_control PARAMS((void)); | |
305 | extern void restart_job_control PARAMS((void)); | |
306 | extern void set_sigchld_handler PARAMS((void)); | |
307 | extern void ignore_tty_job_signals PARAMS((void)); | |
308 | extern void default_tty_job_signals PARAMS((void)); | |
309 | extern void get_original_tty_job_signals PARAMS((void)); | |
726f6388 | 310 | |
8868edaf | 311 | extern void init_job_stats PARAMS((void)); |
95732b49 | 312 | |
8868edaf CR |
313 | extern void close_pgrp_pipe PARAMS((void)); |
314 | extern void save_pgrp_pipe PARAMS((int *, int)); | |
315 | extern void restore_pgrp_pipe PARAMS((int *)); | |
3185942a | 316 | |
8868edaf | 317 | extern void set_maxchild PARAMS((int)); |
ac50fbac | 318 | |
74091dd4 CR |
319 | #ifdef DEBUG |
320 | extern void debug_print_pgrps (void); | |
321 | #endif | |
322 | ||
ac50fbac | 323 | extern int job_control; /* set to 0 in nojobs.c */ |
726f6388 | 324 | |
ccc6cda3 | 325 | #endif /* _JOBS_H_ */ |