| 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 blockExecuted 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 blockExecuted 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 blockExecuted by:
| 3 | ||||||||||||||||||
| 226 | list = list->next; | - | ||||||||||||||||||
| 227 | } executed 35 times by 1 test: end of blockExecuted 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 |