feat: unify system status codes

This commit is contained in:
daniel committed 2026-09-30 09:43:18 +02:00
1 parent 93894b8fe5
commit 8a3ffb2be1
46 files changed
+1499 -489

No files matched your search

+32 -22
View File
@@ -20,6 +20,8 @@
#include <Fs/ProtectedPaths.hpp>
namespace montauk::abi {
// Writes refused here return SystemIntegrityError: the path is protected
// by Fs/ProtectedPaths, not merely gated on an ordinary capability.
static bool CanModifyFilePath(const char* resolved) {
uint64_t required = Fs::RequiredFileWriteCapability(resolved);
return required == 0 || Sched::HasCapability(required);
@@ -27,7 +29,7 @@ namespace montauk::abi {
static int Sys_Open(const char* path) {
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
return Ipc::OpenFileHandle(resolved);
}
@@ -53,8 +55,8 @@ namespace montauk::abi {
static int Sys_ReadDirAt(const char* path, const char** outNames, int maxEntries,
int startIndex) {
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
if (startIndex < 0) return -1;
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
if (startIndex < 0) return InvalidArgument;
// Get entries from VFS into a kernel-local array
const char* kernelNames[256];
@@ -65,7 +67,7 @@ namespace montauk::abi {
// Allocate a user-accessible page for string data via process heap
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr) return -1;
if (proc == nullptr) return GenericFailure;
// Use a rotating ring of scratch pages below the heap instead of
// extending the heap high-water mark on every call. This keeps repeated
@@ -80,11 +82,11 @@ namespace montauk::abi {
if (physAddr == 0) {
void* page = Memory::g_pfa->AllocateZeroed();
if (page == nullptr) return -1;
if (page == nullptr) return OutOfMemory;
physAddr = Memory::SubHHDM((uint64_t)page);
if (!Memory::VMM::Paging::MapUserIn(proc->pml4Phys, physAddr, userVa)) {
Memory::g_pfa->Free(page);
return -1;
return OutOfMemory;
}
pageBuf = (uint8_t*)page;
} else {
@@ -113,25 +115,25 @@ namespace montauk::abi {
static int Sys_FCreate(const char* path) {
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
if (!CanModifyFilePath(resolved)) return SYS_ERR_PERMISSION;
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
if (!CanModifyFilePath(resolved)) return SystemIntegrityError;
return Ipc::CreateFileHandle(resolved);
}
static int Sys_FDelete(const char* path) {
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
if (!CanModifyFilePath(resolved)) return SYS_ERR_PERMISSION;
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
if (!CanModifyFilePath(resolved)) return SystemIntegrityError;
return Fs::Vfs::VfsDelete(resolved);
}
static int Sys_Stat(const char* path, FileStat* out) {
if (out == nullptr) return -1;
if (out == nullptr) return InvalidArgument;
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
Fs::Vfs::StatInfo info;
if (Fs::Vfs::VfsStat(resolved, info) != 0) return -1;
if (Fs::Vfs::VfsStat(resolved, info) != 0) return NoSuchPath;
out->size = info.size;
out->mtime = info.mtime;
@@ -139,38 +141,46 @@ namespace montauk::abi {
out->atime = info.atime;
out->mode = info.mode;
out->isDir = info.isDir ? 1u : 0u;
return 0;
return Success;
}
static int Sys_Utime(const char* path, int64_t atime, int64_t mtime,
bool useCurrent) {
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
// Timestamps are file state like any other: a protected path must not
// be mutable through a side door that skips the write check.
if (!CanModifyFilePath(resolved)) return SYS_ERR_PERMISSION;
if (!CanModifyFilePath(resolved)) return SystemIntegrityError;
if (useCurrent) {
int64_t now = Timekeeping::GetUnixTimestamp();
atime = now;
mtime = now;
}
return Fs::Vfs::VfsSetTimes(resolved, atime, mtime);
// VfsSetTimes has its own codes: -1 not found, -2 unsupported by the
// filesystem, -3 timestamp out of range, -4 I/O error.
switch (Fs::Vfs::VfsSetTimes(resolved, atime, mtime)) {
case 0: return Success;
case -2: return UnsupportedOp;
case -3: return InvalidArgument;
case -4: return IoFailure;
default: return NoSuchPath;
}
}
static int Sys_FMkdir(const char* path) {
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
if (!CanModifyFilePath(resolved)) return SYS_ERR_PERMISSION;
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
if (!CanModifyFilePath(resolved)) return SystemIntegrityError;
return Fs::Vfs::VfsMkdir(resolved);
}
static int Sys_FRename(const char* oldPath, const char* newPath) {
char resolvedOld[256];
char resolvedNew[256];
if (!ResolveProcessPath(oldPath, resolvedOld, sizeof(resolvedOld))) return -1;
if (!ResolveProcessPath(newPath, resolvedNew, sizeof(resolvedNew))) return -1;
if (!ResolveProcessPath(oldPath, resolvedOld, sizeof(resolvedOld))) return InvalidArgument;
if (!ResolveProcessPath(newPath, resolvedNew, sizeof(resolvedNew))) return InvalidArgument;
if (!CanModifyFilePath(resolvedOld) || !CanModifyFilePath(resolvedNew))
return SYS_ERR_PERMISSION;
return SystemIntegrityError;
return Fs::Vfs::VfsRename(resolvedOld, resolvedNew);
}