From 4e530135d554adf4e3edfafc580585b07b3b07ce Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 22 Nov 2021 16:00:53 +0100 Subject: [PATCH] AK+LibSystem+LibMain: Add Error::from_syscall() for syscall failures This creates an error that contains the name of the syscall that failed. This allows error handlers to print out the name of the call if they want to. :^) --- AK/Error.h | 10 ++++++++++ Userland/Libraries/LibMain/Main.cpp | 9 ++++++++- Userland/Libraries/LibSystem/Wrappers.cpp | 14 ++++++++------ 3 files changed, 26 insertions(+), 7 deletions(-) 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); } }