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