View | Details | Raw Unified | Return to bug 170346 | Differences between
and this patch

Collapse All | Expand All

(-)sys/sys/wait.h (+5 lines)
Lines 80-85 Link Here
80
#define	WSTOPPED	WUNTRACED   /* SUS compatibility */
80
#define	WSTOPPED	WUNTRACED   /* SUS compatibility */
81
#define	WCONTINUED	4	/* Report a job control continued process. */
81
#define	WCONTINUED	4	/* Report a job control continued process. */
82
#define	WNOWAIT		8	/* Poll only. Don't delete the proc entry. */
82
#define	WNOWAIT		8	/* Poll only. Don't delete the proc entry. */
83
#define WEXITED		16	/* Wait for exited processes. (SUS) */
84
#define WTRAPPED	32	/* Wait for a process to hit a trap or a breakpoint. (Solaris) */
83
85
84
#if __BSD_VISIBLE
86
#if __BSD_VISIBLE
85
#define	WLINUXCLONE 0x80000000	/* Wait for kthread spawned from linux_clone. */
87
#define	WLINUXCLONE 0x80000000	/* Wait for kthread spawned from linux_clone. */
Lines 95-108 Link Here
95
97
96
#ifndef _KERNEL
98
#ifndef _KERNEL
97
#include <sys/types.h>
99
#include <sys/types.h>
100
#include <sys/signal.h>
98
101
99
__BEGIN_DECLS
102
__BEGIN_DECLS
100
pid_t	wait(int *);
103
pid_t	wait(int *);
101
pid_t	waitpid(pid_t, int *, int);
104
pid_t	waitpid(pid_t, int *, int);
105
int	waitid(idtype_t, id_t, siginfo_t *, int);
102
#if __BSD_VISIBLE
106
#if __BSD_VISIBLE
103
struct rusage;
107
struct rusage;
104
pid_t	wait3(int *, int, struct rusage *);
108
pid_t	wait3(int *, int, struct rusage *);
105
pid_t	wait4(pid_t, int *, int, struct rusage *);
109
pid_t	wait4(pid_t, int *, int, struct rusage *);
110
pid_t	wait6(idtype_t, id_t, int *, int, struct rusage *, siginfo_t *);
106
#endif
111
#endif
107
__END_DECLS
112
__END_DECLS
108
#endif /* !_KERNEL */
113
#endif /* !_KERNEL */
(-)sys/sys/syscallsubr.h (+2 lines)
Lines 233-238 Link Here
233
	    enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg);
233
	    enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg);
234
int	kern_wait(struct thread *td, pid_t pid, int *status, int options,
234
int	kern_wait(struct thread *td, pid_t pid, int *status, int options,
235
	    struct rusage *rup);
235
	    struct rusage *rup);
236
int	kern_wait6(struct thread *td, idtype_t idtype, id_t id, int *status,
237
		   int options, struct rusage *rup, siginfo_t *sip);
236
int	kern_writev(struct thread *td, int fd, struct uio *auio);
238
int	kern_writev(struct thread *td, int fd, struct uio *auio);
237
int	kern_socketpair(struct thread *td, int domain, int type, int protocol,
239
int	kern_socketpair(struct thread *td, int domain, int type, int protocol,
238
	    int *rsv);
240
	    int *rsv);
(-)sys/bsm/audit_kevents.h (+1 lines)
Lines 602-607 Link Here
602
#define	AUE_PDKILL		43198	/* FreeBSD. */
602
#define	AUE_PDKILL		43198	/* FreeBSD. */
603
#define	AUE_PDGETPID		43199	/* FreeBSD. */
603
#define	AUE_PDGETPID		43199	/* FreeBSD. */
604
#define	AUE_PDWAIT		43200	/* FreeBSD. */
604
#define	AUE_PDWAIT		43200	/* FreeBSD. */
605
#define	AUE_WAIT6		43201	/* FreeBSD. */
605
606
606
/*
607
/*
607
 * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
608
 * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
(-)sys/kern/syscalls.master (-2 / +6 lines)
Lines 72-78 Link Here
72
6	AUE_CLOSE	STD	{ int close(int fd); }
72
6	AUE_CLOSE	STD	{ int close(int fd); }
73
7	AUE_WAIT4	STD	{ int wait4(int pid, int *status, \
73
7	AUE_WAIT4	STD	{ int wait4(int pid, int *status, \
74
				    int options, struct rusage *rusage); } \
74
				    int options, struct rusage *rusage); } \
75
				    wait4 wait_args int
75
				    wait4 wait4_args int
76
8	AUE_CREAT	COMPAT	{ int creat(char *path, int mode); }
76
8	AUE_CREAT	COMPAT	{ int creat(char *path, int mode); }
77
9	AUE_LINK	STD	{ int link(char *path, char *link); }
77
9	AUE_LINK	STD	{ int link(char *path, char *link); }
78
10	AUE_UNLINK	STD	{ int unlink(char *path); }
78
10	AUE_UNLINK	STD	{ int unlink(char *path); }
Lines 368-374 Link Here
368
190	AUE_LSTAT	STD	{ int lstat(char *path, struct stat *ub); }
368
190	AUE_LSTAT	STD	{ int lstat(char *path, struct stat *ub); }
369
191	AUE_PATHCONF	STD	{ int pathconf(char *path, int name); }
369
191	AUE_PATHCONF	STD	{ int pathconf(char *path, int name); }
370
192	AUE_FPATHCONF	STD	{ int fpathconf(int fd, int name); }
370
192	AUE_FPATHCONF	STD	{ int fpathconf(int fd, int name); }
371
193	AUE_NULL	UNIMPL	nosys
371
193	AUE_WAIT6	STD	{ int wait6(int idtype, int pid, \
372
					    int *status, int options, \
373
					    struct rusage *rusage, \
374
					    siginfo_t *info); } \
375
					wait6 wait6_args int
372
194	AUE_GETRLIMIT	STD	{ int getrlimit(u_int which, \
376
194	AUE_GETRLIMIT	STD	{ int getrlimit(u_int which, \
373
				    struct rlimit *rlp); } getrlimit \
377
				    struct rlimit *rlp); } getrlimit \
374
				    __getrlimit_args int
378
				    __getrlimit_args int
(-)lib/libc/include/namespace.h (+1 lines)
Lines 229-234 Link Here
229
#define		socketpair			_socketpair
229
#define		socketpair			_socketpair
230
#define		usleep				_usleep
230
#define		usleep				_usleep
231
#define		wait4				_wait4
231
#define		wait4				_wait4
232
#define		wait6				_wait6
232
#define		waitpid				_waitpid
233
#define		waitpid				_waitpid
233
#define		write				_write
234
#define		write				_write
234
#define		writev				_writev
235
#define		writev				_writev
(-)lib/libc/include/un-namespace.h (+1 lines)
Lines 210-215 Link Here
210
#undef		socketpair
210
#undef		socketpair
211
#undef		usleep
211
#undef		usleep
212
#undef		wait4
212
#undef		wait4
213
#undef		wait6
213
#undef		waitpid
214
#undef		waitpid
214
#undef		write
215
#undef		write
215
#undef		writev
216
#undef		writev
(-)lib/libc/gen/Makefile.inc (-1 / +1 lines)
Lines 34-40 Link Here
34
	syslog.c telldir.c termios.c time.c times.c timezone.c tls.c \
34
	syslog.c telldir.c termios.c time.c times.c timezone.c tls.c \
35
	ttyname.c ttyslot.c ualarm.c ulimit.c uname.c unvis.c \
35
	ttyname.c ttyslot.c ualarm.c ulimit.c uname.c unvis.c \
36
	usleep.c utime.c utxdb.c valloc.c vis.c wait.c wait3.c waitpid.c \
36
	usleep.c utime.c utxdb.c valloc.c vis.c wait.c wait3.c waitpid.c \
37
	wordexp.c
37
	waitid.c wordexp.c
38
38
39
CANCELPOINTS_SRCS=sem.c sem_new.c
39
CANCELPOINTS_SRCS=sem.c sem_new.c
40
.for src in ${CANCELPOINTS_SRCS}
40
.for src in ${CANCELPOINTS_SRCS}
(-)sys/cddl/contrib/opensolaris/uts/common/sys/procset.h (+5 lines)
Lines 51-56 Link Here
51
#define	P_INITUID	0
51
#define	P_INITUID	0
52
#define	P_INITPGID	0
52
#define	P_INITPGID	0
53
53
54
#ifndef _IDTYPE_T_DECLARED
54
55
55
/*
56
/*
56
 *	The following defines the values for an identifier type.  It
57
 *	The following defines the values for an identifier type.  It
Lines 79-86 Link Here
79
	P_CTID,		/* A (process) contract identifier.	*/
80
	P_CTID,		/* A (process) contract identifier.	*/
80
	P_CPUID,	/* CPU identifier.			*/
81
	P_CPUID,	/* CPU identifier.			*/
81
	P_PSETID	/* Processor set identifier		*/
82
	P_PSETID	/* Processor set identifier		*/
83
82
} idtype_t;
84
} idtype_t;
83
85
86
#define	_IDTYPE_T_DECLARED
87
88
#endif
84
89
85
/*
90
/*
86
 *	The following defines the operations which can be performed to
91
 *	The following defines the operations which can be performed to
(-)sys/sys/proc.h (-2 / +1 lines)
Lines 879-886 Link Here
879
void	procinit(void);
879
void	procinit(void);
880
void	proc_linkup0(struct proc *p, struct thread *td);
880
void	proc_linkup0(struct proc *p, struct thread *td);
881
void	proc_linkup(struct proc *p, struct thread *td);
881
void	proc_linkup(struct proc *p, struct thread *td);
882
void	proc_reap(struct thread *td, struct proc *p, int *status, int options,
882
void	proc_reap(struct thread *td, struct proc *p, int *status, int options);
883
	    struct rusage *rusage);
884
void	proc_reparent(struct proc *child, struct proc *newparent);
883
void	proc_reparent(struct proc *child, struct proc *newparent);
885
struct	pstats *pstats_alloc(void);
884
struct	pstats *pstats_alloc(void);
886
void	pstats_fork(struct pstats *src, struct pstats *dst);
885
void	pstats_fork(struct pstats *src, struct pstats *dst);
(-)lib/libc/gen/Symbol.map (+1 lines)
Lines 384-389 Link Here
384
	 fdlopen;
384
	 fdlopen;
385
	__FreeBSD_libc_enter_restricted_mode;
385
	__FreeBSD_libc_enter_restricted_mode;
386
	getcontextx;
386
	getcontextx;
387
	waitid;
387
};
388
};
388
389
389
FBSDprivate_1.0 {
390
FBSDprivate_1.0 {
(-)sys/sys/types.h (+39 lines)
Lines 142-147 Link Here
142
#define	_ID_T_DECLARED
142
#define	_ID_T_DECLARED
143
#endif
143
#endif
144
144
145
#ifndef _IDTYPE_T_DECLARED
146
147
typedef enum
148
#if !defined(_XPG4_2) || defined(__EXTENSIONS__)
149
	idtype		/* pollutes XPG4.2 namespace */
150
#endif
151
		{
152
	/*
153
	 * These names were mostly lifted from Solaris source code
154
	 * and still use Solaris style naming to avoid breaking any
155
	 * OpenSolaris code which has been ported to FreeBSD.
156
	 * There is no clear FreeBSD counterpart for all of the names.
157
	 * OTOH some have a clear correspondence to FreeBSD entities.
158
	 */
159
	
160
	P_PID,		/* A process identifier.		*/
161
	P_PPID,		/* A parent process identifier.		*/
162
	P_PGID,		/* A process group (job control group)	*/
163
			/* identifier.				*/
164
	P_SID,		/* A session identifier.		*/
165
	P_CID,		/* A scheduling class identifier.	*/
166
	P_UID,		/* A user identifier.			*/
167
	P_GID,		/* A group identifier.			*/
168
	P_ALL,		/* All processes.			*/
169
	P_LWPID,	/* An LWP identifier.			*/
170
	P_TASKID,	/* A task identifier.			*/
171
	P_PROJID,	/* A project identifier.		*/
172
	P_POOLID,	/* A pool identifier.			*/
173
	P_ZONEID,	/* A zone identifier.			*/
174
	P_CTID,		/* A (process) contract identifier.	*/
175
	P_CPUID,	/* CPU identifier.			*/
176
	P_PSETID	/* Processor set identifier		*/
177
178
} idtype_t;		/* The type of id_t we are using.	*/
179
180
#define	_IDTYPE_T_DECLARED
181
#endif
182
183
145
#ifndef _INO_T_DECLARED
184
#ifndef _INO_T_DECLARED
146
typedef	__ino_t		ino_t;		/* inode number */
185
typedef	__ino_t		ino_t;		/* inode number */
147
#define	_INO_T_DECLARED
186
#define	_INO_T_DECLARED
(-)lib/libc/sys/wait.2 (-23 / +280 lines)
Lines 34-42 Link Here
34
.Sh NAME
34
.Sh NAME
35
.Nm wait ,
35
.Nm wait ,
36
.Nm waitpid ,
36
.Nm waitpid ,
37
.Nm waitid ,
38
.Nm wait3 ,
37
.Nm wait4 ,
39
.Nm wait4 ,
38
.Nm wait3
40
.Nm wait6
39
.Nd wait for process termination
41
.Nd wait for processes to change status
40
.Sh LIBRARY
42
.Sh LIBRARY
41
.Lb libc
43
.Lb libc
42
.Sh SYNOPSIS
44
.Sh SYNOPSIS
Lines 46-57 Link Here
46
.Fn wait "int *status"
48
.Fn wait "int *status"
47
.Ft pid_t
49
.Ft pid_t
48
.Fn waitpid "pid_t wpid" "int *status" "int options"
50
.Fn waitpid "pid_t wpid" "int *status" "int options"
51
.In sys/signal.h
52
.Ft int
53
.Fn waitid "idtype_t idtype" "id_t id" "siginfo_t *info" "int options"
49
.In sys/time.h
54
.In sys/time.h
50
.In sys/resource.h
55
.In sys/resource.h
51
.Ft pid_t
56
.Ft pid_t
52
.Fn wait3 "int *status" "int options" "struct rusage *rusage"
57
.Fn wait3 "int *status" "int options" "struct rusage *rusage"
53
.Ft pid_t
58
.Ft pid_t
54
.Fn wait4 "pid_t wpid" "int *status" "int options" "struct rusage *rusage"
59
.Fn wait4 "pid_t wpid" "int *status" "int options" "struct rusage *rusage"
60
.Ft pid_t
61
.Fn wait6 "idtype_t idtype" "id_t id" "int *status" "int options" "struct rusage *rusage" "siginfo_t *infop"
55
.Sh DESCRIPTION
62
.Sh DESCRIPTION
56
The
63
The
57
.Fn wait
64
.Fn wait
Lines 89-113 Link Here
89
The other wait functions are implemented using
96
The other wait functions are implemented using
90
.Fn wait4 .
97
.Fn wait4 .
91
.Pp
98
.Pp
99
The broadest interface of all functions in this family is
100
.Fn wait6
101
which is otherwise very much like
102
.Fn wait4
103
but with a few very important distinctions.
104
.br
105
It will not wait for existed processes unless the option flag 
106
.Dv WEXITED
107
is explicitly specified.
108
This allows for waiting for processes which have experienced other
109
status changes without having to handle also the exit status from
110
the terminated processes.
111
Another important difference is the additional fifth argument
112
which must be either 
113
.Dv NULL
114
or a pointer to a
115
.Fa siginfo_t
116
structure.
117
Additionally the old
118
.Fq pid_t
119
argument has been split into two separate
120
.Fa idtype_t
121
and
122
.Fa id_t .
123
.br
124
Allowing for the distinction in how the
125
PID or PGID
126
is passed to the routine, calling
127
.Fn wait6
128
with the bits
129
.Dv WEXITED
130
and
131
.Dv WTRAPPED
132
set in the
133
.Fa options
134
and with
135
.Fa infop
136
set to
137
.Dv NULL ,
138
is still functionally equivalent to calling
139
.Fn wait4 .
140
The separation of
141
.Fa idtype
142
and
143
.Fa id
144
arguments has the benefit, though, that many other types of
145
IDs can be supported as well in addition to PID and PGID.
146
.sp
147
Notice that
148
.Fn wait6
149
is not required by any standard nor is it common in other
150
operating system.
151
It is simply a generalized API to support in one function call
152
interface any and all of the functionality available through 
153
any of the other
154
.Fn wait*
155
functions.
156
Do not use it unless you fully accept the implied
157
limitations to the portability of your code.
158
.Pp
92
The
159
The
160
.Fa idtype
161
and
162
.Fa id
163
arguments specify which processes
164
.Fn waitid
165
and
166
.Fn wait6
167
shall wait for.
168
.Bl -tag -width Ds
169
.It Dv +
170
If
171
.Fa idtype
172
is 
173
.Dv P_PID ,
174
.Fn waitid
175
and
176
.Fn wait6
177
wait for the child process with a process ID equal to
178
.Dv (pid_t)id .
179
.It Dv +
180
If
181
.Fa idtype
182
is 
183
.Dv P_PGID ,
184
.Fn waitid
185
and
186
.Fn wait6
187
wait for the child process with a process group ID equal to
188
.Dv (pid_t)id .
189
.It Dv +
190
If
191
.Fa idtype
192
is 
193
.Dv P_ALL ,
194
.Fn waitid
195
and
196
.Fn wait6
197
wait for any child process and the
198
.Dv id
199
is ignored.
200
.It Dv +
201
If
202
.Fa idtype
203
is 
204
.Dv P_PID
205
or
206
.Dv P_PGID
207
and the
208
.Dv id
209
is zero,
210
.Fn waitid
211
and
212
.Fn wait6
213
wait for any child process in the same process group as the caller.
214
.It Dv +
215
While no standard actually requires such functionality,
216
this implementation supports also other types of IDs to wait.
217
.br
218
Notice anyhow that using any of these non-standard features will
219
most likely seriously degrade the portability of your code.
220
Consider such use only as enabling technology for new creative
221
experimentation locked into its original environment.
222
.br
223
Use
224
.Fa idtype
225
value
226
.Dv P_UID
227
to filter processes based on their effective UID,
228
.Dv P_GID
229
to filter processes based on their effective GID.
230
.br
231
.Dv P_SID
232
could be used to filter based on the session ID.
233
In case the child process started its own new session,
234
SID will be the same as its own PID.
235
Otherwise the SID of a child process will match the caller's SID.
236
.br
237
.Dv P_ZONEID
238
facilitates waiting for processes within a certain jail.
239
.br
240
There could be still more meaningful ID types to wait for
241
like
242
.Dv P_PSETID
243
for processes restricted to a certain set of CPUs,
244
.Dv P_CID
245
to wait for processes in a certain scheduling class or
246
.Dv P_CPUID
247
to wait for processes nailed to a certain CPU.
248
These three
249
have not been implemented at the time of this writing,
250
because the data stored in the thread structures seems
251
to be zeroed when a process terminates before the parent
252
gets to wait for the zombie.
253
They are mentioned here as potentially useful extensions.
254
.El
255
.Pp
256
For all the other
257
.Fn wait*
258
variants the
93
.Fa wpid
259
.Fa wpid
94
argument specifies the set of child processes for which to wait.
260
argument specifies the set of child processes for which to wait.
261
.Bl -tag -width Ds
262
.It Dv +
95
If
263
If
96
.Fa wpid
264
.Fa wpid
97
is -1, the call waits for any child process.
265
is -1, the call waits for any child process.
266
.It Dv +
98
If
267
If
99
.Fa wpid
268
.Fa wpid
100
is 0,
269
is 0,
101
the call waits for any child process in the process group of the caller.
270
the call waits for any child process in the process group of the caller.
271
.It Dv +
102
If
272
If
103
.Fa wpid
273
.Fa wpid
104
is greater than zero, the call waits for the process with process id
274
is greater than zero, the call waits for the process with process id
105
.Fa wpid .
275
.Fa wpid .
276
.It Dv +
106
If
277
If
107
.Fa wpid
278
.Fa wpid
108
is less than -1, the call waits for any process whose process group id
279
is less than -1, the call waits for any process whose process group id
109
equals the absolute value of
280
equals the absolute value of
110
.Fa wpid .
281
.Fa wpid .
282
.El
111
.Pp
283
.Pp
112
The
284
The
113
.Fa status
285
.Fa status
Lines 116-156 Link Here
116
The
288
The
117
.Fa options
289
.Fa options
118
argument contains the bitwise OR of any of the following options.
290
argument contains the bitwise OR of any of the following options.
119
The
291
.Bl -tag -width Ds
120
.Dv WCONTINUED
292
.It Dv WCONTINUED
121
option indicates that children of the current process that
293
indicates that children of the current process that
122
have continued from a job control stop, by receiving a
294
have continued from a job control stop, by receiving a
123
.Dv SIGCONT
295
.Dv SIGCONT
124
signal, should also have their status reported.
296
signal, should also have their status reported.
125
The
297
.It Dv WNOHANG
126
.Dv WNOHANG
298
is used to indicate that the call should not block when
127
option
299
there are no processes wishing to report status.
128
is used to indicate that the call should not block if
300
.It Dv WUNTRACED
129
there are no processes that wish to report status.
301
indicates that children of the current process which are stopped
130
If the
131
.Dv WUNTRACED
132
option is set,
133
children of the current process that are stopped
134
due to a
302
due to a
135
.Dv SIGTTIN , SIGTTOU , SIGTSTP ,
303
.Dv SIGTTIN , SIGTTOU , SIGTSTP ,
136
or
304
or
137
.Dv SIGSTOP
305
.Dv SIGSTOP
138
signal also have their status reported.
306
signal shall have their status reported.
139
The
307
.It Dv WSTOPPED
140
.Dv WSTOPPED
308
is an alias for
141
option is an alias for
142
.Dv WUNTRACED .
309
.Dv WUNTRACED .
143
The
310
.It Dv WTRAPPED
144
.Dv WNOWAIT
311
allows waiting for processes which have trapped or reached a breakpoint.
145
option keeps the process whose status is returned in a waitable state.
312
.It Dv WEXITED
313
indicates that the caller is wants to receive status reports from
314
terminated processes.
315
.br
316
This bit is implicitly set for the older functions
317
.Fn wait ,
318
.Fn waitpid ,
319
.Fn wait3 ,
320
and
321
.Fn wait4 
322
to avoid changing their traditional functionality.
323
.br
324
For the more recent new APIs 
325
.Fn waitid
326
and
327
.Fn wait6
328
this bit has to be explicitly included in the 
329
.Fa options ,
330
if status reports from terminated processes are expected.
331
.br
332
This has the benefit that while using the latter two APIs
333
it is possible to request status reports only for processes
334
which have expereinced some other status change, but which
335
have not terminated.
336
So, it is possible to avoid receiving reports for terminated
337
processes, in those parts of a program which are not able
338
to properly handle zombies and delay zombie processing to
339
other parts which can handle them properly.
340
.It Dv WNOWAIT
341
keeps the process whose status is returned in a waitable state.
146
The process may be waited for again after this call completes.
342
The process may be waited for again after this call completes.
343
.El
344
.sp
345
For the more recent APIs 
346
.Fn waitid
347
and
348
.Fn wait6
349
at least one of the options
350
.Dv WEXITED ,
351
.Dv WUNTRACED ,
352
.Dv WSTOPPED ,
353
.Dv WTRAPPED ,
354
or
355
.Dv WCONTINUED
356
must be specified. Otherwise there will be no data for the call to
357
return.
358
To avoid hanging indefinitely in such a case these functions currently
359
behave as if WNOHANG had been specified.
147
.Pp
360
.Pp
148
If
361
If
149
.Fa rusage
362
.Fa rusage
150
is non-zero, a summary of the resources used by the terminated
363
is non-zero, a summary of the resources used by the terminated
151
process and all its
364
process and all its
152
children is returned (this information is currently not available
365
children is returned.
153
for stopped or continued processes).
366
.Pp
367
If
368
.Fa infop
369
is non-null, it must point to a 
370
.Dv siginfo_t
371
structure which will be filled such that the
372
.Dv si_signo
373
field will always be
374
.Dv SIGCHLD
375
and the field
376
.Dv si_pid
377
will be non-zero, if there is a status change to report.
378
If there are no status changes to report and WNOHANG is applied,
379
both of these fields will be zero.
380
.br
381
When using the
382
.Fn waitid
383
API with the
384
.Dv WNOHANG
385
option set checking these fields is the only way to know whether
386
there were any status changes to report, because the return value
387
from
388
.Fn waitid
389
will be zero as it is for any successful return from
390
.Fn waitid .
154
.Pp
391
.Pp
155
When the
392
When the
156
.Dv WNOHANG
393
.Dv WNOHANG
Lines 306-311 Link Here
306
is returned and
543
is returned and
307
.Va errno
544
.Va errno
308
is set to indicate the error.
545
is set to indicate the error.
546
.Pp
547
If
548
.Fn waitid
549
returns because one or more processes have a state change to report,
550
0 is returned.
551
To indicate an error, -1 will be returned and
552
.Dv errno
553
set to an appropriate value.
554
If
555
.Dv WNOHANG
556
was used, 0 can be returned indicating no error, but no processes
557
may have changed state either, if si_signo and/or si_pid are zero.
309
.Sh ERRORS
558
.Sh ERRORS
310
The
559
The
311
.Fn wait
560
.Fn wait
Lines 335-340 Link Here
335
or the signal did not have the
584
or the signal did not have the
336
.Dv SA_RESTART
585
.Dv SA_RESTART
337
flag set.
586
flag set.
587
.It Bq Er EINVAL
588
An invalid value as specified for
589
.Fa options ,
590
or
591
.Fa idtype
592
and
593
.Fa id
594
do not specify a valid set of processes.
338
.El
595
.El
339
.Sh SEE ALSO
596
.Sh SEE ALSO
340
.Xr _exit 2 ,
597
.Xr _exit 2 ,
(-)sys/kern/kern_exit.c (-30 / +346 lines)
Lines 674-679 Link Here
674
	int error, status;
674
	int error, status;
675
675
676
	error = kern_wait(td, WAIT_ANY, &status, 0, NULL);
676
	error = kern_wait(td, WAIT_ANY, &status, 0, NULL);
677
677
	if (error == 0)
678
	if (error == 0)
678
		td->td_retval[1] = status;
679
		td->td_retval[1] = status;
679
	return (error);
680
	return (error);
Lines 684-690 Link Here
684
 * The dirty work is handled by kern_wait().
685
 * The dirty work is handled by kern_wait().
685
 */
686
 */
686
int
687
int
687
sys_wait4(struct thread *td, struct wait_args *uap)
688
sys_wait4(struct thread *td, struct wait4_args *uap)
688
{
689
{
689
	struct rusage ru, *rup;
690
	struct rusage ru, *rup;
690
	int error, status;
691
	int error, status;
Lines 693-703 Link Here
693
		rup = &ru;
694
		rup = &ru;
694
	else
695
	else
695
		rup = NULL;
696
		rup = NULL;
697
696
	error = kern_wait(td, uap->pid, &status, uap->options, rup);
698
	error = kern_wait(td, uap->pid, &status, uap->options, rup);
699
700
	if (uap->status != NULL && error == 0)
701
		error = copyout(&status, uap->status, sizeof(status));
702
	if (uap->rusage != NULL && error == 0)
703
		error = copyout(&ru, uap->rusage, sizeof(struct rusage));
704
	return (error);
705
}
706
707
int
708
sys_wait6(struct thread *td, struct wait6_args *uap)
709
{
710
	struct rusage ru, *rup;
711
	siginfo_t  si, *sip;
712
	int error, status;
713
	pid_t	pid;
714
	idtype_t idtype;
715
	id_t	id;
716
717
	pid = uap->pid;
718
719
	if (pid == WAIT_ANY) {
720
		idtype = P_ALL;
721
		id = 0;
722
	}
723
	else if (pid <= 0) {
724
		idtype = P_PGID;
725
		id = (id_t) -pid;
726
	}
727
	else {
728
		idtype = P_PID;
729
		id = (id_t) pid;
730
	}
731
732
	if (uap->rusage != NULL)
733
		rup = &ru;
734
	else
735
		rup = NULL;
736
737
	if (uap->info != NULL)
738
		sip = &si;
739
	else
740
		sip = NULL;
741
742
	/*
743
	 *  We expect all callers of wait6()
744
	 *  to know about WEXITED & WTRAPPED!
745
	 */
746
	error = kern_wait6(td, idtype, id, &status, uap->options, rup, sip);
747
697
	if (uap->status != NULL && error == 0)
748
	if (uap->status != NULL && error == 0)
698
		error = copyout(&status, uap->status, sizeof(status));
749
		error = copyout(&status, uap->status, sizeof(status));
699
	if (uap->rusage != NULL && error == 0)
750
	if (uap->rusage != NULL && error == 0)
700
		error = copyout(&ru, uap->rusage, sizeof(struct rusage));
751
		error = copyout(&ru, uap->rusage, sizeof(struct rusage));
752
	if (uap->info != NULL && error == 0)
753
		error = copyout(&si, uap->info, sizeof(siginfo_t));
701
	return (error);
754
	return (error);
702
}
755
}
703
756
Lines 707-714 Link Here
707
 * lock as part of its work.
760
 * lock as part of its work.
708
 */
761
 */
709
void
762
void
710
proc_reap(struct thread *td, struct proc *p, int *status, int options,
763
proc_reap(struct thread *td, struct proc *p, int *status, int options)
711
    struct rusage *rusage)
712
{
764
{
713
	struct proc *q, *t;
765
	struct proc *q, *t;
714
766
Lines 718-727 Link Here
718
	KASSERT(p->p_state == PRS_ZOMBIE, ("proc_reap: !PRS_ZOMBIE"));
770
	KASSERT(p->p_state == PRS_ZOMBIE, ("proc_reap: !PRS_ZOMBIE"));
719
771
720
	q = td->td_proc;
772
	q = td->td_proc;
721
	if (rusage) {
773
722
		*rusage = p->p_ru;
723
		calcru(p, &rusage->ru_utime, &rusage->ru_stime);
724
	}
725
	PROC_SUNLOCK(p);
774
	PROC_SUNLOCK(p);
726
	td->td_retval[0] = p->p_pid;
775
	td->td_retval[0] = p->p_pid;
727
	if (status)
776
	if (status)
Lines 834-841 Link Here
834
}
883
}
835
884
836
static int
885
static int
837
proc_to_reap(struct thread *td, struct proc *p, pid_t pid, int *status,
886
proc_to_reap(struct thread *td, struct proc *p,
838
    int options, struct rusage *rusage)
887
	     idtype_t idtype, id_t id, 
888
	     int *status, int options,
889
	     struct rusage *rusage, siginfo_t *siginfo)
839
{
890
{
840
	struct proc *q;
891
	struct proc *q;
841
892
Lines 843-857 Link Here
843
894
844
	q = td->td_proc;
895
	q = td->td_proc;
845
	PROC_LOCK(p);
896
	PROC_LOCK(p);
846
	if (pid != WAIT_ANY && p->p_pid != pid && p->p_pgid != -pid) {
897
898
	switch (idtype) {
899
	case	P_ALL:
900
		break;
901
902
	case	P_PID:
903
		if (p->p_pid != (pid_t) id) {
904
			PROC_UNLOCK(p);
905
			return (0);
906
		}
907
		break;
908
909
	case	P_PGID:
910
		if (p->p_pgid != (pid_t) id) {
911
			PROC_UNLOCK(p);
912
			return (0);
913
		}
914
		break;
915
916
	case	P_SID:
917
		if (p->p_session->s_sid != (pid_t) id) {
918
			PROC_UNLOCK(p);
919
			return (0);
920
		}
921
		break;
922
923
	case	P_UID:
924
		if (p->p_ucred->cr_uid != (uid_t) id) {
925
			PROC_UNLOCK(p);
926
			return (0);
927
		}
928
		break;
929
930
	case	P_GID:
931
		if (p->p_ucred->cr_gid != (gid_t) id) {
932
			PROC_UNLOCK(p);
933
			return (0);
934
		}
935
		break;
936
937
	case	P_ZONEID:	/* jail */
938
		if (! p->p_ucred->cr_prison ||
939
		    (p->p_ucred->cr_prison->pr_id != (int) id)) {
940
			PROC_UNLOCK(p);
941
			return (0);
942
		}
943
		break;
944
945
#if 0
946
		/*
947
		 * It seems that the first thread structure gets zeroed out
948
		 * at process exit.
949
		 * This makes toast of all useful info related to CPU set and
950
		 * scheduling priority class.
951
		 */
952
953
	case	P_PSETID:
954
		{
955
			struct thread	*td1;
956
957
			td1 = FIRST_THREAD_IN_PROC(p);
958
			if (td1->td_cpuset->cs_id != (cpusetid_t) id) {
959
				PROC_UNLOCK(p);
960
				return (0);
961
			}
962
		}
963
		break;
964
965
	case	P_CID:
966
		{
967
			struct thread	*td1;
968
969
			td1 = FIRST_THREAD_IN_PROC(p);
970
			if (td1->td_pri_class != (unsigned) id) {
971
				PROC_UNLOCK(p);
972
				return (0);
973
			}
974
		}
975
		break;
976
977
978
		/*
979
		 * Is there a good place for this?
980
		 * Supposedly also zeroed before it can be used, right?
981
		 */
982
983
	case	P_CPUID:
984
		{
985
			struct thread	*td1;
986
987
			td1 = FIRST_THREAD_IN_PROC(p);
988
			if (td1->td_lastcpu != (unsigned) id) {
989
				PROC_UNLOCK(p);
990
				return (0);
991
			}
992
		}
993
		break;
994
#endif
995
996
	default:
847
		PROC_UNLOCK(p);
997
		PROC_UNLOCK(p);
848
		return (0);
998
		return (0);
999
		break;
849
	}
1000
	}
1001
850
	if (p_canwait(td, p)) {
1002
	if (p_canwait(td, p)) {
851
		PROC_UNLOCK(p);
1003
		PROC_UNLOCK(p);
852
		return (0);
1004
		return (0);
853
	}
1005
	}
854
1006
1007
	if (((options & WEXITED) == 0) && (p->p_state == PRS_ZOMBIE)) {
1008
		PROC_UNLOCK(p);
1009
		return (0);
1010
	}
1011
		
855
	/*
1012
	/*
856
	 * This special case handles a kthread spawned by linux_clone
1013
	 * This special case handles a kthread spawned by linux_clone
857
	 * (see linux_misc.c).  The linux_wait4 and linux_waitpid
1014
	 * (see linux_misc.c).  The linux_wait4 and linux_waitpid
Lines 867-874 Link Here
867
	}
1024
	}
868
1025
869
	PROC_SLOCK(p);
1026
	PROC_SLOCK(p);
1027
1028
	/* New siginfo stuff... */
1029
1030
	if (siginfo) {
1031
		bzero (siginfo, sizeof (*siginfo));
1032
		siginfo->si_signo = SIGCHLD;
1033
		siginfo->si_errno = 0;
1034
1035
		/*
1036
		 *  Right, this is still a rough estimate.
1037
		 *  We will fix the cases TRAPPED, STOPPED,
1038
		 *  and CONTINUED later.
1039
		 */
1040
1041
		if (WCOREDUMP(p->p_xstat))
1042
			siginfo->si_code = CLD_DUMPED;
1043
		else if (WIFSIGNALED(p->p_xstat))
1044
			siginfo->si_code = CLD_KILLED;
1045
		else
1046
			siginfo->si_code = CLD_EXITED;
1047
1048
		siginfo->si_pid = p->p_pid;
1049
		siginfo->si_uid = p->p_ucred->cr_uid;
1050
		siginfo->si_status = p->p_xstat;
1051
1052
		/*
1053
		 *  The si_addr field would be useful
1054
		 *  additional detail, but apparently
1055
		 *  the PC value may be lost when we
1056
		 *  reach this point.
1057
		 */
1058
		siginfo->si_addr = NULL;	/* XXX */
1059
	}
1060
1061
	/*
1062
	 * There should be no reason to limit resources usage info
1063
	 * to exited processes only.
1064
	 * A snapshot about any resources used by a stopped process
1065
	 * may be exactly what is needed.
1066
	 * (1) Solaris limits available info to times only.
1067
	 * (2) Linux does not declare any limitations.
1068
	 * (3) Now we within the same PROC_SLOCK anyway.
1069
	 */
1070
1071
	if (rusage) {
1072
		*rusage = p->p_ru;
1073
		calcru(p, &rusage->ru_utime, &rusage->ru_stime);
1074
	}
1075
870
	if (p->p_state == PRS_ZOMBIE) {
1076
	if (p->p_state == PRS_ZOMBIE) {
871
		proc_reap(td, p, status, options, rusage);
1077
		proc_reap(td, p, status, options);
872
		return (-1);
1078
		return (-1);
873
	}
1079
	}
874
	PROC_SUNLOCK(p);
1080
	PROC_SUNLOCK(p);
Lines 877-900 Link Here
877
}
1083
}
878
1084
879
int
1085
int
880
kern_wait(struct thread *td, pid_t pid, int *status, int options,
1086
kern_wait(struct thread *td, pid_t pid,
881
    struct rusage *rusage)
1087
	  int *status, int options, struct rusage *rusage)
1088
{
1089
	idtype_t idtype;
1090
	id_t id;
1091
1092
	if (pid == WAIT_ANY) {
1093
		idtype = P_ALL;
1094
		id = 0;
1095
	}
1096
	else if (pid <= 0) {
1097
		idtype = P_PGID;
1098
		id = (id_t) -pid;
1099
	}
1100
	else {
1101
		idtype = P_PID;
1102
		id = (id_t) pid;
1103
	}
1104
1105
	/*
1106
	 *  For backward compatibility we implicitly add
1107
	 *  flags WEXITED & WTRAPPED here.
1108
	 */
1109
1110
	options |= (WEXITED | WTRAPPED);
1111
1112
	return (kern_wait6 (td, idtype, id, status, options, rusage, NULL));
1113
}
1114
1115
int
1116
kern_wait6(struct thread *td, idtype_t idtype, id_t id,
1117
	   int *status, int options,
1118
	   struct rusage *rusage, siginfo_t *siginfo)
882
{
1119
{
883
	struct proc *p, *q;
1120
	struct proc *p, *q;
884
	int error, nfound, ret;
1121
	int error, nfound, ret;
885
1122
886
	AUDIT_ARG_PID(pid);
1123
#if 0
1124
	AUDIT_ARG_VALUE((int) idtype);	/* XXX - This is likely wrong! */
1125
#endif
1126
	AUDIT_ARG_PID((pid_t) id);	/* XXX - This may be wrong! */
887
	AUDIT_ARG_VALUE(options);
1127
	AUDIT_ARG_VALUE(options);
888
1128
889
	q = td->td_proc;
1129
	q = td->td_proc;
890
	if (pid == 0) {
1130
1131
	if (((pid_t) id == WAIT_MYPGRP) &&
1132
	    ((idtype == P_PID) || (idtype == P_PGID))) {
891
		PROC_LOCK(q);
1133
		PROC_LOCK(q);
892
		pid = -q->p_pgid;
1134
		id = (id_t) q->p_pgid;
893
		PROC_UNLOCK(q);
1135
		PROC_UNLOCK(q);
1136
		idtype = P_PGID;
894
	}
1137
	}
1138
895
	/* If we don't know the option, just return. */
1139
	/* If we don't know the option, just return. */
896
	if (options & ~(WUNTRACED|WNOHANG|WCONTINUED|WNOWAIT|WLINUXCLONE))
1140
	if (options & ~(WUNTRACED|WNOHANG|WCONTINUED|WNOWAIT|WEXITED|WTRAPPED|WLINUXCLONE))
897
		return (EINVAL);
1141
		return (EINVAL);
1142
1143
	if ((options & (WEXITED|WUNTRACED|WCONTINUED|WTRAPPED)) == 0) {
1144
		/*
1145
		 * We will be unable to find any matching processes.
1146
		 * Simply behave as WHOHANG were specified, because
1147
		 * waiting for real will not help.
1148
		 */
1149
		if (siginfo)
1150
			bzero (siginfo, sizeof (*siginfo));
1151
		td->td_retval[0] = 0;
1152
		return (0);
1153
	}
1154
898
loop:
1155
loop:
899
	if (q->p_flag & P_STATCHILD) {
1156
	if (q->p_flag & P_STATCHILD) {
900
		PROC_LOCK(q);
1157
		PROC_LOCK(q);
Lines 904-910 Link Here
904
	nfound = 0;
1161
	nfound = 0;
905
	sx_xlock(&proctree_lock);
1162
	sx_xlock(&proctree_lock);
906
	LIST_FOREACH(p, &q->p_children, p_sibling) {
1163
	LIST_FOREACH(p, &q->p_children, p_sibling) {
907
		ret = proc_to_reap(td, p, pid, status, options, rusage);
1164
		ret = proc_to_reap(td, p, idtype, id,
1165
				   status, options, rusage, siginfo);
908
		if (ret == 0)
1166
		if (ret == 0)
909
			continue;
1167
			continue;
910
		else if (ret == 1)
1168
		else if (ret == 1)
Lines 914-933 Link Here
914
1172
915
		PROC_LOCK(p);
1173
		PROC_LOCK(p);
916
		PROC_SLOCK(p);
1174
		PROC_SLOCK(p);
917
		if ((p->p_flag & P_STOPPED_SIG) &&
1175
1176
		if ((options & WTRAPPED) &&
1177
		    (p->p_flag & P_TRACED) &&
1178
		    (p->p_flag & (P_STOPPED_TRACE | P_STOPPED_SIG)) &&
918
		    (p->p_suspcount == p->p_numthreads) &&
1179
		    (p->p_suspcount == p->p_numthreads) &&
919
		    (p->p_flag & P_WAITED) == 0 &&
1180
		    ((p->p_flag & P_WAITED) == 0)) {
920
		    (p->p_flag & P_TRACED || options & WUNTRACED)) {
921
			PROC_SUNLOCK(p);
1181
			PROC_SUNLOCK(p);
922
			p->p_flag |= P_WAITED;
1182
1183
			if ((options & WNOWAIT) == 0)
1184
				p->p_flag |= P_WAITED;
1185
923
			sx_xunlock(&proctree_lock);
1186
			sx_xunlock(&proctree_lock);
924
			td->td_retval[0] = p->p_pid;
1187
			td->td_retval[0] = p->p_pid;
1188
925
			if (status)
1189
			if (status)
926
				*status = W_STOPCODE(p->p_xstat);
1190
				*status = W_STOPCODE(p->p_xstat);
927
1191
928
			PROC_LOCK(q);
1192
			if (siginfo) {
929
			sigqueue_take(p->p_ksi);
1193
				siginfo->si_status = W_STOPCODE(p->p_xstat);
930
			PROC_UNLOCK(q);
1194
				siginfo->si_code = CLD_TRAPPED;
1195
			}
1196
1197
			if ((options & WNOWAIT) == 0) {
1198
				PROC_LOCK(q);
1199
				sigqueue_take(p->p_ksi);
1200
				PROC_UNLOCK(q);
1201
			}
1202
1203
			PROC_UNLOCK(p);
1204
1205
			return (0);
1206
		}
1207
1208
		if ((options & WUNTRACED) &&
1209
		    (p->p_flag & P_STOPPED_SIG) &&
1210
		    (p->p_suspcount == p->p_numthreads) &&
1211
		    ((p->p_flag & P_WAITED) == 0)) {
1212
			PROC_SUNLOCK(p);
1213
1214
			if ((options & WNOWAIT) == 0)
1215
				p->p_flag |= P_WAITED;
1216
1217
			sx_xunlock(&proctree_lock);
1218
			td->td_retval[0] = p->p_pid;
1219
1220
			if (status)
1221
				*status = W_STOPCODE(p->p_xstat);
1222
1223
			if (siginfo) {
1224
				siginfo->si_status = W_STOPCODE(p->p_xstat);
1225
				siginfo->si_code = CLD_STOPPED;
1226
			}
1227
1228
			if ((options & WNOWAIT) == 0) {
1229
				PROC_LOCK(q);
1230
				sigqueue_take(p->p_ksi);
1231
				PROC_UNLOCK(q);
1232
			}
1233
931
			PROC_UNLOCK(p);
1234
			PROC_UNLOCK(p);
932
1235
933
			return (0);
1236
			return (0);
Lines 936-950 Link Here
936
		if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) {
1239
		if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) {
937
			sx_xunlock(&proctree_lock);
1240
			sx_xunlock(&proctree_lock);
938
			td->td_retval[0] = p->p_pid;
1241
			td->td_retval[0] = p->p_pid;
939
			p->p_flag &= ~P_CONTINUED;
940
1242
941
			PROC_LOCK(q);
1243
			if ((options & WNOWAIT) == 0) {
942
			sigqueue_take(p->p_ksi);
1244
				p->p_flag &= ~P_CONTINUED;
943
			PROC_UNLOCK(q);
1245
1246
				PROC_LOCK(q);
1247
				sigqueue_take(p->p_ksi);
1248
				PROC_UNLOCK(q);
1249
			}
1250
944
			PROC_UNLOCK(p);
1251
			PROC_UNLOCK(p);
945
1252
946
			if (status)
1253
			if (status)
947
				*status = SIGCONT;
1254
				*status = SIGCONT;
1255
1256
			if (siginfo) {
1257
				siginfo->si_status = SIGCONT;
1258
				siginfo->si_code = CLD_CONTINUED;
1259
			}
1260
948
			return (0);
1261
			return (0);
949
		}
1262
		}
950
		PROC_UNLOCK(p);
1263
		PROC_UNLOCK(p);
Lines 963-969 Link Here
963
	 * to successfully wait until the child becomes a zombie.
1276
	 * to successfully wait until the child becomes a zombie.
964
	 */
1277
	 */
965
	LIST_FOREACH(p, &q->p_orphans, p_orphan) {
1278
	LIST_FOREACH(p, &q->p_orphans, p_orphan) {
966
		ret = proc_to_reap(td, p, pid, status, options, rusage);
1279
		ret = proc_to_reap(td, p, idtype, id,
1280
				   status, options, rusage, siginfo);
967
		if (ret == 0)
1281
		if (ret == 0)
968
			continue;
1282
			continue;
969
		else if (ret == 1)
1283
		else if (ret == 1)
Lines 977-982 Link Here
977
	}
1291
	}
978
	if (options & WNOHANG) {
1292
	if (options & WNOHANG) {
979
		sx_xunlock(&proctree_lock);
1293
		sx_xunlock(&proctree_lock);
1294
		if (siginfo)
1295
			bzero (siginfo, sizeof (*siginfo));
980
		td->td_retval[0] = 0;
1296
		td->td_retval[0] = 0;
981
		return (0);
1297
		return (0);
982
	}
1298
	}
(-)lib/libc/sys/Makefile.inc (-1 / +1 lines)
Lines 210-214 Link Here
210
MLINKS+=truncate.2 ftruncate.2
210
MLINKS+=truncate.2 ftruncate.2
211
MLINKS+=unlink.2 unlinkat.2
211
MLINKS+=unlink.2 unlinkat.2
212
MLINKS+=utimes.2 futimes.2 utimes.2 futimesat.2 utimes.2 lutimes.2
212
MLINKS+=utimes.2 futimes.2 utimes.2 futimesat.2 utimes.2 lutimes.2
213
MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2
213
MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2 wait.2 waitid.2 wait.2 wait6.2
214
MLINKS+=write.2 pwrite.2 write.2 pwritev.2 write.2 writev.2
214
MLINKS+=write.2 pwrite.2 write.2 pwritev.2 write.2 writev.2

Return to bug 170346