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

Collapse All | Expand All

(-)sys/sys/wait.h (+10 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 87-92 Link Here
87
89
88
/*
90
/*
89
 * Tokens for special values of the "pid" parameter to wait4.
91
 * Tokens for special values of the "pid" parameter to wait4.
92
 * Extended struct wrusage to collect rusage for both the target
93
 * process and its children within one wait6() call.
90
 */
94
 */
91
#if __BSD_VISIBLE
95
#if __BSD_VISIBLE
92
#define	WAIT_ANY	(-1)	/* any process */
96
#define	WAIT_ANY	(-1)	/* any process */
Lines 97-108 Link Here
97
#include <sys/types.h>
101
#include <sys/types.h>
98
102
99
__BEGIN_DECLS
103
__BEGIN_DECLS
104
struct __siginfo;
100
pid_t	wait(int *);
105
pid_t	wait(int *);
101
pid_t	waitpid(pid_t, int *, int);
106
pid_t	waitpid(pid_t, int *, int);
107
#if __POSIX_VISIBLE >= 200112
108
int	waitid(idtype_t, id_t, struct __siginfo *, int);
109
#endif
102
#if __BSD_VISIBLE
110
#if __BSD_VISIBLE
103
struct rusage;
111
struct rusage;
112
struct wrusage;
104
pid_t	wait3(int *, int, struct rusage *);
113
pid_t	wait3(int *, int, struct rusage *);
105
pid_t	wait4(pid_t, int *, int, struct rusage *);
114
pid_t	wait4(pid_t, int *, int, struct rusage *);
115
pid_t	wait6(idtype_t, id_t, int *, int, struct wrusage *, struct __siginfo *);
106
#endif
116
#endif
107
__END_DECLS
117
__END_DECLS
108
#endif /* !_KERNEL */
118
#endif /* !_KERNEL */
(-)sys/sys/syscallsubr.h (+3 lines)
Lines 43-48 Link Here
43
struct msqid_ds;
43
struct msqid_ds;
44
struct rlimit;
44
struct rlimit;
45
struct rusage;
45
struct rusage;
46
struct wrusage;
46
union semun;
47
union semun;
47
struct sockaddr;
48
struct sockaddr;
48
struct stat;
49
struct stat;
Lines 233-238 Link Here
233
	    enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg);
234
	    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,
235
int	kern_wait(struct thread *td, pid_t pid, int *status, int options,
235
	    struct rusage *rup);
236
	    struct rusage *rup);
237
int	kern_wait6(struct thread *td, idtype_t idtype, id_t id, int *status,
238
		   int options, struct wrusage *wrup, siginfo_t *sip);
236
int	kern_writev(struct thread *td, int fd, struct uio *auio);
239
int	kern_writev(struct thread *td, int fd, struct uio *auio);
237
int	kern_socketpair(struct thread *td, int domain, int type, int protocol,
240
int	kern_socketpair(struct thread *td, int domain, int type, int protocol,
238
	    int *rsv);
241
	    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
(-)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 (+4 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 81-86 Link Here
81
	P_PSETID	/* Processor set identifier		*/
82
	P_PSETID	/* Processor set identifier		*/
82
} idtype_t;
83
} idtype_t;
83
84
85
#define	_IDTYPE_T_DECLARED
86
87
#endif
84
88
85
/*
89
/*
86
 *	The following defines the operations which can be performed to
90
 *	The following defines the operations which can be performed to
(-)sys/sys/proc.h (-2 / +1 lines)
Lines 884-891 Link Here
884
void	procinit(void);
884
void	procinit(void);
885
void	proc_linkup0(struct proc *p, struct thread *td);
885
void	proc_linkup0(struct proc *p, struct thread *td);
886
void	proc_linkup(struct proc *p, struct thread *td);
886
void	proc_linkup(struct proc *p, struct thread *td);
887
void	proc_reap(struct thread *td, struct proc *p, int *status, int options,
887
void	proc_reap(struct thread *td, struct proc *p, int *status, int options);
888
	    struct rusage *rusage);
889
void	proc_reparent(struct proc *child, struct proc *newparent);
888
void	proc_reparent(struct proc *child, struct proc *newparent);
890
struct	pstats *pstats_alloc(void);
889
struct	pstats *pstats_alloc(void);
891
void	pstats_fork(struct pstats *src, struct pstats *dst);
890
void	pstats_fork(struct pstats *src, struct pstats *dst);
(-)lib/libc/gen/Symbol.map (+2 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;
388
	wait6;
387
};
389
};
388
390
389
FBSDprivate_1.0 {
391
FBSDprivate_1.0 {
(-)sys/sys/types.h (+38 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(__BSD_VISIBLE)
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
} idtype_t;		/* The type of id_t we are using.	*/
178
179
#define	_IDTYPE_T_DECLARED
180
#endif
181
182
145
#ifndef _INO_T_DECLARED
183
#ifndef _INO_T_DECLARED
146
typedef	__ino_t		ino_t;		/* inode number */
184
typedef	__ino_t		ino_t;		/* inode number */
147
#define	_INO_T_DECLARED
185
#define	_INO_T_DECLARED
(-)lib/libc/sys/wait.2 (-26 / +304 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 wrusage *wrusage" "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
.br
112
The traditional argument 
113
.Dv rusage
114
has been replaced with a pointer to a new structure
115
.Bd -literal
116
struct wrusage {
117
        struct rusage   wru_self;
118
	struct rusage   wru_children;
119
};
120
.Ed
121
.sp
122
This allows the calling process to collect resource usage statistics
123
from both its own child process as well as from its grand children.
124
When no resource usage statistics are needed this pointer can be
125
.Dv NULL .
126
.br
127
Another important difference is the new last argument
128
which must be either 
129
.Dv NULL
130
or a pointer to a
131
.Fa siginfo_t
132
structure.
133
.br
134
Additionally the old
135
.Fa pid_t
136
argument has been split into two separate arguments
137
.Fa idtype_t
138
and
139
.Fa id_t .
140
.br
141
Allowing for the distinction in how the
142
PID or PGID
143
is passed to the routine, calling
144
.Fn wait6
145
with the bits
146
.Dv WEXITED
147
and
148
.Dv WTRAPPED
149
set in the
150
.Fa options
151
and with
152
.Fa infop
153
set to
154
.Dv NULL ,
155
is still functionally quite analogous to calling
156
.Fn wait4 .
157
The separation of
158
.Fa idtype
159
and
160
.Fa id
161
arguments has the benefit, though, that many other types of
162
IDs can be supported as well in addition to PID and PGID.
163
.sp
164
Notice that
165
.Fn wait6
166
is not required by any standard nor is it common in other
167
operating systems.
168
It is simply a generalized API to support in one function call
169
interface any and all of the functionality available through 
170
any of the other
171
.Fn wait*
172
functions and a superset of them all.
173
Do not use it unless you fully accept the implied
174
limitations to the portability of your code.
175
.Pp
92
The
176
The
177
.Fa idtype
178
and
179
.Fa id
180
arguments specify which processes
181
.Fn waitid
182
and
183
.Fn wait6
184
shall wait for.
185
.Bl -bullet -offset indent
186
.It
187
If
188
.Fa idtype
189
is 
190
.Dv P_PID ,
191
.Fn waitid
192
and
193
.Fn wait6
194
wait for the child process with a process ID equal to
195
.Dv (pid_t)id .
196
.It
197
If
198
.Fa idtype
199
is 
200
.Dv P_PGID ,
201
.Fn waitid
202
and
203
.Fn wait6
204
wait for the child process with a process group ID equal to
205
.Dv (pid_t)id .
206
.It
207
If
208
.Fa idtype
209
is 
210
.Dv P_ALL ,
211
.Fn waitid
212
and
213
.Fn wait6
214
wait for any child process and the
215
.Dv id
216
is ignored.
217
.It
218
If
219
.Fa idtype
220
is 
221
.Dv P_PID
222
or
223
.Dv P_PGID
224
and the
225
.Dv id
226
is zero,
227
.Fn waitid
228
and
229
.Fn wait6
230
wait for any child process in the same process group as the caller.
231
.It
232
While no standard actually requires such functionality,
233
this implementation supports also other types of IDs to wait.
234
.br
235
Notice anyhow that using any of these non-standard features will
236
most likely seriously degrade the portability of your code.
237
Consider such use only as enabling technology for new creative
238
experimentation locked into its original environment.
239
.br
240
Use
241
.Fa idtype
242
value
243
.Dv P_UID
244
to filter processes based on their effective UID,
245
.Dv P_GID
246
to filter processes based on their effective GID.
247
.br
248
.Dv P_SID
249
could be used to filter based on the session ID.
250
In case the child process started its own new session,
251
SID will be the same as its own PID.
252
Otherwise the SID of a child process will match the caller's SID.
253
.br
254
.Dv P_ZONEID
255
facilitates waiting for processes within a certain jail.
256
.br
257
There could be still more meaningful ID types to wait for
258
like
259
.Dv P_PSETID
260
for processes restricted to a certain set of CPUs,
261
.Dv P_CID
262
to wait for processes in a certain scheduling class or
263
.Dv P_CPUID
264
to wait for processes nailed to a certain CPU.
265
These three
266
have not been implemented at the time of this writing,
267
because the data stored in the thread structures seems
268
to be zeroed when a process terminates before the parent
269
gets to wait for the zombie.
270
They are mentioned here as potentially useful extensions.
271
.El
272
.Pp
273
For all the other
274
.Fn wait*
275
variants the
93
.Fa wpid
276
.Fa wpid
94
argument specifies the set of child processes for which to wait.
277
argument specifies the set of child processes for which to wait.
278
.Bl -bullet -offset indent
279
.It
95
If
280
If
96
.Fa wpid
281
.Fa wpid
97
is -1, the call waits for any child process.
282
is -1, the call waits for any child process.
283
.It
98
If
284
If
99
.Fa wpid
285
.Fa wpid
100
is 0,
286
is 0,
101
the call waits for any child process in the process group of the caller.
287
the call waits for any child process in the process group of the caller.
288
.It
102
If
289
If
103
.Fa wpid
290
.Fa wpid
104
is greater than zero, the call waits for the process with process id
291
is greater than zero, the call waits for the process with process id
105
.Fa wpid .
292
.Fa wpid .
293
.It
106
If
294
If
107
.Fa wpid
295
.Fa wpid
108
is less than -1, the call waits for any process whose process group id
296
is less than -1, the call waits for any process whose process group id
109
equals the absolute value of
297
equals the absolute value of
110
.Fa wpid .
298
.Fa wpid .
299
.El
111
.Pp
300
.Pp
112
The
301
The
113
.Fa status
302
.Fa status
Lines 116-156 Link Here
116
The
305
The
117
.Fa options
306
.Fa options
118
argument contains the bitwise OR of any of the following options.
307
argument contains the bitwise OR of any of the following options.
119
The
308
.Bl -tag -width Ds
120
.Dv WCONTINUED
309
.It Dv WCONTINUED
121
option indicates that children of the current process that
310
indicates that children of the current process that
122
have continued from a job control stop, by receiving a
311
have continued from a job control stop, by receiving a
123
.Dv SIGCONT
312
.Dv SIGCONT
124
signal, should also have their status reported.
313
signal, should also have their status reported.
125
The
314
.It Dv WNOHANG
126
.Dv WNOHANG
315
is used to indicate that the call should not block when
127
option
316
there are no processes wishing to report status.
128
is used to indicate that the call should not block if
317
.It Dv WUNTRACED
129
there are no processes that wish to report status.
318
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
319
due to a
135
.Dv SIGTTIN , SIGTTOU , SIGTSTP ,
320
.Dv SIGTTIN , SIGTTOU , SIGTSTP ,
136
or
321
or
137
.Dv SIGSTOP
322
.Dv SIGSTOP
138
signal also have their status reported.
323
signal shall have their status reported.
139
The
324
.It Dv WSTOPPED
140
.Dv WSTOPPED
325
is an alias for
141
option is an alias for
142
.Dv WUNTRACED .
326
.Dv WUNTRACED .
143
The
327
.It Dv WTRAPPED
144
.Dv WNOWAIT
328
allows waiting for processes which have trapped or reached a breakpoint.
145
option keeps the process whose status is returned in a waitable state.
329
.It Dv WEXITED
330
indicates that the caller is wants to receive status reports from
331
terminated processes.
332
.br
333
This bit is implicitly set for the older functions
334
.Fn wait ,
335
.Fn waitpid ,
336
.Fn wait3 ,
337
and
338
.Fn wait4 
339
to avoid changing their traditional functionality.
340
.br
341
For the more recent APIs 
342
.Fn waitid
343
and
344
.Fn wait6
345
this bit has to be explicitly included in the 
346
.Fa options ,
347
if status reports from terminated processes are expected.
348
.br
349
This has the benefit that while using the latter two APIs
350
it is possible to request status reports only for processes
351
which have experienced some other status change, but which
352
have not terminated.
353
So, it is possible to avoid receiving reports for terminated
354
processes, in those parts of a program which are not able
355
to properly handle zombies and delay zombie processing to
356
other parts which can handle them properly.
357
.It Dv WNOWAIT
358
keeps the process whose status is returned in a waitable state.
146
The process may be waited for again after this call completes.
359
The process may be waited for again after this call completes.
360
.El
361
.sp
362
For the more recent APIs 
363
.Fn waitid
364
and
365
.Fn wait6
366
at least one of the options
367
.Dv WEXITED ,
368
.Dv WUNTRACED ,
369
.Dv WSTOPPED ,
370
.Dv WTRAPPED ,
371
or
372
.Dv WCONTINUED
373
must be specified.
374
Otherwise there will be no events for the call to report.
375
To avoid hanging indefinitely in such a case these functions currently
376
return -1 with errno set to
377
.Dv EINVAL .
147
.Pp
378
.Pp
148
If
379
If
149
.Fa rusage
380
.Fa rusage
150
is non-zero, a summary of the resources used by the terminated
381
is non-zero, a summary of the resources used by the terminated
151
process and all its
382
process and all its
152
children is returned (this information is currently not available
383
children is returned.
153
for stopped or continued processes).
384
.Pp
385
If
386
.Fa infop
387
is non-null, it must point to a 
388
.Dv siginfo_t
389
structure which will be filled such that the
390
.Dv si_signo
391
field will always be
392
.Dv SIGCHLD
393
and the field
394
.Dv si_pid
395
will be non-zero, if there is a status change to report.
396
If there are no status changes to report and WNOHANG is applied,
397
both of these fields will be zero.
398
.br
399
When using the
400
.Fn waitid
401
API with the
402
.Dv WNOHANG
403
option set checking these fields is the only way to know whether
404
there were any status changes to report, because the return value
405
from
406
.Fn waitid
407
will be zero as it is for any successful return from
408
.Fn waitid .
154
.Pp
409
.Pp
155
When the
410
When the
156
.Dv WNOHANG
411
.Dv WNOHANG
Lines 284-289 Link Here
284
is set to indicate the error.
539
is set to indicate the error.
285
.Pp
540
.Pp
286
If
541
If
542
.Fn wait6 ,
287
.Fn wait4 ,
543
.Fn wait4 ,
288
.Fn wait3 ,
544
.Fn wait3 ,
289
or
545
or
Lines 306-311 Link Here
306
is returned and
562
is returned and
307
.Va errno
563
.Va errno
308
is set to indicate the error.
564
is set to indicate the error.
565
.Pp
566
If
567
.Fn waitid
568
returns because one or more processes have a state change to report,
569
0 is returned.
570
To indicate an error, -1 will be returned and
571
.Dv errno
572
set to an appropriate value.
573
If
574
.Dv WNOHANG
575
was used, 0 can be returned indicating no error, but no processes
576
may have changed state either, if si_signo and/or si_pid are zero.
309
.Sh ERRORS
577
.Sh ERRORS
310
The
578
The
311
.Fn wait
579
.Fn wait
Lines 335-340 Link Here
335
or the signal did not have the
603
or the signal did not have the
336
.Dv SA_RESTART
604
.Dv SA_RESTART
337
flag set.
605
flag set.
606
.It Bq Er EINVAL
607
An invalid value was specified for
608
.Fa options ,
609
or
610
.Fa idtype
611
and
612
.Fa id
613
do not specify a valid set of processes.
338
.El
614
.El
339
.Sh SEE ALSO
615
.Sh SEE ALSO
340
.Xr _exit 2 ,
616
.Xr _exit 2 ,
Lines 344-354 Link Here
344
.Xr siginfo 3
620
.Xr siginfo 3
345
.Sh STANDARDS
621
.Sh STANDARDS
346
The
622
The
347
.Fn wait
623
.Fn wait ,
624
.Fn waitpid ,
348
and
625
and
349
.Fn waitpid
626
.Fn waitid
350
functions are defined by POSIX;
627
functions are defined by POSIX;
351
.Fn wait4
628
.Fn wait6 ,
629
.Fn wait4 ,
352
and
630
and
353
.Fn wait3
631
.Fn wait3
354
are not specified by POSIX.
632
are not specified by POSIX.
(-)sys/kern/kern_exit.c (-30 / +319 lines)
Lines 684-690 Link Here
684
 * The dirty work is handled by kern_wait().
684
 * The dirty work is handled by kern_wait().
685
 */
685
 */
686
int
686
int
687
sys_wait4(struct thread *td, struct wait_args *uap)
687
sys_wait4(struct thread *td, struct wait4_args *uap)
688
{
688
{
689
	struct rusage ru, *rup;
689
	struct rusage ru, *rup;
690
	int error, status;
690
	int error, status;
Lines 693-698 Link Here
693
		rup = &ru;
693
		rup = &ru;
694
	else
694
	else
695
		rup = NULL;
695
		rup = NULL;
696
696
	error = kern_wait(td, uap->pid, &status, uap->options, rup);
697
	error = kern_wait(td, uap->pid, &status, uap->options, rup);
697
	if (uap->status != NULL && error == 0)
698
	if (uap->status != NULL && error == 0)
698
		error = copyout(&status, uap->status, sizeof(status));
699
		error = copyout(&status, uap->status, sizeof(status));
Lines 701-714 Link Here
701
	return (error);
702
	return (error);
702
}
703
}
703
704
705
int
706
sys_wait6(struct thread *td, struct wait6_args *uap)
707
{
708
	struct wrusage wru, *wrup;
709
	siginfo_t  si, *sip;
710
	int error, status;
711
	idtype_t idtype;
712
	id_t id;
713
714
	idtype = uap->idtype;
715
	id = uap->id;
716
717
	if (uap->wrusage != NULL)
718
		wrup = &wru;
719
	else
720
		wrup = NULL;
721
722
	if (uap->info != NULL)
723
		sip = &si;
724
	else
725
		sip = NULL;
726
727
	/*
728
	 *  We expect all callers of wait6()
729
	 *  to know about WEXITED and WTRAPPED!
730
	 */
731
	error = kern_wait6(td, idtype, id, &status, uap->options, wrup, sip);
732
733
	if (uap->status != NULL && error == 0)
734
		error = copyout(&status, uap->status, sizeof(status));
735
	if (uap->wrusage != NULL && error == 0)
736
		error = copyout(&wru, uap->wrusage, sizeof(wru));
737
	if (uap->info != NULL && error == 0)
738
		error = copyout(&si, uap->info, sizeof(si));
739
	return (error);
740
}
741
704
/*
742
/*
705
 * Reap the remains of a zombie process and optionally return status and
743
 * Reap the remains of a zombie process and optionally return status and
706
 * rusage.  Asserts and will release both the proctree_lock and the process
744
 * rusage.  Asserts and will release both the proctree_lock and the process
707
 * lock as part of its work.
745
 * lock as part of its work.
708
 */
746
 */
709
void
747
void
710
proc_reap(struct thread *td, struct proc *p, int *status, int options,
748
proc_reap(struct thread *td, struct proc *p, int *status, int options)
711
    struct rusage *rusage)
712
{
749
{
713
	struct proc *q, *t;
750
	struct proc *q, *t;
714
751
Lines 718-727 Link Here
718
	KASSERT(p->p_state == PRS_ZOMBIE, ("proc_reap: !PRS_ZOMBIE"));
755
	KASSERT(p->p_state == PRS_ZOMBIE, ("proc_reap: !PRS_ZOMBIE"));
719
756
720
	q = td->td_proc;
757
	q = td->td_proc;
721
	if (rusage) {
758
722
		*rusage = p->p_ru;
723
		calcru(p, &rusage->ru_utime, &rusage->ru_stime);
724
	}
725
	PROC_SUNLOCK(p);
759
	PROC_SUNLOCK(p);
726
	td->td_retval[0] = p->p_pid;
760
	td->td_retval[0] = p->p_pid;
727
	if (status)
761
	if (status)
Lines 834-841 Link Here
834
}
868
}
835
869
836
static int
870
static int
837
proc_to_reap(struct thread *td, struct proc *p, pid_t pid, int *status,
871
proc_to_reap(struct thread *td, struct proc *p,
838
    int options, struct rusage *rusage)
872
	     idtype_t idtype, id_t id, 
873
	     int *status, int options,
874
	     struct wrusage *wrusage, siginfo_t *siginfo)
839
{
875
{
840
	struct proc *q;
876
	struct proc *q;
841
877
Lines 843-857 Link Here
843
879
844
	q = td->td_proc;
880
	q = td->td_proc;
845
	PROC_LOCK(p);
881
	PROC_LOCK(p);
846
	if (pid != WAIT_ANY && p->p_pid != pid && p->p_pgid != -pid) {
882
883
	switch (idtype) {
884
	case P_ALL:
885
		break;
886
	case P_PID:
887
		if (p->p_pid != (pid_t) id) {
888
			PROC_UNLOCK(p);
889
			return (0);
890
		}
891
		break;
892
	case P_PGID:
893
		if (p->p_pgid != (pid_t) id) {
894
			PROC_UNLOCK(p);
895
			return (0);
896
		}
897
		break;
898
	case P_SID:
899
		if (p->p_session->s_sid != (pid_t) id) {
900
			PROC_UNLOCK(p);
901
			return (0);
902
		}
903
		break;
904
	case P_UID:
905
		if (p->p_ucred->cr_uid != (uid_t) id) {
906
			PROC_UNLOCK(p);
907
			return (0);
908
		}
909
		break;
910
	case P_GID:
911
		if (p->p_ucred->cr_gid != (gid_t) id) {
912
			PROC_UNLOCK(p);
913
			return (0);
914
		}
915
		break;
916
	case P_ZONEID:	/* jail */
917
		if (! p->p_ucred->cr_prison ||
918
		    (p->p_ucred->cr_prison->pr_id != (int) id)) {
919
			PROC_UNLOCK(p);
920
			return (0);
921
		}
922
		break;
923
#if 0
924
		/*
925
		 * It seems that the thread structures get zeroed out
926
		 * at process exit.
927
		 * This makes toast of all useful info related to
928
		 * CPU, CPU set, and scheduling priority class.
929
		 */
930
	case P_PSETID:
931
		{
932
			struct thread	*td1;
933
934
			td1 = FIRST_THREAD_IN_PROC(p);
935
			if (td1->td_cpuset->cs_id != (cpusetid_t) id) {
936
				PROC_UNLOCK(p);
937
				return (0);
938
			}
939
		}
940
		break;
941
	case P_CID:
942
		{
943
			struct thread	*td1;
944
945
			td1 = FIRST_THREAD_IN_PROC(p);
946
			if (td1->td_pri_class != (unsigned) id) {
947
				PROC_UNLOCK(p);
948
				return (0);
949
			}
950
		}
951
		break;
952
	case P_CPUID:
953
		{
954
			struct thread	*td1;
955
956
			td1 = FIRST_THREAD_IN_PROC(p);
957
			if (td1->td_lastcpu != (unsigned) id) {
958
				PROC_UNLOCK(p);
959
				return (0);
960
			}
961
		}
962
		break;
963
#endif
964
965
	default:
847
		PROC_UNLOCK(p);
966
		PROC_UNLOCK(p);
848
		return (0);
967
		return (0);
968
		break;
849
	}
969
	}
970
850
	if (p_canwait(td, p)) {
971
	if (p_canwait(td, p)) {
851
		PROC_UNLOCK(p);
972
		PROC_UNLOCK(p);
852
		return (0);
973
		return (0);
853
	}
974
	}
854
975
976
	if (((options & WEXITED) == 0) && (p->p_state == PRS_ZOMBIE)) {
977
		PROC_UNLOCK(p);
978
		return (0);
979
	}
980
		
855
	/*
981
	/*
856
	 * This special case handles a kthread spawned by linux_clone
982
	 * This special case handles a kthread spawned by linux_clone
857
	 * (see linux_misc.c).  The linux_wait4 and linux_waitpid
983
	 * (see linux_misc.c).  The linux_wait4 and linux_waitpid
Lines 867-874 Link Here
867
	}
993
	}
868
994
869
	PROC_SLOCK(p);
995
	PROC_SLOCK(p);
996
997
	if (siginfo) {
998
		bzero (siginfo, sizeof (*siginfo));
999
		siginfo->si_signo = SIGCHLD;
1000
		siginfo->si_errno = 0;
1001
1002
		/*
1003
		 *  Right, this is still a rough estimate.
1004
		 *  We will fix the cases TRAPPED, STOPPED,
1005
		 *  and CONTINUED later.
1006
		 */
1007
1008
		if (WCOREDUMP(p->p_xstat))
1009
			siginfo->si_code = CLD_DUMPED;
1010
		else if (WIFSIGNALED(p->p_xstat))
1011
			siginfo->si_code = CLD_KILLED;
1012
		else
1013
			siginfo->si_code = CLD_EXITED;
1014
1015
		siginfo->si_pid = p->p_pid;
1016
		siginfo->si_uid = p->p_ucred->cr_uid;
1017
		siginfo->si_status = p->p_xstat;
1018
1019
		/*
1020
		 * The si_addr field would be useful additional detail,
1021
		 * but apparently the PC value may be lost when we reach
1022
		 * this point.
1023
		 * bzero() above sets siginfo->si_addr to NULL.
1024
		 */
1025
	}
1026
1027
	/*
1028
	 * There should be no reason to limit resources usage info
1029
	 * to exited processes only.
1030
	 * A snapshot about any resources used by a stopped process
1031
	 * may be exactly what is needed.
1032
	 * We are now within the same PROC_SLOCK anyway.
1033
	 */
1034
1035
	if (wrusage) {
1036
#if 0
1037
		*rusage = p->p_ru;
1038
		calcru(p, &rusage->ru_utime, &rusage->ru_stime);
1039
#endif
1040
		struct rusage *rup;
1041
1042
		rup = &wrusage->wru_self;
1043
		*rup = p->p_ru;
1044
		calcru(p, &rup->ru_utime, &rup->ru_stime);
1045
1046
		rup = &wrusage->wru_children;
1047
		*rup = p->p_stats->p_cru;
1048
		calccru(p, &rup->ru_utime, &rup->ru_stime);
1049
	}
1050
870
	if (p->p_state == PRS_ZOMBIE) {
1051
	if (p->p_state == PRS_ZOMBIE) {
871
		proc_reap(td, p, status, options, rusage);
1052
		proc_reap(td, p, status, options);
872
		return (-1);
1053
		return (-1);
873
	}
1054
	}
874
	PROC_SUNLOCK(p);
1055
	PROC_SUNLOCK(p);
Lines 877-900 Link Here
877
}
1058
}
878
1059
879
int
1060
int
880
kern_wait(struct thread *td, pid_t pid, int *status, int options,
1061
kern_wait(struct thread *td, pid_t pid,
881
    struct rusage *rusage)
1062
	  int *status, int options, struct rusage *rusage)
1063
{
1064
	struct wrusage wru, *wrup;
1065
	idtype_t idtype;
1066
	id_t id;
1067
	int ret;
1068
1069
	if (pid == WAIT_ANY) {
1070
		idtype = P_ALL;
1071
		id = 0;
1072
	}
1073
	else if (pid <= 0) {
1074
		idtype = P_PGID;
1075
		id = (id_t)-pid;
1076
	}
1077
	else {
1078
		idtype = P_PID;
1079
		id = (id_t)pid;
1080
	}
1081
1082
	if (rusage)
1083
		wrup = &wru;
1084
	else
1085
		wrup = NULL;
1086
1087
	/*
1088
	 *  For backward compatibility we implicitly
1089
	 *  add flags WEXITED and WTRAPPED here.
1090
	 */
1091
	options |= (WEXITED | WTRAPPED);
1092
1093
	ret = kern_wait6 (td, idtype, id, status, options, wrup, NULL);
1094
1095
	if (rusage)
1096
		*rusage = wru.wru_self;
1097
1098
	return (ret);
1099
}
1100
1101
int
1102
kern_wait6(struct thread *td, idtype_t idtype, id_t id,
1103
	   int *status, int options,
1104
	   struct wrusage *wrusage, siginfo_t *siginfo)
882
{
1105
{
883
	struct proc *p, *q;
1106
	struct proc *p, *q;
884
	int error, nfound, ret;
1107
	int error, nfound, ret;
885
1108
886
	AUDIT_ARG_PID(pid);
1109
	AUDIT_ARG_VALUE((int)idtype);	/* XXX - This is likely wrong! */
1110
	AUDIT_ARG_PID((pid_t)id);	/* XXX - This may be wrong! */
887
	AUDIT_ARG_VALUE(options);
1111
	AUDIT_ARG_VALUE(options);
888
1112
889
	q = td->td_proc;
1113
	q = td->td_proc;
890
	if (pid == 0) {
1114
1115
	if (((pid_t)id == WAIT_MYPGRP) &&
1116
	    ((idtype == P_PID) || (idtype == P_PGID))) {
891
		PROC_LOCK(q);
1117
		PROC_LOCK(q);
892
		pid = -q->p_pgid;
1118
		id = (id_t)q->p_pgid;
893
		PROC_UNLOCK(q);
1119
		PROC_UNLOCK(q);
1120
		idtype = P_PGID;
894
	}
1121
	}
1122
895
	/* If we don't know the option, just return. */
1123
	/* If we don't know the option, just return. */
896
	if (options & ~(WUNTRACED|WNOHANG|WCONTINUED|WNOWAIT|WLINUXCLONE))
1124
	if (options & ~(WUNTRACED|WNOHANG|WCONTINUED|
1125
			WNOWAIT|WEXITED|WTRAPPED|WLINUXCLONE))
1126
		return (EINVAL);
1127
1128
	if ((options & (WEXITED|WUNTRACED|WCONTINUED|WTRAPPED)) == 0) {
1129
		/*
1130
		 *  We will be unable to find any matching processes,
1131
		 *  because there are no known events to look for.
1132
		 *  Tell the programmer (s)he is doing something
1133
		 *  patently dysfunctional.
1134
		 */
897
		return (EINVAL);
1135
		return (EINVAL);
1136
	}
1137
898
loop:
1138
loop:
899
	if (q->p_flag & P_STATCHILD) {
1139
	if (q->p_flag & P_STATCHILD) {
900
		PROC_LOCK(q);
1140
		PROC_LOCK(q);
Lines 904-910 Link Here
904
	nfound = 0;
1144
	nfound = 0;
905
	sx_xlock(&proctree_lock);
1145
	sx_xlock(&proctree_lock);
906
	LIST_FOREACH(p, &q->p_children, p_sibling) {
1146
	LIST_FOREACH(p, &q->p_children, p_sibling) {
907
		ret = proc_to_reap(td, p, pid, status, options, rusage);
1147
		ret = proc_to_reap(td, p, idtype, id,
1148
				   status, options, wrusage, siginfo);
908
		if (ret == 0)
1149
		if (ret == 0)
909
			continue;
1150
			continue;
910
		else if (ret == 1)
1151
		else if (ret == 1)
Lines 914-950 Link Here
914
1155
915
		PROC_LOCK(p);
1156
		PROC_LOCK(p);
916
		PROC_SLOCK(p);
1157
		PROC_SLOCK(p);
917
		if ((p->p_flag & P_STOPPED_SIG) &&
1158
1159
		if ((options & WTRAPPED) &&
1160
		    (p->p_flag & P_TRACED) &&
1161
		    (p->p_flag & (P_STOPPED_TRACE | P_STOPPED_SIG)) &&
918
		    (p->p_suspcount == p->p_numthreads) &&
1162
		    (p->p_suspcount == p->p_numthreads) &&
919
		    (p->p_flag & P_WAITED) == 0 &&
1163
		    ((p->p_flag & P_WAITED) == 0)) {
920
		    (p->p_flag & P_TRACED || options & WUNTRACED)) {
921
			PROC_SUNLOCK(p);
1164
			PROC_SUNLOCK(p);
922
			p->p_flag |= P_WAITED;
1165
1166
			if ((options & WNOWAIT) == 0)
1167
				p->p_flag |= P_WAITED;
1168
923
			sx_xunlock(&proctree_lock);
1169
			sx_xunlock(&proctree_lock);
924
			td->td_retval[0] = p->p_pid;
1170
			td->td_retval[0] = p->p_pid;
1171
925
			if (status)
1172
			if (status)
926
				*status = W_STOPCODE(p->p_xstat);
1173
				*status = W_STOPCODE(p->p_xstat);
1174
			if (siginfo) {
1175
				siginfo->si_status = W_STOPCODE(p->p_xstat);
1176
				siginfo->si_code = CLD_TRAPPED;
1177
			}
1178
			if ((options & WNOWAIT) == 0) {
1179
				PROC_LOCK(q);
1180
				sigqueue_take(p->p_ksi);
1181
				PROC_UNLOCK(q);
1182
			}
927
1183
928
			PROC_LOCK(q);
929
			sigqueue_take(p->p_ksi);
930
			PROC_UNLOCK(q);
931
			PROC_UNLOCK(p);
1184
			PROC_UNLOCK(p);
1185
			return (0);
1186
		}
1187
		if ((options & WUNTRACED) &&
1188
		    (p->p_flag & P_STOPPED_SIG) &&
1189
		    (p->p_suspcount == p->p_numthreads) &&
1190
		    ((p->p_flag & P_WAITED) == 0)) {
1191
			PROC_SUNLOCK(p);
1192
1193
			if ((options & WNOWAIT) == 0)
1194
				p->p_flag |= P_WAITED;
1195
1196
			sx_xunlock(&proctree_lock);
1197
			td->td_retval[0] = p->p_pid;
932
1198
1199
			if (status)
1200
				*status = W_STOPCODE(p->p_xstat);
1201
			if (siginfo) {
1202
				siginfo->si_status = W_STOPCODE(p->p_xstat);
1203
				siginfo->si_code = CLD_STOPPED;
1204
			}
1205
			if ((options & WNOWAIT) == 0) {
1206
				PROC_LOCK(q);
1207
				sigqueue_take(p->p_ksi);
1208
				PROC_UNLOCK(q);
1209
			}
1210
1211
			PROC_UNLOCK(p);
933
			return (0);
1212
			return (0);
934
		}
1213
		}
935
		PROC_SUNLOCK(p);
1214
		PROC_SUNLOCK(p);
936
		if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) {
1215
		if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) {
937
			sx_xunlock(&proctree_lock);
1216
			sx_xunlock(&proctree_lock);
938
			td->td_retval[0] = p->p_pid;
1217
			td->td_retval[0] = p->p_pid;
939
			p->p_flag &= ~P_CONTINUED;
940
1218
941
			PROC_LOCK(q);
1219
			if ((options & WNOWAIT) == 0) {
942
			sigqueue_take(p->p_ksi);
1220
				p->p_flag &= ~P_CONTINUED;
943
			PROC_UNLOCK(q);
1221
1222
				PROC_LOCK(q);
1223
				sigqueue_take(p->p_ksi);
1224
				PROC_UNLOCK(q);
1225
			}
1226
944
			PROC_UNLOCK(p);
1227
			PROC_UNLOCK(p);
945
1228
946
			if (status)
1229
			if (status)
947
				*status = SIGCONT;
1230
				*status = SIGCONT;
1231
			if (siginfo) {
1232
				siginfo->si_status = SIGCONT;
1233
				siginfo->si_code = CLD_CONTINUED;
1234
			}
1235
948
			return (0);
1236
			return (0);
949
		}
1237
		}
950
		PROC_UNLOCK(p);
1238
		PROC_UNLOCK(p);
Lines 963-969 Link Here
963
	 * to successfully wait until the child becomes a zombie.
1251
	 * to successfully wait until the child becomes a zombie.
964
	 */
1252
	 */
965
	LIST_FOREACH(p, &q->p_orphans, p_orphan) {
1253
	LIST_FOREACH(p, &q->p_orphans, p_orphan) {
966
		ret = proc_to_reap(td, p, pid, status, options, rusage);
1254
		ret = proc_to_reap(td, p, idtype, id,
1255
				   status, options, wrusage, siginfo);
967
		if (ret == 0)
1256
		if (ret == 0)
968
			continue;
1257
			continue;
969
		else if (ret == 1)
1258
		else if (ret == 1)
(-)lib/libc/sys/Makefile.inc (-1 / +1 lines)
Lines 214-218 Link Here
214
MLINKS+=truncate.2 ftruncate.2
214
MLINKS+=truncate.2 ftruncate.2
215
MLINKS+=unlink.2 unlinkat.2
215
MLINKS+=unlink.2 unlinkat.2
216
MLINKS+=utimes.2 futimes.2 utimes.2 futimesat.2 utimes.2 lutimes.2
216
MLINKS+=utimes.2 futimes.2 utimes.2 futimesat.2 utimes.2 lutimes.2
217
MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2
217
MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2 wait.2 waitid.2 wait.2 wait6.2
218
MLINKS+=write.2 pwrite.2 write.2 pwritev.2 write.2 writev.2
218
MLINKS+=write.2 pwrite.2 write.2 pwritev.2 write.2 writev.2
(-)sys/compat/freebsd32/syscalls.master (+5 lines)
Lines 997-999 Link Here
997
				    uint32_t offset1, uint32_t offset2,\
997
				    uint32_t offset1, uint32_t offset2,\
998
				    uint32_t len1, uint32_t len2, \
998
				    uint32_t len1, uint32_t len2, \
999
				    int advice); }
999
				    int advice); }
1000
532	AUE_WAIT6	STD	{ int freebsd32_wait6(int idtype, int id, \
1001
					    int *status, int options, \
1002
					    struct wrusage32 *wrusage, \
1003
					    siginfo_t *info); }
1004
(-)sys/kern/syscalls.master (-1 / +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 949-953 Link Here
949
				    off_t offset, off_t len); }
949
				    off_t offset, off_t len); }
950
531	AUE_NULL	STD	{ int posix_fadvise(int fd, off_t offset, \
950
531	AUE_NULL	STD	{ int posix_fadvise(int fd, off_t offset, \
951
				    off_t len, int advice); }
951
				    off_t len, int advice); }
952
532	AUE_WAIT6	STD	{ int wait6(int idtype, int id, \
953
					    int *status, int options, \
954
					    struct wrusage *wrusage, \
955
					    siginfo_t *info); } \
956
					wait6 wait6_args int
952
; Please copy any additions and changes to the following compatability tables:
957
; Please copy any additions and changes to the following compatability tables:
953
; sys/compat/freebsd32/syscalls.master
958
; sys/compat/freebsd32/syscalls.master
(-)sys/compat/freebsd32/freebsd32.h (+5 lines)
Lines 79-84 Link Here
79
	int32_t	ru_nivcsw;
79
	int32_t	ru_nivcsw;
80
};
80
};
81
81
82
struct wrusage32 {
83
	struct rusage32	wru_self;
84
	struct rusage32 wru_children;
85
};
86
82
struct itimerval32 {
87
struct itimerval32 {
83
	struct timeval32 it_interval;
88
	struct timeval32 it_interval;
84
	struct timeval32 it_value;
89
	struct timeval32 it_value;
(-)sys/compat/freebsd32/freebsd32_misc.c (+37 lines)
Lines 174-179 Link Here
174
	return (error);
174
	return (error);
175
}
175
}
176
176
177
int
178
freebsd32_wait6(struct thread *td, struct freebsd32_wait6_args *uap)
179
{
180
	int error, status;
181
	struct wrusage32 wru32;
182
	struct wrusage wru, *wrup;
183
	struct siginfo32 si32;
184
	struct __siginfo si, *sip;
185
186
	if (uap->wrusage != NULL)
187
		wrup = &wru;
188
	else
189
		wrup = NULL;
190
191
	if (uap->info != NULL)
192
		sip = &si;
193
	else
194
		sip = NULL;
195
196
	error = kern_wait6(td, uap->idtype, uap->id, 
197
			   &status, uap->options, wrup, sip);
198
	if (error)
199
		return (error);
200
	if (uap->status != NULL)
201
		error = copyout(&status, uap->status, sizeof(status));
202
	if (uap->wrusage != NULL && error == 0) {
203
		freebsd32_rusage_out(&wru.wru_self, &wru32.wru_self);
204
		freebsd32_rusage_out(&wru.wru_children, &wru32.wru_children);
205
		error = copyout(&wru32, uap->wrusage, sizeof(wru32));
206
	}
207
	if (uap->info != NULL && error == 0) {
208
		siginfo_to_siginfo32 (&si, &si32);
209
		error = copyout(&si32, uap->info, sizeof(si32));
210
	}
211
	return (error);
212
}
213
177
#ifdef COMPAT_FREEBSD4
214
#ifdef COMPAT_FREEBSD4
178
static void
215
static void
179
copy_statfs(struct statfs *in, struct statfs32 *out)
216
copy_statfs(struct statfs *in, struct statfs32 *out)
(-)sys/sys/resource.h (+7 lines)
Lines 79-84 Link Here
79
#define	ru_last		ru_nivcsw
79
#define	ru_last		ru_nivcsw
80
};
80
};
81
81
82
#if __BSD_VISIBLE
83
struct wrusage {
84
	struct rusage	wru_self;
85
	struct rusage	wru_children;
86
};
87
#endif
88
82
/*
89
/*
83
 * Resource limits
90
 * Resource limits
84
 */
91
 */
(-)lib/libc/gen/waitid.c (+61 lines)
Added Link Here
1
2
#include "namespace.h"
3
#include <sys/types.h>
4
#include <sys/wait.h>
5
#include <stddef.h>
6
#include <string.h>
7
#include <signal.h>
8
#include <errno.h>
9
#include "un-namespace.h"
10
11
int
12
__waitid (idtype, id, info, flags)
13
	idtype_t	idtype;
14
	id_t		id;
15
	siginfo_t	*info;
16
	int		flags;
17
{
18
	int	status;
19
	pid_t	ret;
20
21
	if (info) {
22
		memset (info, '\0', sizeof (*info));
23
	}
24
25
	/*
26
	 * In case you wish to start waiting for processes
27
	 * - in a certain scheduling class,
28
	 * - running on a certain cpu, or
29
	 * - nailed to a certain CPU set,
30
	 * - etc.
31
	 *  you will have to extend the kern_wait6() in
32
	 *  the kernel to support such idtype_t flavours.
33
	 */
34
35
	ret = _wait6 (idtype, id, &status, flags, NULL, info);
36
37
	/*
38
	 * According to SUS waitid() shall not return a PID when a process
39
	 * is found but only 0.
40
	 * If a process was actually found siginfo_t fields si_signo and
41
	 * si_pid will be non-zero. In case WNOHANG was set in the flags
42
	 * and no process was found those fields will be set to zero.
43
	 */
44
45
	if (ret < 0) {
46
		ret = -1;
47
	}
48
	else if (ret == 0) {
49
		if (info) {
50
			memset (info, '\0', sizeof (*info));
51
		}
52
	}
53
	else {
54
		ret = 0;	/* Crazy standards... */
55
	}
56
57
	return ((int)ret);
58
}
59
60
__weak_reference(__waitid, waitid);
61
__weak_reference(__waitid, _waitid);

Return to bug 170346