diff --git a/AK/Error.h b/AK/Error.h index 1346cb02d9..b25e8348ee 100644 --- a/AK/Error.h +++ b/AK/Error.h @@ -21,9 +21,11 @@ namespace AK { class Error { public: static Error from_errno(int code) { return Error(code); } + static Error from_syscall(StringView syscall_name, int rc) { return Error(syscall_name, rc); } static Error from_string_literal(StringView string_literal) { return Error(string_literal); } bool is_errno() const { return m_code != 0; } + bool is_syscall() const { return m_syscall; } int code() const { return m_code; } StringView string_literal() const { return m_string_literal; } @@ -40,8 +42,16 @@ private: { } + Error(StringView syscall_name, int rc) + : m_code(-rc) + , m_string_literal(syscall_name) + , m_syscall(true) + { + } + int m_code { 0 }; StringView m_string_literal; + bool m_syscall { false }; }; template diff --git a/Userland/Libraries/LibMain/Main.cpp b/Userland/Libraries/LibMain/Main.cpp index 1cee6c2e49..6c1c76425a 100644 --- a/Userland/Libraries/LibMain/Main.cpp +++ b/Userland/Libraries/LibMain/Main.cpp @@ -8,6 +8,7 @@ #include #include #include +#include int main(int argc, char** argv) { @@ -22,7 +23,13 @@ int main(int argc, char** argv) .arguments = arguments.span(), }); if (result.is_error()) { - warnln("Runtime error: {}", result.error()); + auto error = result.release_error(); + if (error.is_syscall()) + warnln("Runtime error: {}: {} (errno={})", error.string_literal(), strerror(error.code()), error.code()); + else if (error.is_errno()) + warnln("Runtime error: {} (errno={})", strerror(error.code()), error.code()); + else + warnln("Runtime error: {}", error.string_literal()); return 1; } return result.value(); diff --git a/Userland/Libraries/LibSystem/Wrappers.cpp b/Userland/Libraries/LibSystem/Wrappers.cpp index 7045d7c786..a614c732e6 100644 --- a/Userland/Libraries/LibSystem/Wrappers.cpp +++ b/Userland/Libraries/LibSystem/Wrappers.cpp @@ -7,6 +7,12 @@ #include #include +#define HANDLE_SYSCALL_RETURN_VALUE(syscall_name, rc) \ + if ((rc) < 0) { \ + return Error::from_syscall(syscall_name, rc); \ + } \ + return {}; + namespace System { ErrorOr pledge(StringView promises, StringView execpromises) @@ -16,9 +22,7 @@ ErrorOr pledge(StringView promises, StringView execpromises) { execpromises.characters_without_null_termination(), execpromises.length() }, }; int rc = syscall(SC_pledge, ¶ms); - if (rc < 0) - return Error::from_errno(-rc); - return {}; + HANDLE_SYSCALL_RETURN_VALUE("pledge"sv, rc); } ErrorOr unveil(StringView path, StringView permissions) @@ -28,9 +32,7 @@ ErrorOr unveil(StringView path, StringView permissions) { permissions.characters_without_null_termination(), permissions.length() }, }; int rc = syscall(SC_unveil, ¶ms); - if (rc < 0) - return Error::from_errno(-rc); - return {}; + HANDLE_SYSCALL_RETURN_VALUE("unveil"sv, rc); } }