libos: Add a very bare-bones C++ RAII File class

This commit is contained in:
apio 2023-04-12 21:46:10 +02:00
parent 193d63c81b
commit d97bf991d1
Signed by: apio
GPG Key ID: B8A7D06E42258954
4 changed files with 114 additions and 11 deletions

View File

@ -1,4 +1,5 @@
#include <os/ArgumentParser.h> #include <os/ArgumentParser.h>
#include <os/File.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -6,19 +7,13 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
FILE* f;
StringView pathname; StringView pathname;
os::ArgumentParser parser; os::ArgumentParser parser;
parser.add_positional_argument(pathname, "file"_sv, true); parser.add_positional_argument(pathname, "path"_sv, true);
parser.parse(argc, argv); parser.parse(argc, argv);
f = fopen(pathname.chars(), "w"); auto file = os::File::open_or_create(pathname, os::File::WriteOnly).release_value();
if (!f)
{
perror(pathname.chars());
return 1;
}
char buffer[4096]; char buffer[4096];
@ -26,10 +21,8 @@ int main(int argc, char** argv)
{ {
char* rc = fgets(buffer, sizeof(buffer), stdin); char* rc = fgets(buffer, sizeof(buffer), stdin);
if (rc == 0) break; if (rc == 0) break;
fputs(buffer, f); file->write(StringView { buffer });
} }
fclose(f);
return 0; return 0;
} }

View File

@ -5,6 +5,7 @@ file(GLOB HEADERS include/os/*.h)
set(SOURCES set(SOURCES
${HEADERS} ${HEADERS}
src/ArgumentParser.cpp src/ArgumentParser.cpp
src/File.cpp
) )
add_library(os ${SOURCES}) add_library(os ${SOURCES})

42
libos/include/os/File.h Normal file
View File

@ -0,0 +1,42 @@
#pragma once
#include <bits/open-flags.h>
#include <luna/Buffer.h>
#include <luna/Result.h>
#include <luna/SharedPtr.h>
#include <luna/StringView.h>
#include <sys/types.h>
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<SharedPtr<File>> open(StringView path, OpenMode flags);
static Result<SharedPtr<File>> open_or_create(StringView path, OpenMode flags, mode_t mode = 0644);
static Result<SharedPtr<File>> create(StringView path, OpenMode flags, mode_t mode = 0644);
void set_close_on_exec();
Result<void> write(StringView str);
File(Badge<File>);
~File();
private:
static Result<SharedPtr<File>> construct(StringView path, int flags, mode_t mode);
Result<usize> raw_read(u8* buf, usize length);
Result<usize> raw_write(const u8* buf, usize length);
int m_fd { -1 };
};
}

67
libos/src/File.cpp Normal file
View File

@ -0,0 +1,67 @@
#include <fcntl.h>
#include <os/File.h>
#include <sys/syscall.h>
#include <unistd.h>
namespace os
{
File::File(Badge<File>)
{
}
File::~File()
{
if (m_fd >= 0) close(m_fd);
}
Result<SharedPtr<File>> 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<int>::from_syscall(rc));
file->m_fd = fd;
return file;
}
Result<SharedPtr<File>> File::open(StringView path, OpenMode flags)
{
return construct(path, (int)flags, 0);
}
Result<SharedPtr<File>> File::open_or_create(StringView path, OpenMode flags, mode_t mode)
{
return construct(path, (int)flags | O_CREAT, mode);
}
Result<SharedPtr<File>> File::create(StringView path, OpenMode flags, mode_t mode)
{
return construct(path, (int)flags | (O_CREAT | O_EXCL), mode);
}
Result<usize> File::raw_read(u8* buf, usize length)
{
long rc = syscall(SYS_read, m_fd, buf, length);
return Result<usize>::from_syscall(rc);
}
Result<usize> File::raw_write(const u8* buf, usize length)
{
long rc = syscall(SYS_write, m_fd, buf, length);
return Result<usize>::from_syscall(rc);
}
Result<void> 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);
}
}