blob: fe6d53d509dfee5ce95abea07b9f43ac9f1f8a2d [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001This file is wait.def, from which is created wait.c.
2It implements the builtin "wait" in Bash.
3
Chet Rameyac50fba2014-02-26 09:36:43 -05004Copyright (C) 1987-2013 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00005
6This file is part of GNU Bash, the Bourne Again SHell.
7
Jari Aalto31859422009-01-12 13:36:28 +00008Bash is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
Jari Aalto726f6381996-08-26 18:22:31 +000012
Jari Aalto31859422009-01-12 13:36:28 +000013Bash is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
Jari Aalto726f6381996-08-26 18:22:31 +000017
Jari Aalto31859422009-01-12 13:36:28 +000018You should have received a copy of the GNU General Public License
19along with Bash. If not, see <http://www.gnu.org/licenses/>.
Jari Aalto726f6381996-08-26 18:22:31 +000020
Jari Aalto726f6381996-08-26 18:22:31 +000021$BUILTIN wait
22$FUNCTION wait_builtin
23$DEPENDS_ON JOB_CONTROL
24$PRODUCES wait.c
Chet Rameyac50fba2014-02-26 09:36:43 -050025$SHORT_DOC wait [-n] [id ...]
Jari Aalto31859422009-01-12 13:36:28 +000026Wait for job completion and return exit status.
27
Chet Rameyac50fba2014-02-26 09:36:43 -050028Waits for each process identified by an ID, which may be a process ID or a
Jari Aalto31859422009-01-12 13:36:28 +000029job specification, and reports its termination status. If ID is not
30given, waits for all currently active child processes, and the return
31status is zero. If ID is a a job specification, waits for all processes
Chet Rameyac50fba2014-02-26 09:36:43 -050032in that job's pipeline.
33
34If the -n option is supplied, waits for the next job to terminate and
35returns its exit status.
Jari Aalto31859422009-01-12 13:36:28 +000036
37Exit Status:
Chet Rameyac50fba2014-02-26 09:36:43 -050038Returns the status of the last ID; fails if ID is invalid or an invalid
39option is given.
Jari Aalto726f6381996-08-26 18:22:31 +000040$END
41
42$BUILTIN wait
43$FUNCTION wait_builtin
44$DEPENDS_ON !JOB_CONTROL
Chet Rameyac50fba2014-02-26 09:36:43 -050045$SHORT_DOC wait [pid ...]
Jari Aalto31859422009-01-12 13:36:28 +000046Wait for process completion and return exit status.
47
Chet Rameyac50fba2014-02-26 09:36:43 -050048Waits for each process specified by a PID and reports its termination status.
49If PID is not given, waits for all currently active child processes,
50and the return status is zero. PID must be a process ID.
Jari Aalto31859422009-01-12 13:36:28 +000051
52Exit Status:
Chet Rameyac50fba2014-02-26 09:36:43 -050053Returns the status of the last PID; fails if PID is invalid or an invalid
54option is given.
Jari Aalto726f6381996-08-26 18:22:31 +000055$END
56
Jari Aaltoccc6cda1996-12-23 17:02:34 +000057#include <config.h>
58
59#include "../bashtypes.h"
Jari Aalto726f6381996-08-26 18:22:31 +000060#include <signal.h>
Jari Aaltoccc6cda1996-12-23 17:02:34 +000061
62#if defined (HAVE_UNISTD_H)
63# include <unistd.h>
64#endif
65
Jari Aaltof73dda02001-11-13 17:56:06 +000066#include <chartypes.h>
67
Jari Aaltod166f041997-06-05 14:59:13 +000068#include "../bashansi.h"
69
Jari Aalto726f6381996-08-26 18:22:31 +000070#include "../shell.h"
71#include "../jobs.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000072#include "common.h"
Jari Aaltod166f041997-06-05 14:59:13 +000073#include "bashgetopt.h"
Jari Aalto726f6381996-08-26 18:22:31 +000074
Jari Aalto7117c2d2002-07-17 14:10:11 +000075extern int wait_signal_received;
Jari Aalto726f6381996-08-26 18:22:31 +000076
Jari Aaltobb706242000-03-17 21:46:59 +000077procenv_t wait_intr_buf;
78
Jari Aalto726f6381996-08-26 18:22:31 +000079/* Wait for the pid in LIST to stop or die. If no arguments are given, then
80 wait for all of the active background processes of the shell and return
81 0. If a list of pids or job specs are given, return the exit status of
82 the last one waited for. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +000083
Jari Aalto28ef6c32001-04-06 19:14:31 +000084#define WAIT_RETURN(s) \
85 do \
86 { \
87 interrupt_immediately = old_interrupt_immediately;\
Chet Rameyac50fba2014-02-26 09:36:43 -050088 wait_signal_received = 0; \
Jari Aalto28ef6c32001-04-06 19:14:31 +000089 return (s);\
90 } \
91 while (0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +000092
93int
Jari Aalto726f6381996-08-26 18:22:31 +000094wait_builtin (list)
95 WORD_LIST *list;
96{
Chet Rameyac50fba2014-02-26 09:36:43 -050097 int status, code, opt, nflag;
Jari Aalto28ef6c32001-04-06 19:14:31 +000098 volatile int old_interrupt_immediately;
Jari Aaltoccc6cda1996-12-23 17:02:34 +000099
Jari Aaltof73dda02001-11-13 17:56:06 +0000100 USE_VAR(list);
101
Chet Rameyac50fba2014-02-26 09:36:43 -0500102 nflag = 0;
103 reset_internal_getopt ();
104 while ((opt = internal_getopt (list, "n")) != -1)
105 {
106 switch (opt)
107 {
108#if defined (JOB_CONTROL)
109 case 'n':
110 nflag = 1;
111 break;
112#endif
113 default:
114 builtin_usage ();
115 return (EX_USAGE);
116 }
117 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000118 list = loptend;
Jari Aalto726f6381996-08-26 18:22:31 +0000119
Jari Aalto28ef6c32001-04-06 19:14:31 +0000120 old_interrupt_immediately = interrupt_immediately;
Chet Rameyac50fba2014-02-26 09:36:43 -0500121#if 0
Jari Aalto726f6381996-08-26 18:22:31 +0000122 interrupt_immediately++;
Chet Rameyac50fba2014-02-26 09:36:43 -0500123#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000124
Jari Aaltobb706242000-03-17 21:46:59 +0000125 /* POSIX.2 says: When the shell is waiting (by means of the wait utility)
126 for asynchronous commands to complete, the reception of a signal for
127 which a trap has been set shall cause the wait utility to return
128 immediately with an exit status greater than 128, after which the trap
129 associated with the signal shall be taken.
130
131 We handle SIGINT here; it's the only one that needs to be treated
132 specially (I think), since it's handled specially in {no,}jobs.c. */
133 code = setjmp (wait_intr_buf);
134 if (code)
135 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000136 status = 128 + wait_signal_received;
Jari Aaltobb706242000-03-17 21:46:59 +0000137 WAIT_RETURN (status);
138 }
139
Jari Aalto726f6381996-08-26 18:22:31 +0000140 /* We support jobs or pids.
141 wait <pid-or-job> [pid-or-job ...] */
142
Chet Rameyac50fba2014-02-26 09:36:43 -0500143#if defined (JOB_CONTROL)
144 if (nflag)
145 {
146 status = wait_for_any_job ();
147 if (status < 0)
148 status = 127;
149 WAIT_RETURN (status);
150 }
151#endif
152
Jari Aalto726f6381996-08-26 18:22:31 +0000153 /* But wait without any arguments means to wait for all of the shell's
154 currently active background processes. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000155 if (list == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000156 {
157 wait_for_background_pids ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000158 WAIT_RETURN (EXECUTION_SUCCESS);
Jari Aalto726f6381996-08-26 18:22:31 +0000159 }
160
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000161 status = EXECUTION_SUCCESS;
Jari Aalto726f6381996-08-26 18:22:31 +0000162 while (list)
163 {
164 pid_t pid;
165 char *w;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000166 intmax_t pid_value;
Jari Aalto726f6381996-08-26 18:22:31 +0000167
168 w = list->word->word;
Jari Aaltof73dda02001-11-13 17:56:06 +0000169 if (DIGIT (*w))
Jari Aalto726f6381996-08-26 18:22:31 +0000170 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000171 if (legal_number (w, &pid_value) && pid_value == (pid_t)pid_value)
Jari Aalto726f6381996-08-26 18:22:31 +0000172 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000173 pid = (pid_t)pid_value;
Jari Aalto726f6381996-08-26 18:22:31 +0000174 status = wait_for_single_pid (pid);
175 }
176 else
177 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000178 sh_badpid (w);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000179 WAIT_RETURN (EXECUTION_FAILURE);
Jari Aalto726f6381996-08-26 18:22:31 +0000180 }
181 }
182#if defined (JOB_CONTROL)
Jari Aaltob80f6442004-07-27 13:29:18 +0000183 else if (*w && *w == '%')
Jari Aalto726f6381996-08-26 18:22:31 +0000184 /* Must be a job spec. Check it out. */
185 {
186 int job;
187 sigset_t set, oset;
188
189 BLOCK_CHILD (set, oset);
190 job = get_job_spec (list);
191
Jari Aalto95732b42005-12-07 14:08:12 +0000192 if (INVALID_JOB (job))
Jari Aalto726f6381996-08-26 18:22:31 +0000193 {
194 if (job != DUP_JOB)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000195 sh_badjob (list->word->word);
Jari Aalto726f6381996-08-26 18:22:31 +0000196 UNBLOCK_CHILD (oset);
197 status = 127; /* As per Posix.2, section 4.70.2 */
198 list = list->next;
199 continue;
200 }
201
202 /* Job spec used. Wait for the last pid in the pipeline. */
203 UNBLOCK_CHILD (oset);
204 status = wait_for_job (job);
205 }
206#endif /* JOB_CONTROL */
207 else
208 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000209 sh_badpid (w);
Jari Aalto726f6381996-08-26 18:22:31 +0000210 status = EXECUTION_FAILURE;
211 }
212 list = list->next;
213 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000214
215 WAIT_RETURN (status);
Jari Aalto726f6381996-08-26 18:22:31 +0000216}