| // 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/cpp/fidl.h> |
| #include <lib/async-loop/cpp/loop.h> |
| #include <lib/async-loop/default.h> |
| #include <lib/memfs/memfs.h> |
| #include <lib/svc/outgoing.h> |
| #include <lib/zx/channel.h> |
| |
| #include <fs/remote_dir.h> |
| |
| int main(int argc, char* argv[]) { |
| async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread); |
| |
| async::Loop memfs_loop(&kAsyncLoopConfigNoAttachToCurrentThread); |
| if (memfs_loop.StartThread() != ZX_OK) { |
| fprintf(stderr, "Failed to start memfs loop\n"); |
| return -1; |
| } |
| |
| memfs_filesystem_t* vfs; |
| zx::channel memfs_channel; |
| zx_status_t status = |
| memfs_create_filesystem(memfs_loop.dispatcher(), &vfs, memfs_channel.reset_and_get_address()); |
| if (status != ZX_OK) { |
| fprintf(stderr, "Failed to create memfs: %d\n", status); |
| return -1; |
| } |
| |
| fidl::InterfacePtr<fuchsia::io::Directory> memfs_dir; |
| memfs_dir.Bind(std::move(memfs_channel)); |
| |
| fidl::InterfaceHandle<fuchsia::io::Node> ro_dir; |
| fidl::InterfaceHandle<fuchsia::io::Node> rw_dir; |
| fidl::InterfaceHandle<fuchsia::io::Node> rx_dir; |
| fidl::InterfaceHandle<fuchsia::io::Node> ra_dir; |
| fidl::InterfaceHandle<fuchsia::io::Node> r_after_scoped_dir; |
| |
| memfs_dir->Clone(fuchsia::io::OPEN_RIGHT_READABLE, ro_dir.NewRequest()); |
| memfs_dir->Clone(fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE, |
| rw_dir.NewRequest()); |
| memfs_dir->Clone(fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_EXECUTABLE, |
| rx_dir.NewRequest()); |
| memfs_dir->Clone(fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_ADMIN, |
| ra_dir.NewRequest()); |
| memfs_dir->Clone(fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE, |
| r_after_scoped_dir.NewRequest()); |
| |
| // TODO(fxbug.dev/37773): We can't use sys::ComponentContext/vfs::PseudoDir/vfs::RemoteDir here |
| // because of a bug in how they handle OPEN_FLAG_POSIX. |
| svc::Outgoing outgoing(loop.dispatcher()); |
| outgoing.root_dir()->AddEntry("read_only", |
| fbl::MakeRefCounted<fs::RemoteDir>(ro_dir.TakeChannel())); |
| outgoing.root_dir()->AddEntry("read_write", |
| fbl::MakeRefCounted<fs::RemoteDir>(rw_dir.TakeChannel())); |
| outgoing.root_dir()->AddEntry("read_exec", |
| fbl::MakeRefCounted<fs::RemoteDir>(rx_dir.TakeChannel())); |
| outgoing.root_dir()->AddEntry("read_admin", |
| fbl::MakeRefCounted<fs::RemoteDir>(ra_dir.TakeChannel())); |
| outgoing.root_dir()->AddEntry("read_only_after_scoped", fbl::MakeRefCounted<fs::RemoteDir>( |
| r_after_scoped_dir.TakeChannel())); |
| status = outgoing.ServeFromStartupInfo(); |
| if (status != ZX_OK) { |
| fprintf(stderr, "Failed to serve outgoing dir: %d\n", status); |
| return -1; |
| } |
| |
| loop.Run(); |
| memfs_free_filesystem(vfs, nullptr); |
| return 0; |
| } |