From afc11065bb151349090d8ae89cb61d1c35bdddae Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Mon, 28 Oct 2024 23:49:50 -0500 Subject: Prepare for new SSO. --- source/fud_file.cpp | 123 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 114 insertions(+), 9 deletions(-) (limited to 'source/fud_file.cpp') diff --git a/source/fud_file.cpp b/source/fud_file.cpp index e27a46d..8dab031 100644 --- a/source/fud_file.cpp +++ b/source/fud_file.cpp @@ -82,6 +82,7 @@ FileResult RegularFile::open( return FudStatus::Partial; case ENOENT: return FudStatus::NotFound; + case EBADF: case EFBIG: case EOVERFLOW: case EINVAL: @@ -117,17 +118,100 @@ FileResult RegularFile::open( return file; } -/* - static FileResult RegularFile::create( - StringView filename, - FileAccessMode mode, - OpenFlags flags, - bool exclusive, - Option dirFdOption, - Allocator* allocator = &globalFudAllocator); +FileResult RegularFile::create( + StringView filename, + FileAccessMode mode, + OpenFlags flags, + Permissions permissions, + bool exclusive, + Option dirFdOption, + Allocator* allocator) { + if (allocator == nullptr) { + return FudStatus::NullPointer; + } + + if (!filename.nullTerminated()) { + return FudStatus::ArgumentInvalid; + } + + int dirFd = dirFdOption.valueOr(AT_FDCWD); + + RegularFile file{}; + + uint32_t openFlags = 0; + switch (mode) { + case FileAccessMode::Read: + openFlags = O_RDONLY; + break; + case FileAccessMode::Write: + openFlags = O_WRONLY; + break; + case FileAccessMode::ReadWrite: + openFlags = O_RDWR; + break; + default: + return FudStatus::ArgumentInvalid; + } + + if (flags.hasFlag(OpenFlagEnum::Append) && flags.hasFlag(OpenFlagEnum::Truncate)) { + return FudStatus::OperationInvalid; + } + + openFlags |= flags.flags() | O_CREAT | (O_EXCL * static_cast(exclusive)); + + open_how openHow{}; + zeroObject(openHow); + openHow.flags = openFlags; + openHow.resolve = RESOLVE_NO_SYMLINKS; + openHow.mode = permissions.mode(); + + auto status = syscall(SYS_openat2, dirFd, filename.data(), &openHow, sizeof(openHow)); + if (status == -1) { + if constexpr (EAGAIN != EWOULDBLOCK && status == EWOULDBLOCK) { + return FudStatus::Partial; + } + switch (errno) { + case ETXTBSY: + case EAGAIN: + return FudStatus::Partial; + case EBADF: + case EFBIG: + case EOVERFLOW: + case EINVAL: + case EISDIR: + case ENAMETOOLONG: + return FudStatus::ArgumentInvalid; + case EROFS: + case EACCES: + case EPERM: + return FudStatus::PermissionDenied; + case EDQUOT: + case ENOENT: + case ELOOP: + case EXDEV: + case ENFILE: + case E2BIG: + default: + return FudStatus::Failure; + } + } + fudAssert(status <= std::numeric_limits::max()); + file.m_fd = static_cast(status); + + using Stat = struct stat; + Stat sBuffer{}; + auto fStatus = fstat(file.m_fd, &sBuffer); + if (fStatus == -1) { + return FudStatus::Failure; + } + + if ((sBuffer.st_mode & S_IFMT) != S_IFREG) { + return FudStatus::ObjectInvalid; + } + + return file; } -*/ RegularFile::~RegularFile() { @@ -198,4 +282,25 @@ FudStatus RegularFile::close() return status; } +Result RegularFile::size() const +{ + auto fileSize = lseek(m_fd, 0, SEEK_END); + if (fileSize == -1) { + switch (errno) { + case EBADF: + case ESPIPE: + return FudStatus::ObjectInvalid; + default: + return FudStatus::Failure; + } + } + + auto seekBegin = lseek(m_fd, 0, SEEK_SET); + if (seekBegin == -1) { + return FudStatus::Failure; + } + + return static_cast(fileSize); +} + } // namespace fud -- cgit v1.2.3