blob: aad2a74c842fe1f5730b27269019587d24e85941 [file] [log] [blame]
// Copyright 2020 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/cpp/fidl.h>
#include <lib/fdio/fd.h>
#include <lib/procfs/cpp/internal/cwd.h>
#include <lib/vfs/cpp/internal/directory.h>
#include <utility>
namespace procfs {
namespace internal {
class CwdDir final : public vfs::internal::Directory {
public:
~CwdDir() override = default;
protected:
// |Node| implementation
zx_status_t Connect(uint32_t flags, zx::channel request, async_dispatcher_t* dispatcher) final {
// This implementation is slightly inefficient because we end up making an extra connection to
// the CWD. First, fdio_cwd_clone gives us a zx::channel with the same flags as the existing
// connection. Second, we call |Clone| to pass the requested |flags|.
//
// We could make this operation more efficient if we added an "async" variant of fdio_cwd_clone
// that let us pass in the desired |flags| and the request handle. However, that would require
// plumbing that variant through ZXIO as well, which seems unnecessarily complex for this use
// case.
//
// We do not want to cache the |cwd| on this object (e.g., by using vfs::RemoteDir) because
// the entry in procfs is supposed to update as the cwd for the process changes.
zx::channel cwd;
zx_status_t status = fdio_cwd_clone(cwd.reset_and_get_address());
if (status != ZX_OK) {
return status;
}
if (!cwd.is_valid()) {
return ZX_ERR_NOT_SUPPORTED;
}
fuchsia::io::DirectorySyncPtr cwd_dir;
cwd_dir.Bind(std::move(cwd));
return cwd_dir->Clone(flags, fidl::InterfaceRequest<fuchsia::io::Node>(std::move(request)));
}
// |Directory| implementation
zx_status_t Readdir(uint64_t offset, void* data, uint64_t len, uint64_t* out_offset,
uint64_t* out_actual) final {
return ZX_ERR_NOT_SUPPORTED;
}
vfs::NodeKind::Type GetKind() const final { return Directory::GetKind() | vfs::NodeKind::kRemote; }
};
std::unique_ptr<vfs::internal::Node> CreateCwd() {
return std::make_unique<CwdDir>();
}
} // namespace internal
} // namespace procfs