diff --git a/programs/include/montauk/statuscodes.h b/programs/include/montauk/statuscodes.h index a078ea0..2f94f00 100644 --- a/programs/include/montauk/statuscodes.h +++ b/programs/include/montauk/statuscodes.h @@ -60,6 +60,13 @@ inline const char* GetStatusText(StatusCode statusCode) { } } +// Map a raw syscall result to a StatusCode. +inline StatusCode StatusFromResult(long long rc) { + if (rc >= 0) return Success; + if (rc < -(long long)WouldBlock) return GenericFailure; + return (StatusCode)(-rc); +} + // Shared with C (libc.c), so no nullptr. inline const char* GetStatusExplanationText(StatusCode statusCode) { const char* explanationText[] = { diff --git a/programs/lib/libc/libc.c b/programs/lib/libc/libc.c index a3bbc03..44d8207 100644 --- a/programs/lib/libc/libc.c +++ b/programs/lib/libc/libc.c @@ -2494,7 +2494,7 @@ char *getcwd(char *buf, size_t size) { } int result = (int)_mtk_syscall2(SYS_GETCWD, (long)buf, (long)size); if (result < 0) { - errno = result == BufferTooSmall ? ERANGE : EIO; + errno = result == -BufferTooSmall ? ERANGE : EIO; return NULL; } return buf; @@ -3584,10 +3584,11 @@ int utime(const char *path, const struct utimbuf *times) { times != NULL ? (long)times->modtime : 0, times == NULL); if (result == 0) return 0; - if (result == UnsupportedOp) errno = ENOTSUP; - else if (result == InvalidArgument) errno = EOVERFLOW; - else if (result == IoFailure) errno = EIO; - else if (result == SystemIntegrityError) errno = EPERM; + /* The kernel returns StatusCodes negated. */ + if (result == -UnsupportedOp) errno = ENOTSUP; + else if (result == -InvalidArgument) errno = EOVERFLOW; + else if (result == -IoFailure) errno = EIO; + else if (result == -SystemIntegrityError) errno = EPERM; else errno = ENOENT; return -1; } diff --git a/programs/src/desktop/apps/filemanager/filemanager_internal.hpp b/programs/src/desktop/apps/filemanager/filemanager_internal.hpp index ba700a2..848f6df 100644 --- a/programs/src/desktop/apps/filemanager/filemanager_internal.hpp +++ b/programs/src/desktop/apps/filemanager/filemanager_internal.hpp @@ -234,10 +234,7 @@ void filemanager_read_system_configuration(FileManagerState* fm); // Map a raw syscall result (kernel StatusCodes are negative) to a userspace // montauk::StatusCodes. Non-negative results (handles, counts) are Success. inline montauk::StatusCode filemanager_status_from_result(int rc) { - if (rc >= 0) return montauk::Success; - int code = -rc; - if (code > montauk::OutOfMemory) return montauk::GenericFailure; - return (montauk::StatusCode)code; + return montauk::StatusFromResult(rc); } // The path itself may not be modified. Falling back to copy + delete after a diff --git a/programs/src/display/main.cpp b/programs/src/display/main.cpp index 77455b2..d6b0653 100644 --- a/programs/src/display/main.cpp +++ b/programs/src/display/main.cpp @@ -501,7 +501,7 @@ static void apply_changes() { if (g_driver_available && g_selected_mode != g_info.currentMode) { int result = montauk::display_set_mode(g_selected_mode); if (result < 0) { - set_status(result == montauk::UnsupportedOp + set_status(montauk::StatusFromResult(result) == montauk::UnsupportedOp ? "Mode needs unsupported display-link training" : "Mode change failed; previous mode restored"); refresh_state(true); diff --git a/programs/src/login/login_shutdown.cpp b/programs/src/login/login_shutdown.cpp index bf0dcdd..36308e0 100644 --- a/programs/src/login/login_shutdown.cpp +++ b/programs/src/login/login_shutdown.cpp @@ -262,7 +262,7 @@ void perform_graceful_shutdown(LoginState* ls, int action) { // A successful power-control syscall never returns. If it does return, // keep the trusted supervisor alive and make the authorization failure // visible instead of falling through an unreachable-code assumption. - show_stage(ls, heading, rc == montauk::CapabilityDenied + show_stage(ls, heading, montauk::StatusFromResult(rc) == montauk::CapabilityDenied ? "Power control permission denied." : "Power control failed."); for (;;) montauk::sleep_ms(1000); diff --git a/programs/src/reset/main.cpp b/programs/src/reset/main.cpp index 9f0bde7..b4278e4 100644 --- a/programs/src/reset/main.cpp +++ b/programs/src/reset/main.cpp @@ -9,7 +9,7 @@ extern "C" void _start() { montauk::print("Rebooting...\n"); int rc = montauk::reset(); - if (rc == montauk::CapabilityDenied) + if (montauk::StatusFromResult(rc) == montauk::CapabilityDenied) montauk::print("reset: permission denied\n"); else montauk::print("reset: reboot failed\n"); diff --git a/programs/src/shell/main.cpp b/programs/src/shell/main.cpp index 1ef09e5..2b19f77 100644 --- a/programs/src/shell/main.cpp +++ b/programs/src/shell/main.cpp @@ -196,7 +196,7 @@ static int process_command(const char* line) { : montauk::abi::POWER_REQ_SHUTDOWN; int rc = montauk::power_request(action); if (rc == 0) montauk::exit(0); - montauk::print(rc == montauk::CapabilityDenied + montauk::print(montauk::StatusFromResult(rc) == montauk::CapabilityDenied ? "power: permission denied\n" : "power: request failed\n"); return 1; @@ -204,7 +204,7 @@ static int process_command(const char* line) { if (streq(cmd, "suspend")) { int rc = montauk::suspend(); - if (rc == montauk::CapabilityDenied) + if (montauk::StatusFromResult(rc) == montauk::CapabilityDenied) montauk::print("suspend: permission denied\n"); return rc == 0 ? 0 : 1; }