kern_return_t ipc_object_translate( ipc_space_t space, mach_port_name_t name, mach_port_right_t right, ipc_object_t *objectp) { ipc_entry_t entry; ipc_object_t object; kern_return_t kr; kr = ipc_right_lookup_read(space, name, &entry); if (kr != KERN_SUCCESS) return kr; /* space is read-locked and active */ if ((entry->ie_bits & MACH_PORT_TYPE(right)) == MACH_PORT_TYPE_NONE) { is_read_unlock(space); return KERN_INVALID_RIGHT; } object = entry->ie_object; assert(object != IO_NULL); io_lock(object); is_read_unlock(space); *objectp = object; return KERN_SUCCESS; }
kern_return_t ipc_object_translate_two( ipc_space_t space, mach_port_name_t name1, mach_port_right_t right1, ipc_object_t *objectp1, mach_port_name_t name2, mach_port_right_t right2, ipc_object_t *objectp2) { ipc_entry_t entry1; ipc_entry_t entry2; ipc_object_t object; kern_return_t kr; kr = ipc_right_lookup_two_read(space, name1, &entry1, name2, &entry2); if (kr != KERN_SUCCESS) return kr; /* space is read-locked and active */ if ((entry1->ie_bits & MACH_PORT_TYPE(right1)) == MACH_PORT_TYPE_NONE) { is_read_unlock(space); return KERN_INVALID_RIGHT; } if ((entry2->ie_bits & MACH_PORT_TYPE(right2)) == MACH_PORT_TYPE_NONE) { is_read_unlock(space); return KERN_INVALID_RIGHT; } object = entry1->ie_object; assert(object != IO_NULL); io_lock(object); *objectp1 = object; object = entry2->ie_object; assert(object != IO_NULL); io_lock(object); *objectp2 = object; is_read_unlock(space); return KERN_SUCCESS; }
static kern_return_t PrintProcessPortSpace(pid_t pid, bool verbose) // Prints port rights owned by the specified process. { kern_return_t err; kern_return_t junk; mach_port_t taskSendRight; mach_port_name_array_t rightNames; mach_msg_type_number_t rightNamesCount; mach_port_type_array_t rightTypes; mach_msg_type_number_t rightTypesCount; unsigned int i; taskSendRight = MACH_PORT_NULL; rightNames = NULL; rightTypes = NULL; // Get the task control port for the process. err = task_for_pid(mach_task_self(), pid, &taskSendRight); if (err != KERN_SUCCESS) { fprintf(stderr, "%s: Could not attach to process %lld (%#08x).\n", gProgramName, (long long) pid, err); } // Get a snapshot of the port name space for the task. if (err == KERN_SUCCESS) { err = mach_port_names(taskSendRight, &rightNames, &rightNamesCount, &rightTypes, &rightTypesCount); } if (err == KERN_SUCCESS) { if ( rightNamesCount != rightTypesCount ) { fprintf(stderr, "%s: Count mismatch (%u/%u)\n", gProgramName, rightNamesCount, rightTypesCount); err = KERN_FAILURE; } } // Print that snapshot. if (err == KERN_SUCCESS) { fprintf(stdout, " Name Send Receive SendOnce PortSet DeadName DNR"); if (verbose) { fprintf(stdout, " flg seqno mscount qlimit msgcount sorights pset"); } fprintf(stdout, "\n"); fprintf(stdout, " ---- ---- ------- -------- ------- -------- ---"); if (verbose) { fprintf(stdout, " --- ----- ------- ------ -------- -------- ----"); } fprintf(stdout, "\n"); // For each name, print a reference count of each type of right. If running // verbose, print other information as well. for (i = 0; i < rightNamesCount; i++) { mach_port_right_t right; // We print the right name in hex because it makes it easier to // see the index and generation fields. See <mach/port.h> for // information about this. fprintf(stdout, "%#8x ", rightNames[i]); for (right = MACH_PORT_RIGHT_SEND; right <= MACH_PORT_RIGHT_DEAD_NAME; right++) { mach_port_urefs_t refCount; // If the rightTypes for this name has the bit associated // with this type of right set (that is, if the name // references this type of right), get the name's reference // for this right and print it. Otherwise just print an // empty string to keep the columns lined up. if (rightTypes[i] & MACH_PORT_TYPE(right)) { err = mach_port_get_refs(taskSendRight, rightNames[i], right, &refCount); if (err == KERN_SUCCESS) { fprintf(stdout, "%8d ", refCount); } else { fprintf(stdout, "%8s ", "???"); } } else { fprintf(stdout, "%8s ", ""); } } if ( rightTypes[i] & MACH_PORT_TYPE_DNREQUEST ) { fprintf(stdout, "yes "); } else { fprintf(stdout, " "); } if (verbose) { if (rightTypes[i] & MACH_PORT_TYPE_PORT_SET) { PrintPortSetMembers(taskSendRight, rightNames[i]); } else if (rightTypes[i] & MACH_PORT_TYPE_RECEIVE) { PrintPortReceiveStatus(taskSendRight, rightNames[i]); } } fprintf(stdout, "\n"); } } // Clean up. if (rightNames != NULL) { junk = vm_deallocate(mach_task_self(), (vm_address_t) rightNames, rightNamesCount * sizeof(*rightNames)); assert(junk == KERN_SUCCESS); } if (rightTypes != NULL) { junk = vm_deallocate(mach_task_self(), (vm_address_t) rightTypes, rightTypesCount * sizeof(*rightTypes)); assert(junk == KERN_SUCCESS); } if (taskSendRight != MACH_PORT_NULL) { junk = mach_port_deallocate(mach_task_self(), taskSendRight); assert(junk == KERN_SUCCESS); } return err; }
kern_return_t mach_port_get_refs( ipc_space_t space, mach_port_name_t name, mach_port_right_t right, mach_port_urefs_t *urefsp) { mach_port_type_t type; mach_port_urefs_t urefs; ipc_entry_t entry; kern_return_t kr; if (space == IS_NULL) return KERN_INVALID_TASK; if (right >= MACH_PORT_RIGHT_NUMBER) return KERN_INVALID_VALUE; if (!MACH_PORT_VALID(name)) { if (right == MACH_PORT_RIGHT_SEND || right == MACH_PORT_RIGHT_SEND_ONCE) { *urefsp = 1; return KERN_SUCCESS; } return KERN_INVALID_NAME; } kr = ipc_right_lookup_write(space, name, &entry); if (kr != KERN_SUCCESS) return kr; /* space is write-locked and active */ kr = ipc_right_info(space, name, entry, &type, &urefs); /* unlocks */ if (kr != KERN_SUCCESS) return kr; /* space is unlocked */ is_write_unlock(space); if (type & MACH_PORT_TYPE(right)) switch (right) { case MACH_PORT_RIGHT_SEND_ONCE: assert(urefs == 1); /* fall-through */ case MACH_PORT_RIGHT_PORT_SET: case MACH_PORT_RIGHT_RECEIVE: *urefsp = 1; break; case MACH_PORT_RIGHT_DEAD_NAME: case MACH_PORT_RIGHT_SEND: assert(urefs > 0); *urefsp = urefs; break; default: panic("mach_port_get_refs: strange rights"); } else *urefsp = 0; return kr; }