summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/bsm/audit_kevents.h1
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/procset.h4
-rw-r--r--sys/compat/freebsd32/freebsd32.h5
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c38
-rw-r--r--sys/compat/freebsd32/syscalls.master5
-rw-r--r--sys/kern/kern_exit.c305
-rw-r--r--sys/kern/sys_procdesc.c2
-rw-r--r--sys/kern/syscalls.master7
-rw-r--r--sys/sys/proc.h3
-rw-r--r--sys/sys/resource.h7
-rw-r--r--sys/sys/syscallsubr.h3
-rw-r--r--sys/sys/types.h40
-rw-r--r--sys/sys/wait.h12
13 files changed, 390 insertions, 42 deletions
diff --git a/sys/bsm/audit_kevents.h b/sys/bsm/audit_kevents.h
index f4f77a5..3eb2e3a 100644
--- a/sys/bsm/audit_kevents.h
+++ b/sys/bsm/audit_kevents.h
@@ -602,6 +602,7 @@
#define AUE_PDKILL 43198 /* FreeBSD. */
#define AUE_PDGETPID 43199 /* FreeBSD. */
#define AUE_PDWAIT 43200 /* FreeBSD. */
+#define AUE_WAIT6 43201 /* FreeBSD. */
/*
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/procset.h b/sys/cddl/contrib/opensolaris/uts/common/sys/procset.h
index c367c93..8c5739b 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/procset.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/procset.h
@@ -51,6 +51,7 @@ extern "C" {
#define P_INITUID 0
#define P_INITPGID 0
+#ifndef _IDTYPE_T_DECLARED
/*
* The following defines the values for an identifier type. It
@@ -81,6 +82,9 @@ typedef enum
P_PSETID /* Processor set identifier */
} idtype_t;
+#define _IDTYPE_T_DECLARED
+
+#endif
/*
* The following defines the operations which can be performed to
diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
index fccdef0..a95b0e5 100644
--- a/sys/compat/freebsd32/freebsd32.h
+++ b/sys/compat/freebsd32/freebsd32.h
@@ -88,6 +88,11 @@ struct rusage32 {
int32_t ru_nivcsw;
};
+struct wrusage32 {
+ struct rusage32 wru_self;
+ struct rusage32 wru_children;
+};
+
struct itimerval32 {
struct timeval32 it_interval;
struct timeval32 it_value;
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index ce8bd7a..8c5f5a6 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -180,6 +180,44 @@ freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
return (error);
}
+int
+freebsd32_wait6(struct thread *td, struct freebsd32_wait6_args *uap)
+{
+ struct wrusage32 wru32;
+ struct __wrusage wru, *wrup;
+ struct siginfo32 si32;
+ struct __siginfo si, *sip;
+ int error, status;
+
+ if (uap->wrusage != NULL)
+ wrup = &wru;
+ else
+ wrup = NULL;
+
+ if (uap->info != NULL) {
+ sip = &si;
+ bzero(sip, sizeof(*sip));
+ } else
+ sip = NULL;
+
+ error = kern_wait6(td, uap->idtype, uap->id, &status, uap->options,
+ wrup, sip);
+ if (error != 0)
+ return (error);
+ if (uap->status != NULL)
+ error = copyout(&status, uap->status, sizeof(status));
+ if (uap->wrusage != NULL && error == 0) {
+ freebsd32_rusage_out(&wru.wru_self, &wru32.wru_self);
+ freebsd32_rusage_out(&wru.wru_children, &wru32.wru_children);
+ error = copyout(&wru32, uap->wrusage, sizeof(wru32));
+ }
+ if (uap->info != NULL && error == 0) {
+ siginfo_to_siginfo32 (&si, &si32);
+ error = copyout(&si32, uap->info, sizeof(si32));
+ }
+ return (error);
+}
+
#ifdef COMPAT_FREEBSD4
static void
copy_statfs(struct statfs *in, struct statfs32 *out)
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index 478558a..4106447 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -1000,3 +1000,8 @@
uint32_t offset1, uint32_t offset2,\
uint32_t len1, uint32_t len2, \
int advice); }
+532 AUE_WAIT6 STD { int freebsd32_wait6(int idtype, int id, \
+ int *status, int options, \
+ struct wrusage32 *wrusage, \
+ siginfo_t *info); }
+
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index c04b992..6b92c25 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -143,7 +143,7 @@ exit1(struct thread *td, int rv)
* XXX in case we're rebooting we just let init die in order to
* work around an unsolved stack overflow seen very late during
* shutdown on sparc64 when the gmirror worker process exists.
- */
+ */
if (p == initproc && rebooting == 0) {
printf("init died (signal %d, exit %d)\n",
WTERMSIG(rv), WEXITSTATUS(rv));
@@ -617,7 +617,7 @@ sys_abort2(struct thread *td, struct abort2_args *uap)
sbuf_clear(sb);
sbuf_printf(sb, "%s(pid %d uid %d) aborted: ",
p->p_comm, p->p_pid, td->td_ucred->cr_uid);
- /*
+ /*
* Since we can't return from abort2(), send SIGKILL in cases, where
* abort2() was called improperly
*/
@@ -689,7 +689,7 @@ owait(struct thread *td, struct owait_args *uap __unused)
* The dirty work is handled by kern_wait().
*/
int
-sys_wait4(struct thread *td, struct wait_args *uap)
+sys_wait4(struct thread *td, struct wait4_args *uap)
{
struct rusage ru, *rup;
int error, status;
@@ -706,14 +706,51 @@ sys_wait4(struct thread *td, struct wait_args *uap)
return (error);
}
+int
+sys_wait6(struct thread *td, struct wait6_args *uap)
+{
+ struct __wrusage wru, *wrup;
+ siginfo_t si, *sip;
+ int error, status;
+ idtype_t idtype;
+ id_t id;
+
+ idtype = uap->idtype;
+ id = uap->id;
+
+ if (uap->wrusage != NULL)
+ wrup = &wru;
+ else
+ wrup = NULL;
+
+ if (uap->info != NULL) {
+ sip = &si;
+ bzero(sip, sizeof(*sip));
+ } else
+ sip = NULL;
+
+ /*
+ * We expect all callers of wait6() to know about WEXITED and
+ * WTRAPPED.
+ */
+ error = kern_wait6(td, idtype, id, &status, uap->options, wrup, sip);
+
+ if (uap->status != NULL && error == 0)
+ error = copyout(&status, uap->status, sizeof(status));
+ if (uap->wrusage != NULL && error == 0)
+ error = copyout(&wru, uap->wrusage, sizeof(wru));
+ if (uap->info != NULL && error == 0)
+ error = copyout(&si, uap->info, sizeof(si));
+ return (error);
+}
+
/*
* Reap the remains of a zombie process and optionally return status and
* rusage. Asserts and will release both the proctree_lock and the process
* lock as part of its work.
*/
void
-proc_reap(struct thread *td, struct proc *p, int *status, int options,
- struct rusage *rusage)
+proc_reap(struct thread *td, struct proc *p, int *status, int options)
{
struct proc *q, *t;
@@ -723,10 +760,7 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options,
KASSERT(p->p_state == PRS_ZOMBIE, ("proc_reap: !PRS_ZOMBIE"));
q = td->td_proc;
- if (rusage) {
- *rusage = p->p_ru;
- calcru(p, &rusage->ru_utime, &rusage->ru_stime);
- }
+
PROC_SUNLOCK(p);
td->td_retval[0] = p->p_pid;
if (status)
@@ -839,24 +873,78 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options,
}
static int
-proc_to_reap(struct thread *td, struct proc *p, pid_t pid, int *status,
- int options, struct rusage *rusage)
+proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id,
+ int *status, int options, struct __wrusage *wrusage, siginfo_t *siginfo)
{
struct proc *q;
+ struct rusage *rup;
sx_assert(&proctree_lock, SA_XLOCKED);
q = td->td_proc;
PROC_LOCK(p);
- if (pid != WAIT_ANY && p->p_pid != pid && p->p_pgid != -pid) {
+
+ switch (idtype) {
+ case P_ALL:
+ break;
+ case P_PID:
+ if (p->p_pid != (pid_t)id) {
+ PROC_UNLOCK(p);
+ return (0);
+ }
+ break;
+ case P_PGID:
+ if (p->p_pgid != (pid_t)id) {
+ PROC_UNLOCK(p);
+ return (0);
+ }
+ break;
+ case P_SID:
+ if (p->p_session->s_sid != (pid_t)id) {
+ PROC_UNLOCK(p);
+ return (0);
+ }
+ break;
+ case P_UID:
+ if (p->p_ucred->cr_uid != (uid_t)id) {
+ PROC_UNLOCK(p);
+ return (0);
+ }
+ break;
+ case P_GID:
+ if (p->p_ucred->cr_gid != (gid_t)id) {
+ PROC_UNLOCK(p);
+ return (0);
+ }
+ break;
+ case P_JAILID:
+ if (p->p_ucred->cr_prison == NULL ||
+ (p->p_ucred->cr_prison->pr_id != (int)id)) {
+ PROC_UNLOCK(p);
+ return (0);
+ }
+ break;
+ /*
+ * It seems that the thread structures get zeroed out
+ * at process exit. This makes it impossible to
+ * support P_SETID, P_CID or P_CPUID.
+ */
+ default:
PROC_UNLOCK(p);
return (0);
+ break;
}
+
if (p_canwait(td, p)) {
PROC_UNLOCK(p);
return (0);
}
+ if (((options & WEXITED) == 0) && (p->p_state == PRS_ZOMBIE)) {
+ PROC_UNLOCK(p);
+ return (0);
+ }
+
/*
* This special case handles a kthread spawned by linux_clone
* (see linux_misc.c). The linux_wait4 and linux_waitpid
@@ -872,8 +960,59 @@ proc_to_reap(struct thread *td, struct proc *p, pid_t pid, int *status,
}
PROC_SLOCK(p);
+
+ if (siginfo != NULL) {
+ bzero (siginfo, sizeof (*siginfo));
+ siginfo->si_errno = 0;
+
+ /*
+ * SUSv4 requires that the si_signo value is always
+ * SIGCHLD. Obey it despite the rfork(2) interface
+ * allows to request other signal for child exit
+ * notification.
+ */
+ siginfo->si_signo = SIGCHLD;
+
+ /*
+ * This is still a rough estimate. We will fix the
+ * cases TRAPPED, STOPPED, and CONTINUED later.
+ */
+ if (WCOREDUMP(p->p_xstat))
+ siginfo->si_code = CLD_DUMPED;
+ else if (WIFSIGNALED(p->p_xstat))
+ siginfo->si_code = CLD_KILLED;
+ else
+ siginfo->si_code = CLD_EXITED;
+
+ siginfo->si_pid = p->p_pid;
+ siginfo->si_uid = p->p_ucred->cr_uid;
+ siginfo->si_status = p->p_xstat;
+
+ /*
+ * The si_addr field would be useful additional
+ * detail, but apparently the PC value may be lost
+ * when we reach this point. bzero() above sets
+ * siginfo->si_addr to NULL.
+ */
+ }
+
+ /*
+ * There should be no reason to limit resources usage info to
+ * exited processes only. A snapshot about any resources used
+ * by a stopped process may be exactly what is needed.
+ */
+ if (wrusage != NULL) {
+ rup = &wrusage->wru_self;
+ *rup = p->p_ru;
+ calcru(p, &rup->ru_utime, &rup->ru_stime);
+
+ rup = &wrusage->wru_children;
+ *rup = p->p_stats->p_cru;
+ calccru(p, &rup->ru_utime, &rup->ru_stime);
+ }
+
if (p->p_state == PRS_ZOMBIE) {
- proc_reap(td, p, status, options, rusage);
+ proc_reap(td, p, status, options);
return (-1);
}
PROC_SUNLOCK(p);
@@ -885,21 +1024,71 @@ int
kern_wait(struct thread *td, pid_t pid, int *status, int options,
struct rusage *rusage)
{
+ struct __wrusage wru, *wrup;
+ idtype_t idtype;
+ id_t id;
+ int ret;
+
+ if (pid == WAIT_ANY) {
+ idtype = P_ALL;
+ id = 0;
+ }
+ else if (pid <= 0) {
+ idtype = P_PGID;
+ id = (id_t)-pid;
+ }
+ else {
+ idtype = P_PID;
+ id = (id_t)pid;
+ }
+ if (rusage != NULL)
+ wrup = &wru;
+ else
+ wrup = NULL;
+ /*
+ * For backward compatibility we implicitly add flags WEXITED
+ * and WTRAPPED here.
+ */
+ options |= WEXITED | WTRAPPED;
+ ret = kern_wait6(td, idtype, id, status, options, wrup, NULL);
+ if (rusage != NULL)
+ *rusage = wru.wru_self;
+ return (ret);
+}
+
+int
+kern_wait6(struct thread *td, idtype_t idtype, id_t id, int *status,
+ int options, struct __wrusage *wrusage, siginfo_t *siginfo)
+{
struct proc *p, *q;
int error, nfound, ret;
- AUDIT_ARG_PID(pid);
+ AUDIT_ARG_VALUE((int)idtype); /* XXX - This is likely wrong! */
+ AUDIT_ARG_PID((pid_t)id); /* XXX - This may be wrong! */
AUDIT_ARG_VALUE(options);
q = td->td_proc;
- if (pid == 0) {
- PROC_LOCK(q);
- pid = -q->p_pgid;
- PROC_UNLOCK(q);
+
+ if ((pid_t)id == WAIT_MYPGRP &&
+ (idtype == P_PID || idtype == P_PGID)) {
+ id = (id_t)q->p_pgid;
+ idtype = P_PGID;
}
+
/* If we don't know the option, just return. */
- if (options & ~(WUNTRACED|WNOHANG|WCONTINUED|WNOWAIT|WLINUXCLONE))
+ if ((options & ~(WUNTRACED | WNOHANG | WCONTINUED | WNOWAIT |
+ WEXITED | WTRAPPED | WLINUXCLONE)) != 0)
return (EINVAL);
+ if ((options & (WEXITED | WUNTRACED | WCONTINUED | WTRAPPED)) == 0) {
+ /*
+ * We will be unable to find any matching processes,
+ * because there are no known events to look for.
+ * Prefer to return error instead of blocking
+ * indefinitely.
+ */
+ return (EINVAL);
+ }
+
loop:
if (q->p_flag & P_STATCHILD) {
PROC_LOCK(q);
@@ -909,7 +1098,8 @@ loop:
nfound = 0;
sx_xlock(&proctree_lock);
LIST_FOREACH(p, &q->p_children, p_sibling) {
- ret = proc_to_reap(td, p, pid, status, options, rusage);
+ ret = proc_to_reap(td, p, idtype, id, status, options,
+ wrusage, siginfo);
if (ret == 0)
continue;
else if (ret == 1)
@@ -919,37 +1109,77 @@ loop:
PROC_LOCK(p);
PROC_SLOCK(p);
- if ((p->p_flag & P_STOPPED_SIG) &&
+
+ if ((options & WTRAPPED) != 0 &&
+ (p->p_flag & P_TRACED) != 0 &&
+ (p->p_flag & (P_STOPPED_TRACE | P_STOPPED_SIG)) != 0 &&
(p->p_suspcount == p->p_numthreads) &&
- (p->p_flag & P_WAITED) == 0 &&
- (p->p_flag & P_TRACED || options & WUNTRACED)) {
+ ((p->p_flag & P_WAITED) == 0)) {
PROC_SUNLOCK(p);
- p->p_flag |= P_WAITED;
+ if ((options & WNOWAIT) == 0)
+ p->p_flag |= P_WAITED;
sx_xunlock(&proctree_lock);
td->td_retval[0] = p->p_pid;
- if (status)
+
+ if (status != NULL)
*status = W_STOPCODE(p->p_xstat);
+ if (siginfo != NULL) {
+ siginfo->si_status = p->p_xstat;
+ siginfo->si_code = CLD_TRAPPED;
+ }
+ if ((options & WNOWAIT) == 0) {
+ PROC_LOCK(q);
+ sigqueue_take(p->p_ksi);
+ PROC_UNLOCK(q);
+ }
- PROC_LOCK(q);
- sigqueue_take(p->p_ksi);
- PROC_UNLOCK(q);
PROC_UNLOCK(p);
+ return (0);
+ }
+ if ((options & WUNTRACED) != 0 &&
+ (p->p_flag & P_STOPPED_SIG) != 0 &&
+ (p->p_suspcount == p->p_numthreads) &&
+ ((p->p_flag & P_WAITED) == 0)) {
+ PROC_SUNLOCK(p);
+ if ((options & WNOWAIT) == 0)
+ p->p_flag |= P_WAITED;
+ sx_xunlock(&proctree_lock);
+ td->td_retval[0] = p->p_pid;
+
+ if (status != NULL)
+ *status = W_STOPCODE(p->p_xstat);
+ if (siginfo != NULL) {
+ siginfo->si_status = p->p_xstat;
+ siginfo->si_code = CLD_STOPPED;
+ }
+ if ((options & WNOWAIT) == 0) {
+ PROC_LOCK(q);
+ sigqueue_take(p->p_ksi);
+ PROC_UNLOCK(q);
+ }
+ PROC_UNLOCK(p);
return (0);
}
PROC_SUNLOCK(p);
- if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) {
+ if ((options & WCONTINUED) != 0 &&
+ (p->p_flag & P_CONTINUED) != 0) {
sx_xunlock(&proctree_lock);
td->td_retval[0] = p->p_pid;
- p->p_flag &= ~P_CONTINUED;
-
- PROC_LOCK(q);
- sigqueue_take(p->p_ksi);
- PROC_UNLOCK(q);
+ if ((options & WNOWAIT) == 0) {
+ p->p_flag &= ~P_CONTINUED;
+ PROC_LOCK(q);
+ sigqueue_take(p->p_ksi);
+ PROC_UNLOCK(q);
+ }
PROC_UNLOCK(p);
- if (status)
+ if (status != NULL)
*status = SIGCONT;
+ if (siginfo != NULL) {
+ siginfo->si_status = SIGCONT;
+ siginfo->si_code = CLD_CONTINUED;
+ }
return (0);
}
PROC_UNLOCK(p);
@@ -968,7 +1198,8 @@ loop:
* to successfully wait until the child becomes a zombie.
*/
LIST_FOREACH(p, &q->p_orphans, p_orphan) {
- ret = proc_to_reap(td, p, pid, status, options, rusage);
+ ret = proc_to_reap(td, p, idtype, id, status, options,
+ wrusage, siginfo);
if (ret == 0)
continue;
else if (ret == 1)
@@ -994,7 +1225,7 @@ loop:
error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "wait", 0);
PROC_UNLOCK(q);
if (error)
- return (error);
+ return (error);
goto loop;
}
diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c
index ac625f7..f400041 100644
--- a/sys/kern/sys_procdesc.c
+++ b/sys/kern/sys_procdesc.c
@@ -374,7 +374,7 @@ procdesc_close(struct file *fp, struct thread *td)
*/
PROC_LOCK(p);
PROC_SLOCK(p);
- proc_reap(curthread, p, NULL, 0, NULL);
+ proc_reap(curthread, p, NULL, 0);
} else {
/*
* If the process is not yet dead, we need to kill it, but we
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 5cb90f8..148dea3 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -71,8 +71,7 @@
; XXX man page says `mode_t mode'.
6 AUE_CLOSE STD { int close(int fd); }
7 AUE_WAIT4 STD { int wait4(int pid, int *status, \
- int options, struct rusage *rusage); } \
- wait4 wait_args int
+ int options, struct rusage *rusage); }
8 AUE_CREAT COMPAT { int creat(char *path, int mode); }
9 AUE_LINK STD { int link(char *path, char *link); }
10 AUE_UNLINK STD { int unlink(char *path); }
@@ -952,5 +951,9 @@
off_t offset, off_t len); }
531 AUE_NULL STD { int posix_fadvise(int fd, off_t offset, \
off_t len, int advice); }
+532 AUE_WAIT6 STD { int wait6(int idtype, int id, \
+ int *status, int options, \
+ struct __wrusage *wrusage, \
+ siginfo_t *info); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 567cb63..ff92050 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -885,8 +885,7 @@ int proc_getenvv(struct thread *td, struct proc *p, struct sbuf *sb);
void procinit(void);
void proc_linkup0(struct proc *p, struct thread *td);
void proc_linkup(struct proc *p, struct thread *td);
-void proc_reap(struct thread *td, struct proc *p, int *status, int options,
- struct rusage *rusage);
+void proc_reap(struct thread *td, struct proc *p, int *status, int options);
void proc_reparent(struct proc *child, struct proc *newparent);
struct pstats *pstats_alloc(void);
void pstats_fork(struct pstats *src, struct pstats *dst);
diff --git a/sys/sys/resource.h b/sys/sys/resource.h
index c5e912b..89dc967 100644
--- a/sys/sys/resource.h
+++ b/sys/sys/resource.h
@@ -79,6 +79,13 @@ struct rusage {
#define ru_last ru_nivcsw
};
+#if __BSD_VISIBLE
+struct __wrusage {
+ struct rusage wru_self;
+ struct rusage wru_children;
+};
+#endif
+
/*
* Resource limits
*/
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index 4335550..48216a5 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -43,6 +43,7 @@ struct msghdr;
struct msqid_ds;
struct rlimit;
struct rusage;
+struct __wrusage;
union semun;
struct sockaddr;
struct stat;
@@ -234,6 +235,8 @@ int kern_utimesat(struct thread *td, int fd, char *path,
enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg);
int kern_wait(struct thread *td, pid_t pid, int *status, int options,
struct rusage *rup);
+int kern_wait6(struct thread *td, idtype_t idtype, id_t id, int *status,
+ int options, struct __wrusage *wrup, siginfo_t *sip);
int kern_writev(struct thread *td, int fd, struct uio *auio);
int kern_socketpair(struct thread *td, int domain, int type, int protocol,
int *rsv);
diff --git a/sys/sys/types.h b/sys/sys/types.h
index 491e99d..bef30da 100644
--- a/sys/sys/types.h
+++ b/sys/sys/types.h
@@ -141,6 +141,46 @@ typedef __id_t id_t; /* can hold a uid_t or pid_t */
#define _ID_T_DECLARED
#endif
+#ifndef _IDTYPE_T_DECLARED
+
+typedef enum
+#if defined(__BSD_VISIBLE)
+ idtype /* pollutes XPG4.2 namespace */
+#endif
+ {
+ /*
+ * These names were mostly lifted from Solaris source code and
+ * still use Solaris style naming to avoid breaking any
+ * OpenSolaris code which has been ported to FreeBSD. There
+ * is no clear FreeBSD counterpart for all of the names, but
+ * some have a clear correspondence to FreeBSD entities.
+ */
+ P_PID, /* A process identifier. */
+ P_PPID, /* A parent process identifier. */
+ P_PGID, /* A process group identifier. */
+ P_SID, /* A session identifier. */
+ P_CID, /* A scheduling class identifier. */
+ P_UID, /* A user identifier. */
+ P_GID, /* A group identifier. */
+ P_ALL, /* All processes. */
+ P_LWPID, /* An LWP identifier. */
+ P_TASKID, /* A task identifier. */
+ P_PROJID, /* A project identifier. */
+ P_POOLID, /* A pool identifier. */
+ P_JAILID, /* A zone identifier. */
+ P_CTID, /* A (process) contract identifier. */
+ P_CPUID, /* CPU identifier. */
+ P_PSETID /* Processor set identifier */
+} idtype_t; /* The type of id_t we are using. */
+
+#if defined(__BSD_VISIBLE)
+#define P_ZONEID P_JAILID
+#endif
+
+#define _IDTYPE_T_DECLARED
+#endif
+
+
#ifndef _INO_T_DECLARED
typedef __ino_t ino_t; /* inode number */
#define _INO_T_DECLARED
diff --git a/sys/sys/wait.h b/sys/sys/wait.h
index 0e23c23..113429f 100644
--- a/sys/sys/wait.h
+++ b/sys/sys/wait.h
@@ -80,6 +80,9 @@
#define WSTOPPED WUNTRACED /* SUS compatibility */
#define WCONTINUED 4 /* Report a job control continued process. */
#define WNOWAIT 8 /* Poll only. Don't delete the proc entry. */
+#define WEXITED 16 /* Wait for exited processes. */
+#define WTRAPPED 32 /* Wait for a process to hit a trap or
+ a breakpoint. */
#if __BSD_VISIBLE
#define WLINUXCLONE 0x80000000 /* Wait for kthread spawned from linux_clone. */
@@ -87,6 +90,8 @@
/*
* Tokens for special values of the "pid" parameter to wait4.
+ * Extended struct __wrusage to collect rusage for both the target
+ * process and its children within one wait6() call.
*/
#if __BSD_VISIBLE
#define WAIT_ANY (-1) /* any process */
@@ -97,12 +102,19 @@
#include <sys/types.h>
__BEGIN_DECLS
+struct __siginfo;
pid_t wait(int *);
pid_t waitpid(pid_t, int *, int);
+#if __POSIX_VISIBLE >= 200112
+int waitid(idtype_t, id_t, struct __siginfo *, int);
+#endif
#if __BSD_VISIBLE
struct rusage;
+struct __wrusage;
pid_t wait3(int *, int, struct rusage *);
pid_t wait4(pid_t, int *, int, struct rusage *);
+pid_t wait6(idtype_t, id_t, int *, int, struct __wrusage *,
+ struct __siginfo *);
#endif
__END_DECLS
#endif /* !_KERNEL */
OpenPOWER on IntegriCloud