From d97bf991d1e6ecd159b2ee124f7d8246bbe0a299 Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 12 Apr 2023 21:46:10 +0200 Subject: [PATCH] libos: Add a very bare-bones C++ RAII File class --- apps/edit.cpp | 15 +++------ libos/CMakeLists.txt | 1 + libos/include/os/File.h | 42 ++++++++++++++++++++++++++ libos/src/File.cpp | 67 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 11 deletions(-) create mode 100644 libos/include/os/File.h create mode 100644 libos/src/File.cpp diff --git a/apps/edit.cpp b/apps/edit.cpp index f514a330..0871047f 100644 --- a/apps/edit.cpp +++ b/apps/edit.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -6,19 +7,13 @@ int main(int argc, char** argv) { - FILE* f; StringView pathname; os::ArgumentParser parser; - parser.add_positional_argument(pathname, "file"_sv, true); + parser.add_positional_argument(pathname, "path"_sv, true); parser.parse(argc, argv); - f = fopen(pathname.chars(), "w"); - if (!f) - { - perror(pathname.chars()); - return 1; - } + auto file = os::File::open_or_create(pathname, os::File::WriteOnly).release_value(); char buffer[4096]; @@ -26,10 +21,8 @@ int main(int argc, char** argv) { char* rc = fgets(buffer, sizeof(buffer), stdin); if (rc == 0) break; - fputs(buffer, f); + file->write(StringView { buffer }); } - fclose(f); - return 0; } diff --git a/libos/CMakeLists.txt b/libos/CMakeLists.txt index c939aba1..00d2f22a 100644 --- a/libos/CMakeLists.txt +++ b/libos/CMakeLists.txt @@ -5,6 +5,7 @@ file(GLOB HEADERS include/os/*.h) set(SOURCES ${HEADERS} src/ArgumentParser.cpp + src/File.cpp ) add_library(os ${SOURCES}) diff --git a/libos/include/os/File.h b/libos/include/os/File.h new file mode 100644 index 00000000..f5cd2fdc --- /dev/null +++ b/libos/include/os/File.h @@ -0,0 +1,42 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +namespace os +{ + class File + { + public: + enum OpenMode + { + ReadOnly = O_RDONLY, + WriteOnly = O_WRONLY | O_TRUNC, + ReadWrite = O_RDWR | O_TRUNC, + Append = O_WRONLY | O_APPEND, + ReadAppend = O_RDWR | O_APPEND, + }; + + static Result> open(StringView path, OpenMode flags); + static Result> open_or_create(StringView path, OpenMode flags, mode_t mode = 0644); + static Result> create(StringView path, OpenMode flags, mode_t mode = 0644); + + void set_close_on_exec(); + + Result write(StringView str); + + File(Badge); + ~File(); + + private: + static Result> construct(StringView path, int flags, mode_t mode); + + Result raw_read(u8* buf, usize length); + Result raw_write(const u8* buf, usize length); + + int m_fd { -1 }; + }; +} diff --git a/libos/src/File.cpp b/libos/src/File.cpp new file mode 100644 index 00000000..3ae3dbf6 --- /dev/null +++ b/libos/src/File.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include + +namespace os +{ + File::File(Badge) + { + } + + File::~File() + { + if (m_fd >= 0) close(m_fd); + } + + Result> File::construct(StringView path, int flags, mode_t mode) + { + auto file = TRY(adopt_shared(new (std::nothrow) File({}))); + + long rc = syscall(SYS_open, path.chars(), flags, mode); + int fd = TRY(Result::from_syscall(rc)); + + file->m_fd = fd; + + return file; + } + + Result> File::open(StringView path, OpenMode flags) + { + return construct(path, (int)flags, 0); + } + + Result> File::open_or_create(StringView path, OpenMode flags, mode_t mode) + { + return construct(path, (int)flags | O_CREAT, mode); + } + + Result> File::create(StringView path, OpenMode flags, mode_t mode) + { + return construct(path, (int)flags | (O_CREAT | O_EXCL), mode); + } + + Result File::raw_read(u8* buf, usize length) + { + long rc = syscall(SYS_read, m_fd, buf, length); + return Result::from_syscall(rc); + } + + Result File::raw_write(const u8* buf, usize length) + { + long rc = syscall(SYS_write, m_fd, buf, length); + return Result::from_syscall(rc); + } + + Result File::write(StringView str) + { + TRY(raw_write((const u8*)str.chars(), str.length())); + + return {}; + } + + void File::set_close_on_exec() + { + fcntl(m_fd, F_SETFD, FD_CLOEXEC); + } +}