blob: 73ce8738f4211f5886f11a9c811c92a9f691dc2c [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <task-utils/get.h>
#include <magenta/syscalls.h>
#include <task-utils/walker.h>
typedef struct {
mx_koid_t desired_koid;
mx_handle_t found_handle;
mx_obj_type_t found_type;
} get_task_ctx_t;
static mx_status_t common_callback(mx_obj_type_t type, get_task_ctx_t* ctx,
mx_handle_t handle, mx_koid_t koid) {
if (koid == ctx->desired_koid) {
mx_handle_t dup;
mx_status_t s = mx_handle_duplicate(handle, MX_RIGHT_SAME_RIGHTS, &dup);
if (s != MX_OK) {
return s;
}
ctx->found_handle = dup;
ctx->found_type = type;
return MX_ERR_STOP;
}
return MX_OK;
}
static mx_status_t job_callback(void* ctx, int depth, mx_handle_t handle,
mx_koid_t koid, mx_koid_t parent_koid) {
return common_callback(MX_OBJ_TYPE_JOB, ctx, handle, koid);
}
static mx_status_t process_callback(void* ctx, int depth, mx_handle_t handle,
mx_koid_t koid, mx_koid_t parent_koid) {
return common_callback(MX_OBJ_TYPE_PROCESS, ctx, handle, koid);
}
static mx_status_t thread_callback(void* ctx, int depth, mx_handle_t handle,
mx_koid_t koid, mx_koid_t parent_koid) {
return common_callback(MX_OBJ_TYPE_THREAD, ctx, handle, koid);
}
mx_status_t get_task_by_koid(mx_koid_t koid,
mx_obj_type_t* type, mx_handle_t* out) {
if (type == NULL || out == NULL) {
return MX_ERR_INVALID_ARGS;
}
get_task_ctx_t ctx = {
.desired_koid = koid,
.found_handle = MX_HANDLE_INVALID,
.found_type = MX_OBJ_TYPE_NONE,
};
mx_status_t s = walk_root_job_tree(
job_callback, process_callback, thread_callback, &ctx);
if (s == MX_ERR_STOP) {
*type = ctx.found_type;
*out = ctx.found_handle;
return MX_OK;
}
if (s == MX_OK) {
// The callback would have returned MX_ERR_STOP if it found anything.
return MX_ERR_NOT_FOUND;
}
return s;
}