fix: inherit process environment and untrack libc objects

This commit is contained in:
2026-08-11 13:08:40 +02:00
parent 0a91131cb0
commit 3ef98a9fd5
26 changed files with 254 additions and 36 deletions
+1 -1
View File
@@ -12,4 +12,4 @@
#pragma once
#define MONTAUK_BUILD_NUMBER 104
#define MONTAUK_BUILD_NUMBER 106
+22 -2
View File
@@ -43,14 +43,16 @@ namespace montauk::abi {
return Sched::LookupExitCode(pid);
}
static int Sys_Spawn(const char* path, const char* args) {
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;
auto* parent = Sched::GetCurrentProcessPtr();
int parentSlot = Ipc::CurrentSlot();
bool inheritRedirection = parent && parent->redirected;
int childPid = Sched::Spawn(resolved, args, !inheritRedirection);
int childPid = Sched::Spawn(resolved, args, !inheritRedirection,
environment, environmentLength);
if (childPid < 0) return childPid;
if (inheritRedirection) {
@@ -107,6 +109,24 @@ namespace montauk::abi {
return i;
}
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;
for (uint32_t i = 0; i < proc->environmentLength; i++)
buf[i] = proc->environment[i];
return (int)proc->environmentLength;
}
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;
for (uint64_t i = 0; i < len; i++) proc->environment[i] = buf[i];
proc->environmentLength = (uint32_t)len;
return 0;
}
static int Sys_ProcList(ProcInfo* buf, int maxCount) {
if (buf == nullptr || maxCount <= 0) return 0;
int count = 0;
+17
View File
@@ -149,8 +149,25 @@ namespace montauk::abi {
if (frame->arg2 != 0 && !UserMemory::String(frame->arg2, kMaxArgsBytes)) return -1;
return (int64_t)Sys_Spawn((const char*)frame->arg1,
UserMemory::IsUserPtr(frame->arg2) ? (const char*)frame->arg2 : nullptr);
case SYS_SPAWN_ENV:
if (!UserMemory::String(frame->arg1, kMaxPathBytes)) return -1;
if (frame->arg2 != 0 && !UserMemory::String(frame->arg2, kMaxArgsBytes)) return -1;
if (frame->arg3 == 0 || frame->arg4 == 0 ||
frame->arg4 > Sched::Process::EnvironmentBytes ||
!UserMemory::Range(frame->arg3, frame->arg4, false) ||
((const char*)frame->arg3)[frame->arg4 - 1] != '\0') return -1;
return (int64_t)Sys_Spawn((const char*)frame->arg1,
UserMemory::IsUserPtr(frame->arg2) ? (const char*)frame->arg2 : nullptr,
(const char*)frame->arg3, (uint32_t)frame->arg4);
case SYS_WAITPID:
return Sys_WaitPid((int)frame->arg1);
case SYS_GETENVIRON:
if (!UserMemory::Range(frame->arg1, frame->arg2, true)) return -1;
return Sys_GetEnviron((char*)frame->arg1, frame->arg2);
case SYS_SETENVIRON:
if (frame->arg2 == 0 || frame->arg2 > Sched::Process::EnvironmentBytes ||
!UserMemory::Range(frame->arg1, frame->arg2, false)) return -1;
return Sys_SetEnviron((const char*)frame->arg1, frame->arg2);
case SYS_FBINFO:
if (!UserMemory::Writable<FbInfo>(frame->arg1)) return -1;
Sys_FbInfo((FbInfo*)frame->arg1);
+3
View File
@@ -315,6 +315,9 @@ namespace montauk::abi {
static constexpr uint64_t SYS_MMAP_ANON = 168;
static constexpr uint64_t SYS_MUNMAP = 169;
static constexpr uint64_t SYS_MPROTECT = 170;
static constexpr uint64_t SYS_GETENVIRON = 171;
static constexpr uint64_t SYS_SETENVIRON = 172;
static constexpr uint64_t SYS_SPAWN_ENV = 173;
// Tunable parameters (for SYS_SDR_SETPARAM / SYS_SDR_GETPARAM).
static constexpr int SDR_PARAM_FREQ = 0; // center frequency, Hz
+24 -1
View File
@@ -294,6 +294,8 @@ namespace Sched {
processTable[i].heapNext = 0;
processTable[i].readdirCursor = 0;
processTable[i].args[0] = '\0';
processTable[i].environment[0] = '\0';
processTable[i].environmentLength = 1;
processTable[i].user[0] = '\0';
processTable[i].cwd[0] = '\0';
processTable[i].runningOnCpu = -1;
@@ -337,7 +339,8 @@ namespace Sched {
<< " process slots, " << (uint64_t)TimeSliceMs << " ms time slice)";
}
int Spawn(const char* vfsPath, const char* args, bool startReady) {
int Spawn(const char* vfsPath, const char* args, bool startReady,
const char* environment, uint32_t environmentLength) {
schedLock.Acquire();
int slot = -1;
@@ -511,6 +514,9 @@ namespace Sched {
auto* currentCpu = Smp::GetCurrentCpuData();
int parentSlot = currentCpu ? currentCpu->currentSlot : -1;
int parentPrimarySlot = parentSlot;
if (parentPrimarySlot >= 0 && processTable[parentPrimarySlot].primarySlot >= 0)
parentPrimarySlot = processTable[parentPrimarySlot].primarySlot;
// Copy arguments string into process
proc.args[0] = '\0';
@@ -522,6 +528,23 @@ namespace Sched {
proc.args[i] = '\0';
}
// posix_spawn(envp) supplies an explicit snapshot. Plain spawn calls
// omit it and inherit the environment stored on the parent process.
if (environment != nullptr && environmentLength > 0 &&
environmentLength <= Process::EnvironmentBytes) {
for (uint32_t i = 0; i < environmentLength; i++)
proc.environment[i] = environment[i];
proc.environmentLength = environmentLength;
} else if (parentPrimarySlot >= 0) {
auto& parent = processTable[parentPrimarySlot];
for (uint32_t i = 0; i < parent.environmentLength; i++)
proc.environment[i] = parent.environment[i];
proc.environmentLength = parent.environmentLength;
} else {
proc.environment[0] = '\0';
proc.environmentLength = 1;
}
// Inherit user string from parent, or default to "system" if no parent
{
if (parentSlot >= 0) {
+5 -1
View File
@@ -65,6 +65,7 @@ namespace Sched {
};
struct Process {
static constexpr uint32_t EnvironmentBytes = 4096;
int pid;
ProcessState state;
int waitingForPid; // PID this process is blocked on (-1 if none)
@@ -82,6 +83,8 @@ namespace Sched {
uint64_t heapNext; // Simple bump allocator for user heap
uint32_t readdirCursor; // Next SYS_READDIR scratch slot
char args[4096]; // Command-line arguments (set by parent via Spawn)
char environment[EnvironmentBytes]; // NUL-separated NAME=VALUE entries
uint32_t environmentLength;
char user[32]; // Owner user name (inherited from parent on spawn)
char cwd[256]; // Absolute current working directory
@@ -139,7 +142,8 @@ namespace Sched {
};
void Initialize();
int Spawn(const char* vfsPath, const char* args = nullptr, bool startReady = true);
int Spawn(const char* vfsPath, const char* args = nullptr, bool startReady = true,
const char* environment = nullptr, uint32_t environmentLength = 0);
int StartProcess(int pid);
void Schedule();