/* * Copyright (c) 2021-2022, Andreas Kling * Copyright (c) 2021-2022, Kenneth Myhra * Copyright (c) 2021-2022, Sam Atkins * Copyright (c) 2022, Matthias Zimmerman * Copyright (c) 2023, Cameron Youell * Copyright (c) 2024, stasoid * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include namespace Core::System { ErrorOr open(StringView path, int options, mode_t mode) { int fd = _open(ByteString(path).characters(), options | O_BINARY | _O_OBTAIN_DIR, mode); if (fd < 0) return Error::from_syscall("open"sv, -errno); return fd; } ErrorOr close(int fd) { if (_close(fd) < 0) return Error::from_syscall("close"sv, -errno); return {}; } ErrorOr read(int fd, Bytes buffer) { int rc = _read(fd, buffer.data(), buffer.size()); if (rc < 0) return Error::from_syscall("read"sv, -errno); return rc; } ErrorOr write(int fd, ReadonlyBytes buffer) { int rc = _write(fd, buffer.data(), buffer.size()); if (rc < 0) return Error::from_syscall("write"sv, -errno); return rc; } ErrorOr lseek(int fd, off_t offset, int whence) { long rc = _lseek(fd, offset, whence); if (rc < 0) return Error::from_syscall("lseek"sv, -errno); return rc; } ErrorOr ftruncate(int fd, off_t length) { long position = _tell(fd); if (position == -1) return Error::from_errno(errno); ScopeGuard restore_position { [&] { _lseek(fd, position, SEEK_SET); } }; auto result = lseek(fd, length, SEEK_SET); if (result.is_error()) return result.release_error(); if (SetEndOfFile((HANDLE)_get_osfhandle(fd)) == 0) return Error::from_windows_error(); return {}; } ErrorOr fstat(int fd) { struct stat st = {}; if (::fstat(fd, &st) < 0) return Error::from_syscall("fstat"sv, -errno); return st; } ErrorOr ioctl(int, unsigned, ...) { dbgln("Core::System::ioctl() is not implemented"); VERIFY_NOT_REACHED(); } ErrorOr getcwd() { auto* cwd = _getcwd(nullptr, 0); if (!cwd) return Error::from_syscall("getcwd"sv, -errno); ByteString string_cwd(cwd); free(cwd); return string_cwd; } ErrorOr stat(StringView path) { if (path.is_null()) return Error::from_syscall("stat"sv, -EFAULT); struct stat st = {}; ByteString path_string = path; if (::stat(path_string.characters(), &st) < 0) return Error::from_syscall("stat"sv, -errno); return st; } ErrorOr rmdir(StringView path) { if (path.is_null()) return Error::from_errno(EFAULT); ByteString path_string = path; if (_rmdir(path_string.characters()) < 0) return Error::from_syscall("rmdir"sv, -errno); return {}; } ErrorOr unlink(StringView path) { if (path.is_null()) return Error::from_errno(EFAULT); ByteString path_string = path; if (_unlink(path_string.characters()) < 0) return Error::from_syscall("unlink"sv, -errno); return {}; } ErrorOr mkdir(StringView path, mode_t) { ByteString str = path; if (_mkdir(str.characters()) < 0) return Error::from_syscall("mkdir"sv, -errno); return {}; } ErrorOr openat(int, StringView, int, mode_t) { dbgln("Core::System::openat() is not implemented"); VERIFY_NOT_REACHED(); } ErrorOr fstatat(int, StringView, int) { dbgln("Core::System::fstatat() is not implemented"); VERIFY_NOT_REACHED(); } ErrorOr mmap(void* address, size_t size, int protection, int flags, int fd, off_t offset, size_t alignment, StringView) { // custom alignment is not supported VERIFY(!alignment); void* ptr = ::mmap(address, size, protection, flags, fd, offset); if (ptr == MAP_FAILED) return Error::from_syscall("mmap"sv, -errno); return ptr; } ErrorOr munmap(void* address, size_t size) { if (::munmap(address, size) < 0) return Error::from_syscall("munmap"sv, -errno); return {}; } int getpid() { return GetCurrentProcessId(); } }