| // 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 |