+
+int
+proc_pid_rusage(int pid, int flavor, user_addr_t buffer, __unused int32_t *retval)
+{
+ proc_t p;
+ int error;
+ int zombie = 0;
+
+ if ((p = proc_find(pid)) == PROC_NULL) {
+ if ((p = proc_find_zombref(pid)) == PROC_NULL) {
+ return (ESRCH);
+ }
+ zombie = 1;
+ }
+
+ /* Do we have permission to look into this? */
+ if ((error = proc_security_policy(p, PROC_INFO_CALL_PIDRUSAGE, flavor, CHECK_SAME_USER)))
+ goto out;
+
+ error = proc_get_rusage(p, flavor, buffer, zombie);
+
+out:
+ if (zombie)
+ proc_drop_zombref(p);
+ else
+ proc_rele(p);
+
+ return (error);
+}
+
+void
+proc_archinfo(proc_t p, struct proc_archinfo *pai)
+{
+ proc_lock(p);
+ pai->p_cputype = p->p_cputype;
+ pai->p_cpusubtype = p->p_cpusubtype;
+ proc_unlock(p);
+}
+
+void
+proc_pidcoalitioninfo(proc_t p, struct proc_pidcoalitioninfo *ppci)
+{
+ bzero(ppci, sizeof(*ppci));
+ ppci->coalition_id = proc_coalitionid(p);
+}
+
+
+
+/*
+ * Wrapper to provide NOTE_EXIT_DETAIL and NOTE_EXITSTATUS
+ * It mimics the data that is typically captured by the
+ * EVFILT_PROC, NOTE_EXIT event mechanism.
+ * See filt_proc() in kern_event.c.
+ */
+int
+proc_pidnoteexit(proc_t p, uint64_t flags, uint32_t *data)
+{
+ uint32_t exit_data = 0;
+ uint32_t exit_flags = (uint32_t)flags;
+
+ proc_lock(p);
+
+ /*
+ * Allow access to the parent of the exiting
+ * child or the parent debugger only.
+ */
+ do {
+ pid_t selfpid = proc_selfpid();
+
+ if (p->p_ppid == selfpid)
+ break; /* parent => ok */
+
+ if ((p->p_lflag & P_LTRACED) != 0 &&
+ (p->p_oppid == selfpid))
+ break; /* parent-in-waiting => ok */
+
+ proc_unlock(p);
+ return (EACCES);
+ } while (0);
+
+ if ((exit_flags & NOTE_EXITSTATUS) != 0) {
+ /* The signal and exit status */
+ exit_data |= (p->p_xstat & NOTE_PDATAMASK);
+ }
+
+ if ((exit_flags & NOTE_EXIT_DETAIL) != 0) {
+ /* The exit detail */
+ if ((p->p_lflag & P_LTERM_DECRYPTFAIL) != 0) {
+ exit_data |= NOTE_EXIT_DECRYPTFAIL;
+ }
+
+ if ((p->p_lflag & P_LTERM_JETSAM) != 0) {
+ exit_data |= NOTE_EXIT_MEMORY;
+
+ switch (p->p_lflag & P_JETSAM_MASK) {
+ case P_JETSAM_VMPAGESHORTAGE:
+ exit_data |= NOTE_EXIT_MEMORY_VMPAGESHORTAGE;
+ break;
+ case P_JETSAM_VMTHRASHING:
+ exit_data |= NOTE_EXIT_MEMORY_VMTHRASHING;
+ break;
+ case P_JETSAM_FCTHRASHING:
+ exit_data |= NOTE_EXIT_MEMORY_FCTHRASHING;
+ break;
+ case P_JETSAM_VNODE:
+ exit_data |= NOTE_EXIT_MEMORY_VNODE;
+ break;
+ case P_JETSAM_HIWAT:
+ exit_data |= NOTE_EXIT_MEMORY_HIWAT;
+ break;
+ case P_JETSAM_PID:
+ exit_data |= NOTE_EXIT_MEMORY_PID;
+ break;
+ case P_JETSAM_IDLEEXIT:
+ exit_data |= NOTE_EXIT_MEMORY_IDLE;
+ break;
+ }
+ }
+
+ if ((p->p_csflags & CS_KILLED) != 0) {
+ exit_data |= NOTE_EXIT_CSERROR;
+ }
+ }
+
+ proc_unlock(p);
+
+ *data = exit_data;
+
+ return (0);
+}
+