feat: Rust std target + ruststd tests; SYS_EXIT_GROUP; fix mkdir/create under missing parent

This commit is contained in:
daniel committed 2026-10-17 10:30:24 +02:00
1 parent 9e66c3b249
commit e87bd358a6
20 files changed
+657 -97

No files matched your search

+1 -1
View File
@@ -12,4 +12,4 @@
#pragma once
#define MONTAUK_BUILD_NUMBER 1
#define MONTAUK_BUILD_NUMBER 3
+19
View File
@@ -27,6 +27,23 @@ namespace montauk::abi {
return required == 0 || Sched::HasCapability(required);
}
// Drivers fail a create under a missing parent with a bare -1; report it
// as NoSuchPath so callers can tell it apart (Rust's create_dir_all only
// creates the missing ancestors when mkdir says NotFound).
static bool ParentDirExists(const char* resolved) {
char parent[256];
int len = Lib::strlen(resolved);
if (len >= (int)sizeof(parent)) return false;
memcpy(parent, resolved, len + 1);
while (len > 0 && parent[len - 1] == '/') len--;
while (len > 0 && parent[len - 1] != '/') len--;
while (len > 0 && parent[len - 1] == '/') len--;
if (len == 0 || parent[len - 1] == ':') return true; // drive root
parent[len] = '\0';
Fs::Vfs::StatInfo info;
return Fs::Vfs::VfsStat(parent, info) == 0 && info.isDir;
}
static int Sys_Open(const char* path) {
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
@@ -117,6 +134,7 @@ namespace montauk::abi {
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
if (!CanModifyFilePath(resolved)) return SystemIntegrityError;
if (!ParentDirExists(resolved)) return NoSuchPath;
return Ipc::CreateFileHandle(resolved);
}
@@ -171,6 +189,7 @@ namespace montauk::abi {
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return InvalidArgument;
if (!CanModifyFilePath(resolved)) return SystemIntegrityError;
if (!ParentDirExists(resolved)) return NoSuchPath;
return Fs::Vfs::VfsMkdir(resolved);
}
+8
View File
@@ -228,6 +228,14 @@ namespace montauk::abi {
Sched::ExitProcess();
}
// Like Sys_Abort, but a normal exit with the caller's code: every thread
// goes, and waiters see exitCode & 0xFF, the same as SYS_EXIT on the main
// thread.
static void Sys_ExitGroup(int exitCode) {
Sched::KillProcess(Sched::GetCurrentPid(), exitCode & 0xFF);
Sched::ExitProcess();
}
static int Sys_Kill(int pid) {
// A process may always kill itself (kill(getpid(), ...)); waiters
// see TerminatedKilled. abort() uses SYS_ABORT instead.
+3
View File
@@ -403,6 +403,9 @@ namespace montauk::abi {
case SYS_ABORT:
Sys_Abort();
return Success;
case SYS_EXIT_GROUP:
Sys_ExitGroup((int)frame->arg1);
return Success;
case SYS_SETSESSION:
return (int64_t)Sys_SetSession();
case SYS_KILLSESSION:
+6
View File
@@ -380,6 +380,12 @@ namespace montauk::abi {
sibling thread ends only that thread, so abort() needs its own call. */
static constexpr uint64_t SYS_ABORT = 198; // () -> does not return
/* Normal termination of the whole process from any thread, with an exit
code (0..255) instead of SYS_ABORT's fixed TerminatedAborted. libc
exit() and Rust std::process::exit() use it, so exiting from a sibling
thread ends the process rather than only that thread. */
static constexpr uint64_t SYS_EXIT_GROUP = 199; // (exitCode) -> does not return
/* Kernel-owned process capabilities. User identities may namespace
per-user resources, but never participate in authorization decisions. */
static constexpr uint64_t CAP_PROCESS_ADMIN = 1ULL << 0;
+18
View File
@@ -89,6 +89,20 @@ namespace Fs::Ramdisk {
return -1;
}
// Mkdir/Create must not conjure entries under a missing parent: the
// table is flat, so "a/b/" with no "a/" entry is invisible to ReadDir of
// the parent and makes "a" fail Stat, Delete and recursive removal.
static bool ParentExists(const char* path) {
char normalized[MaxNameLen];
int len = NormalizePath(path, normalized, MaxNameLen);
if (len < 0) return false;
while (len > 0 && normalized[len - 1] != '/') len--;
if (len <= 1) return true; // parent is the root
normalized[len - 1] = '\0';
int idx = FindEntryByPath(normalized);
return idx >= 0 && fileTable[idx].isDirectory;
}
void Initialize(void* moduleData, uint64_t moduleSize) {
Kt::KernelLogStream(Kt::OK, "Ramdisk") << "Parsing USTAR archive (" << moduleSize << " bytes)";
@@ -442,6 +456,8 @@ namespace Fs::Ramdisk {
}
}
if (!ParentExists(path)) return -1;
// Create new file entry
FileEntry& entry = fileTable[fileCount];
@@ -531,6 +547,8 @@ namespace Fs::Ramdisk {
}
}
if (!ParentExists(path)) return -1;
// Create directory entry (stored with trailing slash for tar convention)
FileEntry& entry = fileTable[fileCount];