Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/bash/src/builtins/wait.def |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | This file is wait.def, from which is created wait.c. | - | ||||||||||||||||||
2 | It implements the builtin "wait" in Bash. | - | ||||||||||||||||||
3 | - | |||||||||||||||||||
4 | Copyright (C) 1987-2017 Free Software Foundation, Inc. | - | ||||||||||||||||||
5 | - | |||||||||||||||||||
6 | This file is part of GNU Bash, the Bourne Again SHell. | - | ||||||||||||||||||
7 | - | |||||||||||||||||||
8 | Bash is free software: you can redistribute it and/or modify | - | ||||||||||||||||||
9 | it under the terms of the GNU General Public License as published by | - | ||||||||||||||||||
10 | the Free Software Foundation, either version 3 of the License, or | - | ||||||||||||||||||
11 | (at your option) any later version. | - | ||||||||||||||||||
12 | - | |||||||||||||||||||
13 | Bash is distributed in the hope that it will be useful, | - | ||||||||||||||||||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | ||||||||||||||||||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | ||||||||||||||||||
16 | GNU General Public License for more details. | - | ||||||||||||||||||
17 | - | |||||||||||||||||||
18 | You should have received a copy of the GNU General Public License | - | ||||||||||||||||||
19 | along with Bash. If not, see <http://www.gnu.org/licenses/>. | - | ||||||||||||||||||
20 | - | |||||||||||||||||||
21 | $BUILTIN wait | - | ||||||||||||||||||
22 | $FUNCTION wait_builtin | - | ||||||||||||||||||
23 | $DEPENDS_ON JOB_CONTROL | - | ||||||||||||||||||
24 | $PRODUCES wait.c | - | ||||||||||||||||||
25 | $SHORT_DOC wait [-fn] [id ...] | - | ||||||||||||||||||
26 | Wait for job completion and return exit status. | - | ||||||||||||||||||
27 | - | |||||||||||||||||||
28 | Waits for each process identified by an ID, which may be a process ID or a | - | ||||||||||||||||||
29 | job specification, and reports its termination status. If ID is not | - | ||||||||||||||||||
30 | given, waits for all currently active child processes, and the return | - | ||||||||||||||||||
31 | status is zero. If ID is a job specification, waits for all processes | - | ||||||||||||||||||
32 | in that jobs pipeline. | - | ||||||||||||||||||
33 | - | |||||||||||||||||||
34 | If the -n option is supplied, waits for the next job to terminate and | - | ||||||||||||||||||
35 | returns its exit status. | - | ||||||||||||||||||
36 | - | |||||||||||||||||||
37 | If the -f option is supplied, and job control is enabled, waits for the | - | ||||||||||||||||||
38 | specified ID to terminate, instead of waiting for it to change status. | - | ||||||||||||||||||
39 | - | |||||||||||||||||||
40 | Exit Status: | - | ||||||||||||||||||
41 | Returns the status of the last ID; fails if ID is invalid or an invalid | - | ||||||||||||||||||
42 | option is given. | - | ||||||||||||||||||
43 | $END | - | ||||||||||||||||||
44 | - | |||||||||||||||||||
45 | $BUILTIN wait | - | ||||||||||||||||||
46 | $FUNCTION wait_builtin | - | ||||||||||||||||||
47 | $DEPENDS_ON !JOB_CONTROL | - | ||||||||||||||||||
48 | $SHORT_DOC wait [pid ...] | - | ||||||||||||||||||
49 | Wait for process completion and return exit status. | - | ||||||||||||||||||
50 | - | |||||||||||||||||||
51 | Waits for each process specified by a PID and reports its termination status. | - | ||||||||||||||||||
52 | If PID is not given, waits for all currently active child processes, | - | ||||||||||||||||||
53 | and the return status is zero. PID must be a process ID. | - | ||||||||||||||||||
54 | - | |||||||||||||||||||
55 | Exit Status: | - | ||||||||||||||||||
56 | Returns the status of the last PID; fails if PID is invalid or an invalid | - | ||||||||||||||||||
57 | option is given. | - | ||||||||||||||||||
58 | $END | - | ||||||||||||||||||
59 | - | |||||||||||||||||||
60 | #include <config.h> | - | ||||||||||||||||||
61 | - | |||||||||||||||||||
62 | #include "../bashtypes.h" | - | ||||||||||||||||||
63 | #include <signal.h> | - | ||||||||||||||||||
64 | - | |||||||||||||||||||
65 | #if defined (HAVE_UNISTD_H) | - | ||||||||||||||||||
66 | # include <unistd.h> | - | ||||||||||||||||||
67 | #endif | - | ||||||||||||||||||
68 | - | |||||||||||||||||||
69 | #include <chartypes.h> | - | ||||||||||||||||||
70 | - | |||||||||||||||||||
71 | #include "../bashansi.h" | - | ||||||||||||||||||
72 | - | |||||||||||||||||||
73 | #include "../shell.h" | - | ||||||||||||||||||
74 | #include "../execute_cmd.h" | - | ||||||||||||||||||
75 | #include "../jobs.h" | - | ||||||||||||||||||
76 | #include "common.h" | - | ||||||||||||||||||
77 | #include "bashgetopt.h" | - | ||||||||||||||||||
78 | - | |||||||||||||||||||
79 | extern int wait_signal_received; | - | ||||||||||||||||||
80 | - | |||||||||||||||||||
81 | procenv_t wait_intr_buf; | - | ||||||||||||||||||
82 | int wait_intr_flag; | - | ||||||||||||||||||
83 | - | |||||||||||||||||||
84 | /* Wait for the pid in LIST to stop or die. If no arguments are given, then | - | ||||||||||||||||||
85 | wait for all of the active background processes of the shell and return | - | ||||||||||||||||||
86 | 0. If a list of pids or job specs are given, return the exit status of | - | ||||||||||||||||||
87 | the last one waited for. */ | - | ||||||||||||||||||
88 | - | |||||||||||||||||||
89 | #define WAIT_RETURN(s) \ | - | ||||||||||||||||||
90 | do \ | - | ||||||||||||||||||
91 | { \ | - | ||||||||||||||||||
92 | interrupt_immediately = old_interrupt_immediately;\ | - | ||||||||||||||||||
93 | wait_signal_received = 0; \ | - | ||||||||||||||||||
94 | wait_intr_flag = 0; \ | - | ||||||||||||||||||
95 | return (s);\ | - | ||||||||||||||||||
96 | } \ | - | ||||||||||||||||||
97 | while (0) | - | ||||||||||||||||||
98 | - | |||||||||||||||||||
99 | int | - | ||||||||||||||||||
100 | wait_builtin (list) | - | ||||||||||||||||||
101 | WORD_LIST *list; | - | ||||||||||||||||||
102 | { | - | ||||||||||||||||||
103 | int status, code, opt, nflag, wflags; | - | ||||||||||||||||||
104 | volatile int old_interrupt_immediately; | - | ||||||||||||||||||
105 | - | |||||||||||||||||||
106 | USE_VAR(list); | - | ||||||||||||||||||
107 | - | |||||||||||||||||||
108 | nflag = wflags = 0; | - | ||||||||||||||||||
109 | reset_internal_getopt (); | - | ||||||||||||||||||
110 | while ((opt = internal_getopt (list, "nf")) != -1)
| 2-183 | ||||||||||||||||||
111 | { | - | ||||||||||||||||||
112 | switch (opt) | - | ||||||||||||||||||
113 | { | - | ||||||||||||||||||
114 | #if defined (JOB_CONTROL) | - | ||||||||||||||||||
115 | case 'n': executed 1 time by 1 test: case 'n': Executed by:
| 1 | ||||||||||||||||||
116 | nflag = 1; | - | ||||||||||||||||||
117 | break; executed 1 time by 1 test: break; Executed by:
| 1 | ||||||||||||||||||
118 | case 'f': executed 1 time by 1 test: case 'f': Executed by:
| 1 | ||||||||||||||||||
119 | wflags |= JWAIT_FORCE; | - | ||||||||||||||||||
120 | break; executed 1 time by 1 test: break; Executed by:
| 1 | ||||||||||||||||||
121 | #endif | - | ||||||||||||||||||
122 | CASE_HELPOPT; never executed: return (258); never executed: case -99: | 0 | ||||||||||||||||||
123 | default: never executed: default: | 0 | ||||||||||||||||||
124 | builtin_usage (); | - | ||||||||||||||||||
125 | return (EX_USAGE); never executed: return (258); | 0 | ||||||||||||||||||
126 | } | - | ||||||||||||||||||
127 | } | - | ||||||||||||||||||
128 | list = loptend; | - | ||||||||||||||||||
129 | - | |||||||||||||||||||
130 | old_interrupt_immediately = interrupt_immediately; | - | ||||||||||||||||||
131 | #if 0 | - | ||||||||||||||||||
132 | interrupt_immediately++; | - | ||||||||||||||||||
133 | #endif | - | ||||||||||||||||||
134 | - | |||||||||||||||||||
135 | /* POSIX.2 says: When the shell is waiting (by means of the wait utility) | - | ||||||||||||||||||
136 | for asynchronous commands to complete, the reception of a signal for | - | ||||||||||||||||||
137 | which a trap has been set shall cause the wait utility to return | - | ||||||||||||||||||
138 | immediately with an exit status greater than 128, after which the trap | - | ||||||||||||||||||
139 | associated with the signal shall be taken. | - | ||||||||||||||||||
140 | - | |||||||||||||||||||
141 | We handle SIGINT here; it's the only one that needs to be treated | - | ||||||||||||||||||
142 | specially (I think), since it's handled specially in {no,}jobs.c. */ | - | ||||||||||||||||||
143 | wait_intr_flag = 1; | - | ||||||||||||||||||
144 | code = setjmp_sigs (wait_intr_buf); | - | ||||||||||||||||||
145 | - | |||||||||||||||||||
146 | if (code)
| 0-183 | ||||||||||||||||||
147 | { | - | ||||||||||||||||||
148 | last_command_exit_signal = wait_signal_received; | - | ||||||||||||||||||
149 | status = 128 + wait_signal_received; | - | ||||||||||||||||||
150 | wait_sigint_cleanup (); | - | ||||||||||||||||||
151 | WAIT_RETURN (status); never executed: return (status); | 0 | ||||||||||||||||||
152 | } | - | ||||||||||||||||||
153 | - | |||||||||||||||||||
154 | /* We support jobs or pids. | - | ||||||||||||||||||
155 | wait <pid-or-job> [pid-or-job ...] */ | - | ||||||||||||||||||
156 | - | |||||||||||||||||||
157 | #if defined (JOB_CONTROL) | - | ||||||||||||||||||
158 | if (nflag)
| 1-182 | ||||||||||||||||||
159 | { | - | ||||||||||||||||||
160 | status = wait_for_any_job (wflags); | - | ||||||||||||||||||
161 | if (status < 0)
| 0-1 | ||||||||||||||||||
162 | status = 127; never executed: status = 127; | 0 | ||||||||||||||||||
163 | WAIT_RETURN (status); executed 1 time by 1 test: return (status); Executed by:
| 1 | ||||||||||||||||||
164 | } | - | ||||||||||||||||||
165 | #endif | - | ||||||||||||||||||
166 | - | |||||||||||||||||||
167 | /* But wait without any arguments means to wait for all of the shell's | - | ||||||||||||||||||
168 | currently active background processes. */ | - | ||||||||||||||||||
169 | if (list == 0)
| 44-138 | ||||||||||||||||||
170 | { | - | ||||||||||||||||||
171 | wait_for_background_pids (); | - | ||||||||||||||||||
172 | WAIT_RETURN (EXECUTION_SUCCESS); executed 138 times by 1 test: return (0); Executed by:
| 138 | ||||||||||||||||||
173 | } | - | ||||||||||||||||||
174 | - | |||||||||||||||||||
175 | status = EXECUTION_SUCCESS; | - | ||||||||||||||||||
176 | while (list)
| 41-44 | ||||||||||||||||||
177 | { | - | ||||||||||||||||||
178 | pid_t pid; | - | ||||||||||||||||||
179 | char *w; | - | ||||||||||||||||||
180 | intmax_t pid_value; | - | ||||||||||||||||||
181 | - | |||||||||||||||||||
182 | w = list->word->word; | - | ||||||||||||||||||
183 | if (DIGIT (*w))
| 0-26 | ||||||||||||||||||
184 | { | - | ||||||||||||||||||
185 | if (legal_number (w, &pid_value) && pid_value == (pid_t)pid_value)
| 0-23 | ||||||||||||||||||
186 | { | - | ||||||||||||||||||
187 | pid = (pid_t)pid_value; | - | ||||||||||||||||||
188 | status = wait_for_single_pid (pid, wflags|JWAIT_PERROR); | - | ||||||||||||||||||
189 | } executed 23 times by 1 test: end of block Executed by:
| 23 | ||||||||||||||||||
190 | else | - | ||||||||||||||||||
191 | { | - | ||||||||||||||||||
192 | sh_badpid (w); | - | ||||||||||||||||||
193 | WAIT_RETURN (EXECUTION_FAILURE); executed 3 times by 1 test: return (1); Executed by:
| 3 | ||||||||||||||||||
194 | } | - | ||||||||||||||||||
195 | } | - | ||||||||||||||||||
196 | #if defined (JOB_CONTROL) | - | ||||||||||||||||||
197 | else if (*w && *w == '%')
| 0-18 | ||||||||||||||||||
198 | /* Must be a job spec. Check it out. */ | - | ||||||||||||||||||
199 | { | - | ||||||||||||||||||
200 | int job; | - | ||||||||||||||||||
201 | sigset_t set, oset; | - | ||||||||||||||||||
202 | - | |||||||||||||||||||
203 | BLOCK_CHILD (set, oset); | - | ||||||||||||||||||
204 | job = get_job_spec (list); | - | ||||||||||||||||||
205 | - | |||||||||||||||||||
206 | if (INVALID_JOB (job))
| 0-15 | ||||||||||||||||||
207 | { | - | ||||||||||||||||||
208 | if (job != DUP_JOB)
| 0-6 | ||||||||||||||||||
209 | sh_badjob (list->word->word); executed 6 times by 1 test: sh_badjob (list->word->word); Executed by:
| 6 | ||||||||||||||||||
210 | UNBLOCK_CHILD (oset); | - | ||||||||||||||||||
211 | status = 127; /* As per Posix.2, section 4.70.2 */ | - | ||||||||||||||||||
212 | list = list->next; | - | ||||||||||||||||||
213 | continue; executed 6 times by 1 test: continue; Executed by:
| 6 | ||||||||||||||||||
214 | } | - | ||||||||||||||||||
215 | - | |||||||||||||||||||
216 | /* Job spec used. Wait for the last pid in the pipeline. */ | - | ||||||||||||||||||
217 | UNBLOCK_CHILD (oset); | - | ||||||||||||||||||
218 | status = wait_for_job (job, wflags); | - | ||||||||||||||||||
219 | } executed 9 times by 1 test: end of block Executed by:
| 9 | ||||||||||||||||||
220 | #endif /* JOB_CONTROL */ | - | ||||||||||||||||||
221 | else | - | ||||||||||||||||||
222 | { | - | ||||||||||||||||||
223 | sh_badpid (w); | - | ||||||||||||||||||
224 | status = EXECUTION_FAILURE; | - | ||||||||||||||||||
225 | } executed 3 times by 1 test: end of block Executed by:
| 3 | ||||||||||||||||||
226 | list = list->next; | - | ||||||||||||||||||
227 | } executed 35 times by 1 test: end of block Executed by:
| 35 | ||||||||||||||||||
228 | - | |||||||||||||||||||
229 | WAIT_RETURN (status); executed 41 times by 1 test: return (status); Executed by:
| 41 | ||||||||||||||||||
230 | } | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |