+ return task;
+}
+
+/*
+ * Routine: convert_port_to_task_check_type
+ * Purpose:
+ * Convert from a port to a task based on port's type.
+ * Doesn't consume the port ref; produces a task ref,
+ * which may be null.
+ * Arguments:
+ * port: The port that we do conversion on
+ * kotype: Returns the IKOT_TYPE of the port, if translation succeeded
+ * at_most: The lowest capability flavor allowed. In mach_task_flavor_t,
+ * the higher the flavor number, the lesser the capability, hence the name.
+ * eval_check: Whether to run task_conversion_eval check during the conversion.
+ * For backward compatibility, some interfaces does not run conversion
+ * eval on IKOT_TASK_CONTROL.
+ * Conditions:
+ * Nothing locked.
+ * Returns:
+ * task_t and port's type, if translation succeeded;
+ * TASK_NULL and IKOT_NONE, if translation failed
+ */
+task_t
+convert_port_to_task_check_type(
+ ipc_port_t port,
+ ipc_kobject_type_t *kotype,
+ mach_task_flavor_t at_most,
+ boolean_t eval_check)
+{
+ task_t task = TASK_NULL;
+ ipc_kobject_type_t type = IKOT_NONE;
+
+ if (!IP_VALID(port) || !ip_active(port)) {
+ goto out;
+ }
+
+ switch (ip_kotype(port)) {
+ case IKOT_TASK_CONTROL:
+ task = eval_check ? convert_port_to_task(port) : convert_port_to_task_no_eval(port);
+ if (task != TASK_NULL) {
+ type = IKOT_TASK_CONTROL;
+ }
+ break;
+ case IKOT_TASK_READ:
+ if (at_most >= TASK_FLAVOR_READ) {
+ task = eval_check ? convert_port_to_task_read(port) : convert_port_to_task_read_no_eval(port);
+ if (task != TASK_READ_NULL) {
+ type = IKOT_TASK_READ;
+ }
+ }
+ break;
+ case IKOT_TASK_INSPECT:
+ if (at_most >= TASK_FLAVOR_INSPECT) {
+ task = convert_port_to_task_inspect(port);
+ if (task != TASK_INSPECT_NULL) {
+ type = IKOT_TASK_INSPECT;
+ }
+ }
+ break;
+ case IKOT_TASK_NAME:
+ if (at_most >= TASK_FLAVOR_NAME) {
+ task = convert_port_to_task_name(port);
+ if (task != TASK_NAME_NULL) {
+ type = IKOT_TASK_NAME;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+out:
+ if (kotype) {
+ *kotype = type;
+ }
+ return task;
+}
+
+/*
+ * Routine: convert_port_to_thread_check_type
+ * Purpose:
+ * Convert from a port to a thread based on port's type.
+ * Doesn't consume the port ref; produces a thread ref,
+ * which may be null.
+ * This conversion routine is _ONLY_ supposed to be used
+ * by thread_get_special_port.
+ * Arguments:
+ * port: The port that we do conversion on
+ * kotype: Returns the IKOT_TYPE of the port, if translation succeeded
+ * at_most: The lowest capability flavor allowed. In mach_thread_flavor_t,
+ * the higher the flavor number, the lesser the capability, hence the name.
+ * eval_check: Whether to run task_conversion_eval check during the conversion.
+ * For backward compatibility, some interfaces do not run
+ * conversion eval on IKOT_THREAD_CONTROL.
+ * Conditions:
+ * Nothing locked.
+ * Returns:
+ * thread_t and port's type, if translation succeeded;
+ * THREAD_NULL and IKOT_NONE, if translation failed
+ */
+thread_t
+convert_port_to_thread_check_type(
+ ipc_port_t port,
+ ipc_kobject_type_t *kotype,
+ mach_thread_flavor_t at_most,
+ boolean_t eval_check)
+{
+ thread_t thread = THREAD_NULL;
+ ipc_kobject_type_t type = IKOT_NONE;
+
+ if (!IP_VALID(port) || !ip_active(port)) {
+ goto out;
+ }
+
+ switch (ip_kotype(port)) {
+ case IKOT_THREAD_CONTROL:
+ thread = eval_check ? convert_port_to_thread(port) : convert_port_to_thread_no_eval(port);
+ if (thread != THREAD_NULL) {
+ type = IKOT_THREAD_CONTROL;
+ }
+ break;
+ case IKOT_THREAD_READ:
+ if (at_most >= THREAD_FLAVOR_READ) {
+ thread = eval_check ? convert_port_to_thread_read(port) : convert_port_to_thread_read_no_eval(port);
+ if (thread != THREAD_READ_NULL) {
+ type = IKOT_THREAD_READ;
+ }
+ }
+ break;
+ case IKOT_THREAD_INSPECT:
+ if (at_most >= THREAD_FLAVOR_INSPECT) {
+ thread = convert_port_to_thread_inspect(port);
+ if (thread != THREAD_INSPECT_NULL) {
+ type = IKOT_THREAD_INSPECT;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+out:
+ if (kotype) {
+ *kotype = type;
+ }
+ return thread;
+}
+
+/*
+ * Routine: convert_port_to_space_check_type
+ * Purpose:
+ * Convert from a port to a space based on port's type.
+ * Doesn't consume the port ref; produces a space ref,
+ * which may be null.
+ * Arguments:
+ * port: The port that we do conversion on
+ * kotype: Returns the IKOT_TYPE of the port, if translation succeeded
+ * at_most: The lowest capability flavor allowed. In mach_task_flavor_t,
+ * the higher the flavor number, the lesser the capability, hence the name.
+ * eval_check: Whether to run task_conversion_eval check during the conversion.
+ * For backward compatibility, some interfaces do not run
+ * conversion eval on IKOT_TASK_CONTROL.
+ * Conditions:
+ * Nothing locked.
+ * Returns:
+ * ipc_space_t and port's type, if translation succeeded;
+ * IPC_SPACE_NULL and IKOT_NONE, if translation failed
+ */
+ipc_space_t
+convert_port_to_space_check_type(
+ ipc_port_t port,
+ ipc_kobject_type_t *kotype,
+ mach_task_flavor_t at_most,
+ boolean_t eval_check)
+{
+ ipc_space_t space = IPC_SPACE_NULL;
+ ipc_kobject_type_t type = IKOT_NONE;
+
+ if (!IP_VALID(port) || !ip_active(port)) {
+ goto out;
+ }
+
+ switch (ip_kotype(port)) {
+ case IKOT_TASK_CONTROL:
+ space = eval_check ? convert_port_to_space(port) : convert_port_to_space_no_eval(port);
+ if (space != IPC_SPACE_NULL) {
+ type = IKOT_TASK_CONTROL;
+ }
+ break;
+ case IKOT_TASK_READ:
+ if (at_most >= TASK_FLAVOR_READ) {
+ space = eval_check ? convert_port_to_space_read(port) : convert_port_to_space_read_no_eval(port);
+ if (space != IPC_SPACE_READ_NULL) {
+ type = IKOT_TASK_READ;
+ }
+ }
+ break;
+ case IKOT_TASK_INSPECT:
+ if (at_most >= TASK_FLAVOR_INSPECT) {
+ space = convert_port_to_space_inspect(port);
+ if (space != IPC_SPACE_INSPECT_NULL) {
+ type = IKOT_TASK_INSPECT;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+out:
+ if (kotype) {
+ *kotype = type;
+ }