From 1334ca42c672320cd7113cbcbc253cd93bf158b8 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Thu, 30 Jan 2025 20:49:41 +0100 Subject: Correctly return errors caused bu sub-process signals such as segfaults and aborts. --- src/execute.cc | 32 +++++++++++++++++++++++++++++--- test/execute_test.cc | 6 ++++++ test/testprog.cc | 8 ++++++-- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/execute.cc b/src/execute.cc index 17f8714..a905efc 100644 --- a/src/execute.cc +++ b/src/execute.cc @@ -48,12 +48,38 @@ int parent_waitpid(pid_t pid) { int status{}; - if(waitpid(pid, &status, 0) != pid) + auto rc_pid = waitpid(pid, &status, 0); + + if(rc_pid > 0) { - return 1; + if(WIFEXITED(status)) + { + // Child exited with normally + return WEXITSTATUS(status); + } + if(WIFSIGNALED(status)) + { + // Child exited via signal (segfault, abort, ...) + std::cerr << strsignal(status) << '\n'; + return WTERMSIG(status); + } + } + else + { // No PID returned, this is an error + if(errno == ECHILD) + { + // No children exist. + return 1; + } + else + { + // Unexpected error. + abort(); + } } - return WEXITSTATUS(status); + // Should never happen... + return 1; } } // namespace :: diff --git a/test/execute_test.cc b/test/execute_test.cc index 4c686bf..722b6ea 100644 --- a/test/execute_test.cc +++ b/test/execute_test.cc @@ -35,6 +35,12 @@ public: uASSERT_EQUAL(1, value); value = execute(s, "no-such-binary", {}, {}, false); uASSERT_EQUAL(1, value); + value = execute(s, cmd, {"segfault"}, {}, false); + uASSERT_EQUAL(11, value); + value = execute(s, cmd, {"throw"}, {}, false); + uASSERT_EQUAL(6, value); + value = execute(s, cmd, {"abort"}, {}, false); + uASSERT_EQUAL(6, value); } void env() diff --git a/test/testprog.cc b/test/testprog.cc index dbfb665..faf1498 100644 --- a/test/testprog.cc +++ b/test/testprog.cc @@ -1,8 +1,7 @@ #include #include #include - -extern const char **environ; // see 'man environ' +#include int main(int argc, const char* argv[]) { @@ -40,6 +39,11 @@ int main(int argc, const char* argv[]) abort(); } + if(cmd == "segfault") + { + raise(SIGSEGV); + } + if(cmd == "throw") { throw "ouch"; -- cgit v1.2.3