+ /* Check if we need to look for zombies */
+ if ((flavor == PROC_PIDTBSDINFO) || (flavor == PROC_PIDT_SHORTBSDINFO) || (flavor == PROC_PIDT_BSDINFOWITHUNIQID)
+ || (flavor == PROC_PIDUNIQIDENTIFIERINFO)) {
+ if (arg) {
+ findzomb = 1;
+ }
+ }
+
+ if ((p = proc_find(pid)) == PROC_NULL) {
+ if (findzomb) {
+ p = proc_find_zombref(pid);
+ }
+ if (p == PROC_NULL) {
+ error = ESRCH;
+ goto out;
+ }
+ zombie = 1;
+ } else {
+ gotref = 1;
+ }
+
+ /* Certain operations don't require privileges */
+ switch (flavor) {
+ case PROC_PIDT_SHORTBSDINFO:
+ case PROC_PIDUNIQIDENTIFIERINFO:
+ case PROC_PIDPATHINFO:
+ case PROC_PIDCOALITIONINFO:
+ case PROC_PIDPLATFORMINFO:
+ check_same_user = NO_CHECK_SAME_USER;
+ break;
+ default:
+ check_same_user = CHECK_SAME_USER;
+ break;
+ }
+
+ /* Do we have permission to look into this? */
+ if ((error = proc_security_policy(p, PROC_INFO_CALL_PIDINFO, flavor, check_same_user))) {
+ goto out;
+ }
+
+ switch (flavor) {
+ case PROC_PIDLISTFDS: {
+ error = proc_pidfdlist(p, buffer, buffersize, retval);
+ }
+ break;
+
+ case PROC_PIDUNIQIDENTIFIERINFO: {
+ struct proc_uniqidentifierinfo p_uniqidinfo;
+ bzero(&p_uniqidinfo, sizeof(p_uniqidinfo));
+ proc_piduniqidentifierinfo(p, &p_uniqidinfo);
+ error = copyout(&p_uniqidinfo, buffer, sizeof(struct proc_uniqidentifierinfo));
+ if (error == 0) {
+ *retval = sizeof(struct proc_uniqidentifierinfo);
+ }
+ }
+ break;
+
+ case PROC_PIDT_SHORTBSDINFO:
+ shortversion = 1;
+ case PROC_PIDT_BSDINFOWITHUNIQID:
+ case PROC_PIDTBSDINFO: {
+ struct proc_bsdinfo pbsd;
+ struct proc_bsdshortinfo pbsd_short;
+ struct proc_bsdinfowithuniqid pbsd_uniqid;
+
+ if (flavor == PROC_PIDT_BSDINFOWITHUNIQID) {
+ uniqidversion = 1;
+ }
+
+ if (shortversion != 0) {
+ error = proc_pidshortbsdinfo(p, &pbsd_short, zombie);
+ } else {
+ error = proc_pidbsdinfo(p, &pbsd, zombie);
+ if (uniqidversion != 0) {
+ bzero(&pbsd_uniqid, sizeof(pbsd_uniqid));
+ proc_piduniqidentifierinfo(p, &pbsd_uniqid.p_uniqidentifier);
+ pbsd_uniqid.pbsd = pbsd;
+ }
+ }
+
+ if (error == 0) {
+ if (shortversion != 0) {
+ error = copyout(&pbsd_short, buffer, sizeof(struct proc_bsdshortinfo));
+ if (error == 0) {
+ *retval = sizeof(struct proc_bsdshortinfo);
+ }
+ } else if (uniqidversion != 0) {
+ error = copyout(&pbsd_uniqid, buffer, sizeof(struct proc_bsdinfowithuniqid));
+ if (error == 0) {
+ *retval = sizeof(struct proc_bsdinfowithuniqid);
+ }
+ } else {
+ error = copyout(&pbsd, buffer, sizeof(struct proc_bsdinfo));
+ if (error == 0) {
+ *retval = sizeof(struct proc_bsdinfo);
+ }
+ }
+ }
+ }
+ break;
+
+ case PROC_PIDTASKINFO: {
+ struct proc_taskinfo ptinfo;
+
+ error = proc_pidtaskinfo(p, &ptinfo);
+ if (error == 0) {
+ error = copyout(&ptinfo, buffer, sizeof(struct proc_taskinfo));