blob: 14854ca95e94f590bc4550fa5a73f12f456be9ec [file] [log] [blame]
// Copyright 2026 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 "src/lib/dso/cpp/async.h"
#include <string.h>
#include <zircon/compiler.h>
#include <zircon/processargs.h>
extern "C" struct dso_async_input {
uint32_t handle_count;
zx_handle_t* handle;
uint32_t* handle_info;
uint32_t name_count;
const char** names;
int argc;
const char** argv;
const char** envp;
fdf_dispatcher_t* dispatcher;
};
typedef struct dso_async_input dso_async_input_t;
#define TAKE_HANDLE(_name_) \
_name_ = input.handle[n]; \
input.handle_info[n] = ZX_HANDLE_INVALID; \
input.handle[n] = ZX_HANDLE_INVALID;
__EXPORT
extern "C" int _dso_start_async(dso_async_input_t input) {
// Capture handles that we want to pass to dso_main() directly.
zx_handle_t svc = ZX_HANDLE_INVALID;
zx_handle_t pkg = ZX_HANDLE_INVALID;
zx_handle_t directory_request = ZX_HANDLE_INVALID;
zx_handle_t lifecycle = ZX_HANDLE_INVALID;
zx_handle_t config = ZX_HANDLE_INVALID;
for (uint32_t n = 0; n < input.handle_count; ++n) {
const unsigned arg = PA_HND_ARG(input.handle_info[n]);
switch (PA_HND_TYPE(input.handle_info[n])) {
case PA_NS_DIR:
if (arg < input.name_count) {
if (strcmp(input.names[arg], "/svc") == 0) {
TAKE_HANDLE(svc)
}
if (strcmp(input.names[arg], "/pkg") == 0) {
TAKE_HANDLE(pkg)
}
}
break;
case PA_DIRECTORY_REQUEST:
TAKE_HANDLE(directory_request)
break;
case PA_LIFECYCLE:
TAKE_HANDLE(lifecycle)
break;
case PA_VMO_COMPONENT_CONFIG:
TAKE_HANDLE(config)
break;
default:
continue;
}
}
return dso_main_async(input.argc, input.argv, input.envp, svc, pkg, directory_request, lifecycle,
config, input.dispatcher);
}