AuroraRuntime/Source/AuProcAddresses.UNIX.cpp

221 lines
5.0 KiB
C++
Executable File

/***
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 <Source/Debug/ExceptionWatcher.Unix.hpp>
#include <sys/mman.h>
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()
{
::killpg(0, SIGKILL);
}
static bool PosixLseek63(int fd, AuUInt64 offset, int whence, AuUInt64 *pOffset)
{
if (offset > std::numeric_limits<off_t>::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<off_t>::max() >= std::numeric_limits<AuInt64>::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;
}
void PosixWriteEoS(int fd)
{
::ftruncate(fd, PosixGetOffset(fd));
}
void SysWriteEoS(AuUInt uOSHandle)
{
PosixWriteEoS(uOSHandle);
}
void SysCloseHandle(AuUInt uOSHandle)
{
::close(uOSHandle);
}
bool SysHandleIsNonZero(AuUInt uOSHandle)
{
#if defined(AURORA_IS_64BIT)
return uOSHandle && (uOSHandle != 0xFFFFFFFFull) && (uOSHandle != 0xFFFFFFFFFFFFFFFFull);
#else
return uOSHandle && (uOSHandle != 0xFFFFFFFF);
#endif
}
void SysFlushHandle(AuUInt uOSHandle)
{
::fsync(uOSHandle);
}
int PosixUnlink(const char *pathname)
{
return ::unlink(pathname);
}
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);
}
bool SysMemoryLockPages(const void *pVoid, AuUInt uLength)
{
return ::mlock(pVoid, uLength) == 0;
}
bool SysMemoryUnlockPages(const void *pVoid, AuUInt uLength)
{
return ::munlock(pVoid, uLength) == 0;
}
}