blob: 557d8f9163871be6abc6722b64cdc5e26337e3e5 [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 <zircon/syscalls.h>
#include <task-utils/get.h>
#include <task-utils/walker.h>
typedef struct {
zx_koid_t desired_koid;
zx_handle_t found_handle;
zx_obj_type_t found_type;
} get_task_ctx_t;
static zx_status_t common_callback(zx_obj_type_t type, get_task_ctx_t* ctx, zx_handle_t handle,
zx_koid_t koid) {
if (koid == ctx->desired_koid) {
zx_handle_t dup;
zx_status_t s = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &dup);
if (s != ZX_OK) {
return s;
}
ctx->found_handle = dup;
ctx->found_type = type;
return ZX_ERR_STOP;
}
return ZX_OK;
}
static zx_status_t job_callback(void* ctx, int depth, zx_handle_t handle, zx_koid_t koid,
zx_koid_t parent_koid) {
return common_callback(ZX_OBJ_TYPE_JOB, ctx, handle, koid);
}
static zx_status_t process_callback(void* ctx, int depth, zx_handle_t handle, zx_koid_t koid,
zx_koid_t parent_koid) {
return common_callback(ZX_OBJ_TYPE_PROCESS, ctx, handle, koid);
}
static zx_status_t thread_callback(void* ctx, int depth, zx_handle_t handle, zx_koid_t koid,
zx_koid_t parent_koid) {
return common_callback(ZX_OBJ_TYPE_THREAD, ctx, handle, koid);
}
zx_status_t get_task_by_koid(zx_koid_t koid, zx_obj_type_t* type, zx_handle_t* out) {
if (type == NULL || out == NULL) {
return ZX_ERR_INVALID_ARGS;
}
get_task_ctx_t ctx = {
.desired_koid = koid,
.found_handle = ZX_HANDLE_INVALID,
.found_type = ZX_OBJ_TYPE_NONE,
};
zx_status_t s = walk_root_job_tree(job_callback, process_callback, thread_callback, &ctx);
if (s == ZX_ERR_STOP) {
*type = ctx.found_type;
*out = ctx.found_handle;
return ZX_OK;
}
if (s == ZX_OK) {
// The callback would have returned ZX_ERR_STOP if it found anything.
return ZX_ERR_NOT_FOUND;
}
return s;
}