Skip to content

Commit

Permalink
test read-only fs
Browse files Browse the repository at this point in the history
  • Loading branch information
lesomnus committed Jul 29, 2023
1 parent 97ba703 commit 3c32f29
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 288 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ int main(int argc, char* argv[]) {
- `vfs::make_vfs` Basic file system.
- `vfs::make_mem_fs` Files are stored on the memory.
- `vfs::make_union_fs` Provides a single coherent file system over multiple file systems.
- `vfs::make_read_only_fs` Makes the given file system read-only.
### Utilities
- `vfs::Fs::change_root` Changes the root directory.
Expand Down
10 changes: 8 additions & 2 deletions include/vfs/fs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1156,21 +1156,27 @@ std::shared_ptr<Fs> make_os_fs();
/**
* @brief Makes empty `Fs` that is virtual. Regular files are written to the temporary directory of the OS and are deleted when the `Fs` is destructed.
*
* @param temp_dir Path to the temporary directory in the created Fs.
* @param temp_dir Path to the temporary directory in the created `Fs`.
* @return New empty `Fs` that is virtual.
*/
std::shared_ptr<Fs> make_vfs(std::filesystem::path const& temp_dir = "/tmp");

/**
* @brief Makes empty `Fs` that is virtual. Regular files are stored on the memory.
*
* @param temp_dir Path to the temporary directory in the created Fs.
* @param temp_dir Path to the temporary directory in the created `Fs`.
* @return New empty `Fs` that is virtual.
*/
std::shared_ptr<Fs> make_mem_fs(std::filesystem::path const& temp_dir = "/tmp");

std::shared_ptr<Fs> make_union_fs(Fs& upper, Fs const& lower);

/**
* @brief Makes `Fs` read-only. Non-const methods of resulting `Fs` throw `std::filesystem::filesystem_error` with `std::errc::read_only_file_system`.
*
* @param fs `Fs` to make read-only.
* @return `Fs` that is the same as the given `Fs` but read-only.
*/
std::shared_ptr<Fs> make_read_only_fs(Fs const& fs);

} // namespace vfs
141 changes: 141 additions & 0 deletions internal/vfs/impl/fs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,155 @@
#include <type_traits>

#include "vfs/impl/file.hpp"
#include "vfs/impl/utils.hpp"

#include "vfs/fs.hpp"

#define VFS_FS_METHOD_NAMES \
Fs::canonical, \
Fs::weakly_canonical, \
Fs::copy, \
Fs::copy_file, \
Fs::create_directory, \
Fs::create_directories, \
Fs::create_hard_link, \
Fs::create_symlink, \
Fs::current_path, \
Fs::equivalent, \
Fs::file_size, \
Fs::hard_link_count, \
Fs::last_write_time, \
Fs::permissions, \
Fs::read_symlink, \
Fs::remove, \
Fs::remove_all, \
Fs::rename, \
Fs::resize_file, \
Fs::space, \
Fs::status, \
Fs::symlink_status, \
Fs::temp_directory_path, \
Fs::is_empty

namespace vfs {
namespace impl {

class FsBase: public Fs {
public:
using VFS_FS_METHOD_NAMES;

std::filesystem::path canonical(std::filesystem::path const& p, std::error_code& ec) const override {
return handle_error([&] { return this->canonical(p); }, ec);
}

std::filesystem::path weakly_canonical(std::filesystem::path const& p, std::error_code& ec) const override {
return handle_error([&] { return this->weakly_canonical(p); }, ec);
}

void copy(std::filesystem::path const& src, std::filesystem::path const& dst, std::filesystem::copy_options opts, std::error_code& ec) override {
handle_error([&] { this->copy(src, dst, opts); return 0; }, ec);
}

bool copy_file(std::filesystem::path const& src, std::filesystem::path const& dst, std::filesystem::copy_options opts, std::error_code& ec) override {
return handle_error([&] { return this->copy_file(src, dst, opts); }, ec);
}

bool create_directory(std::filesystem::path const& p, std::error_code& ec) noexcept override {
return handle_error([&] { return this->create_directory(p); }, ec);
}

bool create_directory(std::filesystem::path const& p, std::filesystem::path const& attr, std::error_code& ec) noexcept override {
return handle_error([&] { return this->create_directory(p, attr); }, ec);
}

bool create_directories(std::filesystem::path const& p, std::error_code& ec) override {
return handle_error([&] { return this->create_directories(p); }, ec);
}

void create_hard_link(std::filesystem::path const& target, std::filesystem::path const& link, std::error_code& ec) noexcept override {
handle_error([&] { this->create_hard_link(target, link); return 0; }, ec);
}

void create_symlink(std::filesystem::path const& target, std::filesystem::path const& link, std::error_code& ec) noexcept override {
handle_error([&] { this->create_symlink(target, link); return 0; }, ec);
}

[[nodiscard]] std::filesystem::path current_path(std::error_code& ec) const override {
return handle_error([&] { return this->current_path(); }, ec);
}

[[nodiscard]] std::shared_ptr<Fs const> current_path(std::filesystem::path const& p, std::error_code& ec) const noexcept override {
return handle_error([&] { return this->current_path(p); }, ec);
}

[[nodiscard]] std::shared_ptr<Fs> current_path(std::filesystem::path const& p, std::error_code& ec) noexcept override {
return handle_error([&] { return this->current_path(p); }, ec);
}

[[nodiscard]] bool equivalent(std::filesystem::path const& p1, std::filesystem::path const& p2, std::error_code& ec) const noexcept override {
return handle_error([&] { return this->equivalent(p1, p2); }, ec);
}

[[nodiscard]] std::uintmax_t file_size(std::filesystem::path const& p, std::error_code& ec) const noexcept override {
return handle_error([&] { return this->file_size(p); }, ec, static_cast<std::uintmax_t>(-1));
}

[[nodiscard]] std::uintmax_t hard_link_count(std::filesystem::path const& p, std::error_code& ec) const noexcept override {
return handle_error([&] { return this->hard_link_count(p); }, ec, static_cast<std::uintmax_t>(-1));
}

[[nodiscard]] std::filesystem::file_time_type last_write_time(std::filesystem::path const& p, std::error_code& ec) const noexcept override {
return handle_error([&] { return this->last_write_time(p); }, ec);
}

void last_write_time(std::filesystem::path const& p, std::filesystem::file_time_type t, std::error_code& ec) noexcept override {
handle_error([&] { this->last_write_time(p, t); return 0; }, ec);
}

void permissions(std::filesystem::path const& p, std::filesystem::perms prms, std::filesystem::perm_options opts, std::error_code& ec) override {
handle_error([&] { this->permissions(p, prms, opts); return 0; }, ec);
}

[[nodiscard]] std::filesystem::path read_symlink(std::filesystem::path const& p, std::error_code& ec) const override {
return handle_error([&] { return this->read_symlink(p); }, ec);
}

bool remove(std::filesystem::path const& p, std::error_code& ec) noexcept override {
return handle_error([&] { return this->remove(p); }, ec);
}

std::uintmax_t remove_all(std::filesystem::path const& p, std::error_code& ec) override {
return handle_error([&] { return this->remove_all(p); }, ec, static_cast<std::uintmax_t>(-1));
}

void rename(std::filesystem::path const& src, std::filesystem::path const& dst, std::error_code& ec) noexcept override {
handle_error([&] { this->rename(src, dst); return 0; }, ec);
}

void resize_file(std::filesystem::path const& p, std::uintmax_t n, std::error_code& ec) noexcept override {
handle_error([&] { this->resize_file(p, n); return 0; }, ec);
}

[[nodiscard]] std::filesystem::space_info space(std::filesystem::path const& p, std::error_code& ec) const noexcept override {
return handle_error([&] { return this->space(p); }, ec);
}

[[nodiscard]] std::filesystem::file_status status(std::filesystem::path const& p, std::error_code& ec) const noexcept override {
return handle_error([&] { return this->status(p); }, ec);
}

[[nodiscard]] std::filesystem::file_status symlink_status(std::filesystem::path const& p, std::error_code& ec) const noexcept override {
return handle_error([&] { return this->symlink_status(p); }, ec);
}

[[nodiscard]] std::filesystem::path temp_directory_path(std::error_code& ec) const override {
return handle_error([&] { return this->temp_directory_path(); }, ec);
}

[[nodiscard]] bool is_empty(std::filesystem::path const& p, std::error_code& ec) const override {
return handle_error([&] { return this->is_empty(p); }, ec);
}

[[nodiscard]] virtual std::shared_ptr<File const> file_at(std::filesystem::path const& p) const = 0;

virtual std::shared_ptr<File> file_at(std::filesystem::path const& p) = 0;
Expand Down
Loading

0 comments on commit 3c32f29

Please sign in to comment.