blob: 3c81d87bc22f9669f12f1abb1668c5bf97455a74 [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 <fuchsia/io/llcpp/fidl.h>
#include <lib/async/default.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/vfs.h>
#include <zircon/status.h>
#include <string>
#include <string_view>
#include <runtests-utils/service-proxy-dir.h>
namespace fio = fuchsia_io;
namespace runtests {
ServiceProxyDir::ServiceProxyDir(zx::channel proxy_dir) : proxy_dir_(std::move(proxy_dir)) {}
void ServiceProxyDir::AddEntry(std::string name, fbl::RefPtr<fs::Vnode> node) {
entries_[name] = node;
}
zx_status_t ServiceProxyDir::GetAttributes(fs::VnodeAttributes* attr) {
*attr = fs::VnodeAttributes();
attr->mode = V_TYPE_DIR | V_IRUSR;
attr->inode = fio::wire::kInoUnknown;
attr->link_count = 1;
return ZX_OK;
}
zx_status_t ServiceProxyDir::GetNodeInfoForProtocol([[maybe_unused]] fs::VnodeProtocol protocol,
[[maybe_unused]] fs::Rights rights,
fs::VnodeRepresentation* info) {
*info = fs::VnodeRepresentation::Directory();
return ZX_OK;
}
fs::VnodeProtocolSet ServiceProxyDir::GetProtocols() const { return fs::VnodeProtocol::kDirectory; }
zx_status_t ServiceProxyDir::Lookup(std::string_view name, fbl::RefPtr<fs::Vnode>* out) {
std::unique_lock lock(lock_);
auto entry_name = std::string(name.data(), name.length());
auto entry = entries_.find(entry_name);
if (entry != entries_.end()) {
*out = entry->second;
return ZX_OK;
}
entries_.emplace(entry_name,
*out = fbl::MakeRefCounted<fs::Service>([this, entry_name](zx::channel request) {
return fidl::WireCall<fio::Directory>(zx::unowned_channel(proxy_dir_))
.Open(fio::wire::kOpenRightReadable | fio::wire::kOpenRightWritable, 0755,
fidl::StringView::FromExternal(entry_name), std::move(request))
.status();
}));
return ZX_OK;
}
} // namespace runtests