diff --git a/kernel/src/Api/BuildNo.hpp b/kernel/src/Api/BuildNo.hpp index 377d126..4c64324 100644 --- a/kernel/src/Api/BuildNo.hpp +++ b/kernel/src/Api/BuildNo.hpp @@ -12,4 +12,4 @@ #pragma once -#define MONTAUK_BUILD_NUMBER 254 +#define MONTAUK_BUILD_NUMBER 264 diff --git a/kernel/src/Common/StatusCodes.hpp b/kernel/src/Common/StatusCodes.hpp index 5cf43e8..ddd707d 100644 --- a/kernel/src/Common/StatusCodes.hpp +++ b/kernel/src/Common/StatusCodes.hpp @@ -6,9 +6,8 @@ #pragma once -// Syscall return status. Mirrored for userspace in -// programs/include/montauk/statuscodes.h and, as MTK_STATUS_*, in -// programs/include/libc/montauk.h; scripts/montauk-syscalls.py checks all three. +// Syscall return status. +// Mirrored in userspace with positive values at programs/include/montauk/statuscodes.h. enum StatusCodes { Success = 0, GenericFailure = -1, diff --git a/programs/include/montauk/statuscodes.h b/programs/include/montauk/statuscodes.h index be65416..e0366d9 100644 --- a/programs/include/montauk/statuscodes.h +++ b/programs/include/montauk/statuscodes.h @@ -6,29 +6,83 @@ #pragma once -// Userspace mirror of kernel/src/Common/StatusCodes.hpp. Also usable from C -// (the libc includes it), where the enumerators are unqualified. +// Userspace status codes. +// Analogous to kernel/src/Common/StatusCodes.hpp, but positive numbers are used. #ifdef __cplusplus namespace montauk { #endif -enum StatusCodes { +typedef enum { Success = 0, - GenericFailure = -1, - PermissionDenied = -2, - CapabilityDenied = -3, - SystemIntegrityError = -4, - BadPointer = -5, - InvalidArgument = -6, - UnsupportedOp = -7, - NoDevice = -8, - IoFailure = -9, - BadInvocation = -10, - NoSuchPath = -11, - Busy = -12, - BufferTooSmall = -13, - OutOfMemory = -14 -}; + GenericFailure = 1, + PermissionDenied = 2, + CapabilityDenied = 3, + SystemIntegrityError = 4, + BadPointer = 5, + InvalidArgument = 6, + UnsupportedOp = 7, + NoDevice = 8, + IoFailure = 9, + BadInvocation = 10, + NoSuchPath = 11, + Busy = 12, + BufferTooSmall = 13, + OutOfMemory = 14 +} StatusCodes; + +inline const char* GetStatusText(StatusCodes statusCode) { + const char* statusText[] = { + "Success", // 0 + "Generic failure", // 1 + "Permission denied", // 2 + "Capability denied", // 3 + "System integrity error", // 4 + "Bad pointer", // 5 + "Invalid argument", // 6 + "Unsupported operation", // 7 + "No device", // 8 + "I/O failure", // 9 + "Bad invocation", // 10 + "No such path", // 11 + "Busy", // 12 + "Buffer too small", // 13 + "Out of memory", // 14 + }; + + if (statusCode > 0 && statusCode <= 14) { + return statusText[statusCode]; + } else { + return "Unknown error"; + } +} + +inline const char* GetStatusExplanationText(StatusCodes statusCode) { + const char* explanationText[] = { + nullptr, // 0 + nullptr, // 1 + nullptr, // 2 + nullptr, // 3 + "The path is protected by the system and can't be modified.", // 4 + nullptr, // 5 + nullptr, // 6 + nullptr, // 7 + nullptr, // 8 + nullptr, // 9 + nullptr, // 10 + nullptr, // 11 + nullptr, // 12 + "The buffer supplied by the caller is too small.", // 13 + nullptr, // 14 + }; + + if (statusCode > 0 && statusCode <= 14) { + if (explanationText[statusCode] != nullptr) { + return explanationText[statusCode]; + } + } + + return GetStatusText(statusCode); +} #ifdef __cplusplus } diff --git a/programs/src/init/main.cpp b/programs/src/init/main.cpp index 83e34be..520540a 100644 --- a/programs/src/init/main.cpp +++ b/programs/src/init/main.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include // ---- ANSI color codes ---- @@ -204,7 +205,7 @@ const char* getReleaseString(char* buffer, int n) { extern "C" void _start() { if (system_already_initialized()) { - montauk::exit(1); + montauk::exit(montauk::StatusCodes::BadInvocation); } char releaseString[128] = ""; diff --git a/programs/src/shell/exec.cpp b/programs/src/shell/exec.cpp index 294df8d..f42f846 100644 --- a/programs/src/shell/exec.cpp +++ b/programs/src/shell/exec.cpp @@ -17,7 +17,9 @@ static bool file_exists(const char* path) { // ---- Try to spawn an ELF at the given path ---- -static void print_exit_code(int code) { +static void print_exit_code(const int exitCode) { + int code = exitCode; + if (code == 0) return; char buf[16]; int n = 0; @@ -36,6 +38,16 @@ static void print_exit_code(int code) { char c[2] = { buf[--n], 0 }; montauk::print(c); } + + if (exitCode > 0 && exitCode <= 14) { // 0-14 - current range of status codes within StatusCodes enum + const char* statusText = montauk::GetStatusText((montauk::StatusCodes)exitCode); + + if (statusText != nullptr) { + montauk::print(" - "); + montauk::print(statusText); + } + } + montauk::print("]\n"); } diff --git a/scripts/montauk-syscalls.py b/scripts/montauk-syscalls.py index 043e09d..60a43a6 100755 --- a/scripts/montauk-syscalls.py +++ b/scripts/montauk-syscalls.py @@ -4,7 +4,6 @@ # # Source of truth : programs/include/Api/Syscall.hpp (montauk::abi::SYS_*) # kernel/src/Common/StatusCodes.hpp (enum StatusCodes) -# Mirrors : programs/include/montauk/statuscodes.h (must match exactly) # Generated blocks: programs/include/libc/montauk.h (#define MTK_SYS_*, # #define MTK_STATUS_*) # @@ -16,13 +15,11 @@ # # Usage: # montauk-syscalls.py check Verify every SYS_* has a matching MTK_SYS_* with -# the same number, and that both status code -# mirrors match the kernel enum. Exits non-zero on -# any drift. Run from the build so stale headers -# fail loudly. +# the same number, and that MTK_STATUS_* matches +# the kernel enum. Exits non-zero on any drift. +# Run from the build so stale headers fail loudly. # montauk-syscalls.py gen Rewrite the MTK_SYS_* and MTK_STATUS_* blocks in # montauk.h (numbers only; wrappers untouched). -# statuscodes.h is not generated; fix it by hand. import os import re @@ -33,7 +30,6 @@ REPO_ROOT = os.path.dirname(SCRIPT_DIR) ABI_HDR = os.path.join(REPO_ROOT, "programs/include/Api/Syscall.hpp") C_HDR = os.path.join(REPO_ROOT, "programs/include/libc/montauk.h") STATUS_HDR = os.path.join(REPO_ROOT, "kernel/src/Common/StatusCodes.hpp") -STATUS_MIRROR = os.path.join(REPO_ROOT, "programs/include/montauk/statuscodes.h") BEGIN_MARKER = "/* @SYSCALLS-BEGIN" END_MARKER = "/* @SYSCALLS-END */" @@ -91,16 +87,9 @@ def status_macro(name): def check_status(c_text): - """Print drift between the kernel enum and its two mirrors; return count.""" + """Print drift between the kernel enum and MTK_STATUS_*; return count.""" canon = parse_status(STATUS_HDR) problems = 0 - mirror = parse_status(STATUS_MIRROR) - if mirror != canon: - problems += 1 - print("montauk-syscalls: DRIFT between Common/StatusCodes.hpp and " - "montauk/statuscodes.h", file=sys.stderr) - print(" kernel: %s" % canon, file=sys.stderr) - print(" mirror: %s" % mirror, file=sys.stderr) want = {status_macro(n): v for n, v in canon} have = {n: int(v) for n, v in STATUS_DEF_RE.findall(c_text)} if want != have: @@ -132,8 +121,8 @@ def cmd_check(): status_problems = check_status(c_text) if not (missing or mismatched or extra): if status_problems: - print("\n Run 'make gen-syscalls' to regenerate MTK_STATUS_*; " - "montauk/statuscodes.h is fixed by hand.", file=sys.stderr) + print("\n Run 'make gen-syscalls' to regenerate MTK_STATUS_*.", + file=sys.stderr) return 1 print("montauk-syscalls: OK (%d syscalls, %d status codes in sync)" % (len(abi), len(parse_status(STATUS_HDR))))