blob: a3c769fb94d4f764a00c9a6cedbeedb36931dab8 [file] [log] [blame]
// Copyright 2019 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 <lib/fdio/directory.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/zx/channel.h>
namespace sys {
namespace {
zx::channel OpenServiceRoot() {
zx::channel request, service_root;
if (zx::channel::create(0, &request, &service_root) != ZX_OK)
return zx::channel();
if (fdio_service_connect("/svc/.", request.release()) != ZX_OK)
return zx::channel();
return service_root;
}
} // namespace
ServiceDirectory::ServiceDirectory(zx::channel directory) : directory_(std::move(directory)) {}
ServiceDirectory::ServiceDirectory(fidl::InterfaceHandle<fuchsia::io::Directory> directory)
: ServiceDirectory(directory.TakeChannel()) {}
ServiceDirectory::~ServiceDirectory() = default;
std::shared_ptr<ServiceDirectory> ServiceDirectory::CreateFromNamespace() {
return std::make_shared<ServiceDirectory>(OpenServiceRoot());
}
std::shared_ptr<ServiceDirectory> ServiceDirectory::CreateWithRequest(zx::channel* out_request) {
zx::channel directory;
// no need to check status, even if this fails, service directory would be
// backed by invalid channel and Connect will return correct error.
zx::channel::create(0, &directory, out_request);
return std::make_shared<ServiceDirectory>(ServiceDirectory(std::move(directory)));
}
std::shared_ptr<ServiceDirectory> ServiceDirectory::CreateWithRequest(
fidl::InterfaceRequest<fuchsia::io::Directory>* out_request) {
zx::channel request;
auto directory = CreateWithRequest(&request);
out_request->set_channel(std::move(request));
return directory;
}
zx_status_t ServiceDirectory::Connect(const std::string& interface_name,
zx::channel channel) const {
return fdio_service_connect_at(directory_.get(), interface_name.c_str(), channel.release());
}
fidl::InterfaceHandle<fuchsia::io::Directory> ServiceDirectory::CloneChannel() const {
fidl::InterfaceHandle<fuchsia::io::Directory> dir;
CloneChannel(dir.NewRequest());
return dir;
}
zx_status_t ServiceDirectory::CloneChannel(
fidl::InterfaceRequest<fuchsia::io::Directory> dir) const {
return fdio_service_clone_to(directory_.get(), dir.TakeChannel().release());
}
} // namespace sys