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

+30 -30
View File
@@ -49,13 +49,13 @@ namespace montauk::abi {
// stream, whether or not it also carries a capability grant. The child is
// created suspended (startReady == false) so its first instruction cannot
// run before the channels exist, and is started here once they do.
// Returns childPid, or kills the child and returns -1 on failure.
// Returns childPid, or kills the child and returns GenericFailure.
static int InheritRedirection(int childPid, Sched::Process* parent, int parentSlot) {
auto* child = Sched::GetProcessByPid(childPid);
int childSlot = Ipc::SlotForPid(childPid);
if (child == nullptr || childSlot < 0 || parentSlot < 0) {
Sched::KillProcess(childPid);
return -1;
return GenericFailure;
}
child->ioOutHandle = DuplicateHandleBetweenSlots(parentSlot, parent->ioOutHandle, childSlot);
@@ -65,7 +65,7 @@ namespace montauk::abi {
if (child->ioOutHandle < 0 || child->ioInHandle < 0 || child->ioKeyHandle < 0 ||
!ConfigureRedirWaitsetForSlot(childSlot, child)) {
Sched::KillProcess(childPid);
return -1;
return GenericFailure;
}
child->redirected = true;
@@ -74,7 +74,7 @@ namespace montauk::abi {
child->termRows = parent->termRows;
if (Sched::StartProcess(childPid) < 0) {
Sched::KillProcess(childPid);
return -1;
return GenericFailure;
}
return childPid;
@@ -83,7 +83,7 @@ namespace montauk::abi {
static int Sys_Spawn(const char* path, const char* args,
const char* environment = nullptr, uint32_t environmentLength = 0) {
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
auto* parent = Sched::GetCurrentProcessPtr();
int parentSlot = Ipc::CurrentSlot();
@@ -101,7 +101,7 @@ namespace montauk::abi {
static int Sys_SpawnCaps(const char* path, const char* args,
const char* user, const SpawnCapabilities* requested) {
auto* parent = Sched::GetCurrentProcessPtr();
if (parent == nullptr || requested == nullptr) return -1;
if (parent == nullptr || requested == nullptr) return InvalidArgument;
// Snapshot all security-sensitive userspace inputs before evaluating
// them. This prevents another thread from changing a mask or owner
@@ -111,7 +111,7 @@ namespace montauk::abi {
const char* userOverride = nullptr;
if (user != nullptr) {
if (!Sched::HasCapability(CAP_USER_ADMIN))
return SYS_ERR_PERMISSION;
return CapabilityDenied;
int i = 0;
for (; i < 31 && user[i]; i++) childUser[i] = user[i];
childUser[i] = '\0';
@@ -122,11 +122,11 @@ namespace montauk::abi {
// possessing a capability is insufficient to pass it: the parent must
// also hold it in its delegable set.
if (!ValidCapabilityDelegation(copy, parent->delegableCaps)) {
return SYS_ERR_PERMISSION;
return CapabilityDenied;
}
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
int parentSlot = Ipc::CurrentSlot();
bool inheritRedirection = parent->redirected;
@@ -143,16 +143,16 @@ namespace montauk::abi {
// The calling process's own capability masks.
static int Sys_GetCaps(SpawnCapabilities* out) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr || out == nullptr) return -1;
if (proc == nullptr || out == nullptr) return InvalidArgument;
out->effective = proc->effectiveCaps;
out->delegable = proc->delegableCaps;
return 0;
return Success;
}
// Copy the absolute path this process was spawned from (argv[0]).
static int Sys_GetExecPath(char* buf, uint64_t maxLen) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr || buf == nullptr || maxLen == 0) return -1;
if (proc == nullptr || buf == nullptr || maxLen == 0) return InvalidArgument;
int i = 0;
for (; i < (int)maxLen - 1 && proc->name[i]; i++) {
buf[i] = proc->name[i];
@@ -163,7 +163,7 @@ namespace montauk::abi {
static int Sys_GetArgs(char* buf, uint64_t maxLen) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr || buf == nullptr || maxLen == 0) return -1;
if (proc == nullptr || buf == nullptr || maxLen == 0) return InvalidArgument;
int i = 0;
for (; i < (int)maxLen - 1 && proc->args[i]; i++) {
buf[i] = proc->args[i];
@@ -174,8 +174,8 @@ namespace montauk::abi {
static int Sys_GetEnviron(char* buf, uint64_t maxLen) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr || buf == nullptr || maxLen == 0) return -1;
if (maxLen < proc->environmentLength) return -2;
if (proc == nullptr || buf == nullptr || maxLen == 0) return InvalidArgument;
if (maxLen < proc->environmentLength) return BufferTooSmall;
for (uint32_t i = 0; i < proc->environmentLength; i++)
buf[i] = proc->environment[i];
return (int)proc->environmentLength;
@@ -184,10 +184,10 @@ namespace montauk::abi {
static int Sys_SetEnviron(const char* buf, uint64_t len) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr || buf == nullptr || len == 0 ||
len > Sched::Process::EnvironmentBytes || buf[len - 1] != '\0') return -1;
len > Sched::Process::EnvironmentBytes || buf[len - 1] != '\0') return InvalidArgument;
for (uint64_t i = 0; i < len; i++) proc->environment[i] = buf[i];
proc->environmentLength = (uint32_t)len;
return 0;
return Success;
}
static int Sys_ProcList(ProcInfo* buf, int maxCount) {
@@ -233,7 +233,7 @@ namespace montauk::abi {
}
ancestor = target->parentPid;
}
if (!descendant) return SYS_ERR_PERMISSION;
if (!descendant) return PermissionDenied;
}
return Sched::KillProcess(pid);
}
@@ -247,19 +247,19 @@ namespace montauk::abi {
}
static int Sys_SetUser(int pid, const char* name) {
if (name == nullptr) return -1;
if (name == nullptr) return InvalidArgument;
auto* target = Sched::GetProcessByPid(pid);
if (target == nullptr) return -1;
if (target == nullptr) return InvalidArgument;
int i = 0;
for (; i < 31 && name[i]; i++)
target->user[i] = name[i];
target->user[i] = '\0';
return 0;
return Success;
}
static int Sys_GetUser(char* buf, uint64_t maxLen) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr || buf == nullptr || maxLen == 0) return -1;
if (proc == nullptr || buf == nullptr || maxLen == 0) return InvalidArgument;
int i = 0;
for (; i < (int)maxLen - 1 && proc->user[i]; i++)
buf[i] = proc->user[i];
@@ -269,15 +269,15 @@ namespace montauk::abi {
static int Sys_GetCwd(char* buf, uint64_t maxLen) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr || buf == nullptr || maxLen == 0) return -1;
if (proc == nullptr || buf == nullptr || maxLen == 0) return InvalidArgument;
const char* cwd = proc->cwd[0] ? proc->cwd : "0:/";
uint64_t cwdLen = 0;
while (cwd[cwdLen] != '\0') cwdLen++;
// Reserve -1 for non-size failures so libc can distinguish them
// from a buffer that can be retried with a larger allocation.
if (maxLen <= cwdLen) return -2;
// BufferTooSmall tells libc the call can be retried with a larger
// allocation (ERANGE), unlike the other failures.
if (maxLen <= cwdLen) return BufferTooSmall;
for (uint64_t i = 0; i <= cwdLen; i++) buf[i] = cwd[i];
return (int)cwdLen;
@@ -304,10 +304,10 @@ namespace montauk::abi {
static int Sys_Chdir(const char* path) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr || path == nullptr) return -1;
if (proc == nullptr || path == nullptr) return InvalidArgument;
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
// ReadDir doubles as the directory-existence probe: it fails
// for nonexistent paths and for regular files (directories are
@@ -315,12 +315,12 @@ namespace montauk::abi {
// would reject every valid target).
{
const char* entries[1];
if (Fs::Vfs::VfsReadDir(resolved, entries, 1) < 0) return -1;
if (Fs::Vfs::VfsReadDir(resolved, entries, 1) < 0) return NoSuchPath;
}
int i = 0;
for (; i < 255 && resolved[i]; i++) proc->cwd[i] = resolved[i];
proc->cwd[i] = '\0';
return 0;
return Success;
}
};