summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/execute.cc32
-rw-r--r--test/execute_test.cc6
-rw-r--r--test/testprog.cc8
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 <iostream>
#include <fstream>
#include <string>
-
-extern const char **environ; // see 'man environ'
+#include <signal.h>
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";