/*** Copyright (C) 2024 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuProcAddresses.UNIX.cpp Date: 2024-3-5 Author: Reece ***/ #include "RuntimeInternal.hpp" #include "AuProcAddresses.UNIX.hpp" #include #include namespace Aurora::Process { void PosixForkResetLocks(); } namespace Aurora::Memory { AuUInt32 RoundPageUp(AuUInt32 value); } namespace Aurora { int PosixOpen(const char *pathname, int flags, mode_t mode) { return ::open(pathname, flags, mode); } void PosixDoForkHooks() { Process::PosixForkResetLocks(); Debug::DeinitSignalHandlers(); } void PosixShutup() { int fd = PosixOpen("/dev/null", O_RDWR); ::dup2(fd, STDERR_FILENO); ::dup2(fd, STDOUT_FILENO); ::dup2(fd, STDIN_FILENO); ::close(fd); } void PosixTerminate() { #if 0 PosixShutup(); #endif ::killpg(0, SIGKILL); } static bool PosixLseek63(int fd, AuUInt64 offset, int whence, AuUInt64 *pOffset) { if (offset > std::numeric_limits::max()) { SysPushErrorIO("int overflow exploit?"); return false; } #if defined(AURORA_IS_LINUX_DERIVED) auto ret = lseek64(fd, offset, whence); #elif defined(AURORA_IS_64BIT) static_assert(std::numeric_limits::max() >= std::numeric_limits::max(), "unsupported posix os"); auto ret = lseek(fd, offset, whence); #elif defined(AURORA_FORCE_32BIT_FILESYSTEMS_ONLY) auto ret = lseek(fd, (off_t)offset, whence); #else #error ancient 32-bit posix operating systems require 64-bit file awareness #endif if (ret < 0) { // Intentionally omitted (thank linuxs' mess of incomplete filesystems) // SysPushErrorIO("PosixLseek63 IO Error: {}", ret); return false; } if (pOffset) { *pOffset = ret; } return true; } AuUInt64 PosixGetLength(int fd) { AuUInt64 ret {}, old {}; bool status {}; if (!PosixLseek63(fd, 0, SEEK_CUR, &old)) { return 0; } status = PosixLseek63(fd, 0, SEEK_END, &ret); status &= PosixLseek63(fd, old, SEEK_SET, nullptr); return status ? ret : 0; } AuUInt64 PosixGetOffset(int fd) { AuUInt64 ret; if (!PosixLseek63(fd, 0, SEEK_CUR, &ret)) { return 0; } return ret; } bool PosixSetOffset(int fd, AuUInt64 offset) { return PosixLseek63(fd, offset, SEEK_SET, nullptr); } bool PosixRead(int fd, void *buf, AuUInt32 count, AuUInt32 *pRead) { AuSInt ret; do { ret = ::read(fd, buf, count); } while ((ret == -1 && errno == EINTR)); if (ret < 0) { SysPushErrorIO("PosixRead IO Error: {}", errno); return false; } if (pRead) { *pRead = ret; } return true; } bool PosixWrite(int fd, const void *buf, AuUInt32 count, AuUInt32 *pWritten) { AuSInt ret; do { ret = ::write(fd, buf, count); } while ((ret == -1 && errno == EINTR)); if (ret < 0) { SysPushErrorIO("PosixWrite IO Error: {}", errno); return false; } if (pWritten) { *pWritten = ret; } return true; } AuUInt64 SysGetFileLength(AuUInt uOSHandle) { return PosixGetLength(uOSHandle); } void *SysAllocateLarge(AuUInt uLength) { uLength = AuMemory::RoundPageUp(uLength); return ::mmap(0, uLength, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); } void SysAllocateFree(void *pBuffer, AuUInt uLength) { uLength = AuMemory::RoundPageUp(uLength); ::munmap(pBuffer, uLength); } }