blob: 5576947447f6165fb53449c6a5ed4cf311ea54f2 [file] [log] [blame]
// Copyright 2018 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/developer/debug/debug_agent/zircon_binary_launcher.h"
#include <inttypes.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/io.h>
#include <zircon/processargs.h>
#include <utility>
#include "src/developer/debug/debug_agent/zircon_process_handle.h"
#include "src/lib/fxl/strings/string_printf.h"
namespace debug_agent {
ZirconBinaryLauncher::ZirconBinaryLauncher(fidl::UnownedClientEnd<fuchsia_io::Directory> svc_dir)
: builder_(svc_dir) {}
ZirconBinaryLauncher::~ZirconBinaryLauncher() = default;
debug::Status ZirconBinaryLauncher::Setup(const std::vector<std::string>& argv) {
if (zx_status_t status = builder_.LoadPath(argv[0]); status != ZX_OK) {
if (status == ZX_ERR_NOT_FOUND) {
// Rewrite this common error to provide a better message.
return debug::Status(debug::Status::kNotFound,
fxl::StringPrintf("The binary '%s' was not found.", argv[0].c_str()));
}
return debug::ZxStatus(status);
}
if (zx_status_t status = builder_.AddArgs(argv); status != ZX_OK) {
return debug::ZxStatus(status);
}
if (zx_status_t status = builder_.CloneJob(); status != ZX_OK) {
return debug::ZxStatus(status);
}
if (zx_status_t status = builder_.CloneNamespace(); status != ZX_OK) {
return debug::ZxStatus(status);
}
if (zx_status_t status = builder_.CloneEnvironment(); status != ZX_OK) {
return debug::ZxStatus(status);
}
stdio_handles_.out = AddStdioEndpoint(STDOUT_FILENO);
stdio_handles_.err = AddStdioEndpoint(STDERR_FILENO);
return debug::ZxStatus(builder_.Prepare(nullptr));
}
std::unique_ptr<ProcessHandle> ZirconBinaryLauncher::GetProcess() const {
zx::process process;
builder_.data().process().duplicate(ZX_RIGHT_SAME_RIGHTS, &process);
return std::make_unique<ZirconProcessHandle>(std::move(process));
}
debug::Status ZirconBinaryLauncher::Start() { return debug::ZxStatus(builder_.Start(nullptr)); }
zx::socket ZirconBinaryLauncher::AddStdioEndpoint(int fd) {
zx::socket local;
zx::socket target;
zx_status_t status = zx::socket::create(0, &local, &target);
if (status != ZX_OK)
return zx::socket();
builder_.AddHandle(PA_HND(PA_FD, fd), std::move(target));
return local;
}
StdioHandles ZirconBinaryLauncher::ReleaseStdioHandles() { return std::move(stdio_handles_); }
} // namespace debug_agent