diff --git a/contrib/atf/atf-c/detail/process.h b/contrib/atf/atf-c/detail/process.h --- a/contrib/atf/atf-c/detail/process.h +++ b/contrib/atf/atf-c/detail/process.h @@ -28,6 +28,7 @@ #include +#include #include #include @@ -76,7 +77,7 @@ * --------------------------------------------------------------------- */ struct atf_process_status { - int m_status; + siginfo_t m_info; }; typedef struct atf_process_status atf_process_status_t; diff --git a/contrib/atf/atf-c/detail/process.c b/contrib/atf/atf-c/detail/process.c --- a/contrib/atf/atf-c/detail/process.c +++ b/contrib/atf/atf-c/detail/process.c @@ -42,7 +42,7 @@ /* This prototype is not in the header file because this is a private * function; however, we need to access it during testing. */ -atf_error_t atf_process_status_init(atf_process_status_t *, int); +atf_error_t atf_process_status_init(atf_process_status_t *, siginfo_t *); /* --------------------------------------------------------------------- * The "stream_prepare" auxiliary type. @@ -186,9 +186,9 @@ * --------------------------------------------------------------------- */ atf_error_t -atf_process_status_init(atf_process_status_t *s, int status) +atf_process_status_init(atf_process_status_t *s, siginfo_t *info) { - s->m_status = status; + memcpy(&s->m_info, info, sizeof(*info)); return atf_no_error(); } @@ -201,43 +201,35 @@ bool atf_process_status_exited(const atf_process_status_t *s) { - int mutable_status = s->m_status; - return WIFEXITED(mutable_status); + return s->m_info.si_code == CLD_EXITED; } int atf_process_status_exitstatus(const atf_process_status_t *s) { PRE(atf_process_status_exited(s)); - int mutable_status = s->m_status; - return WEXITSTATUS(mutable_status); + return s->m_info.si_status; } bool atf_process_status_signaled(const atf_process_status_t *s) { - int mutable_status = s->m_status; - return WIFSIGNALED(mutable_status); + int si_code = s->m_info.si_code; + return si_code == CLD_KILLED || si_code == CLD_DUMPED; } int atf_process_status_termsig(const atf_process_status_t *s) { PRE(atf_process_status_signaled(s)); - int mutable_status = s->m_status; - return WTERMSIG(mutable_status); + return s->m_info.si_status; } bool atf_process_status_coredump(const atf_process_status_t *s) { PRE(atf_process_status_signaled(s)); -#if defined(WCOREDUMP) - int mutable_status = s->m_status; - return WCOREDUMP(mutable_status); -#else - return false; -#endif + return s->m_info.si_code == CLD_DUMPED; } /* --------------------------------------------------------------------- @@ -269,14 +261,14 @@ atf_process_child_wait(atf_process_child_t *c, atf_process_status_t *s) { atf_error_t err; - int status; + siginfo_t info; - if (waitpid(c->m_pid, &status, 0) == -1) + if (waitid(P_PID, c->m_pid, &info, WEXITED) == -1) err = atf_libc_error(errno, "Failed waiting for process %d", c->m_pid); else { atf_process_child_fini(c); - err = atf_process_status_init(s, status); + err = atf_process_status_init(s, &info); } return err; diff --git a/contrib/atf/atf-c/detail/process_test.c b/contrib/atf/atf-c/detail/process_test.c --- a/contrib/atf/atf-c/detail/process_test.c +++ b/contrib/atf/atf-c/detail/process_test.c @@ -47,7 +47,7 @@ #include "atf-c/detail/sanity.h" #include "atf-c/detail/test_helpers.h" -atf_error_t atf_process_status_init(atf_process_status_t *, int); +atf_error_t atf_process_status_init(atf_process_status_t *, siginfo_t *); /* --------------------------------------------------------------------- * Auxiliary functions for testing of 'atf_process_fork'. @@ -576,23 +576,19 @@ } static -int -fork_and_wait_child(void (*child_func)(void)) +void +fork_and_wait_child(void (*child_func)(void), siginfo_t *info) { pid_t pid; - int status; pid = fork(); ATF_REQUIRE(pid != -1); if (pid == 0) { - status = 0; /* Silence compiler warnings */ child_func(); UNREACHABLE; } else { - ATF_REQUIRE(waitpid(pid, &status, 0) != 0); + ATF_REQUIRE(waitid(P_PID, pid, info, WEXITED) != -1); } - - return status; } ATF_TC(status_exited); @@ -603,10 +599,12 @@ } ATF_TC_BODY(status_exited, tc) { + siginfo_t info; + { - const int rawstatus = fork_and_wait_child(child_exit_success); + fork_and_wait_child(child_exit_success, &info); atf_process_status_t s; - RE(atf_process_status_init(&s, rawstatus)); + RE(atf_process_status_init(&s, &info)); ATF_CHECK(atf_process_status_exited(&s)); ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_SUCCESS); ATF_CHECK(!atf_process_status_signaled(&s)); @@ -614,9 +612,9 @@ } { - const int rawstatus = fork_and_wait_child(child_exit_failure); + fork_and_wait_child(child_exit_failure, &info); atf_process_status_t s; - RE(atf_process_status_init(&s, rawstatus)); + RE(atf_process_status_init(&s, &info)); ATF_CHECK(atf_process_status_exited(&s)); ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_FAILURE); ATF_CHECK(!atf_process_status_signaled(&s)); @@ -632,10 +630,12 @@ } ATF_TC_BODY(status_signaled, tc) { + siginfo_t info; + { - const int rawstatus = fork_and_wait_child(child_sigkill); + fork_and_wait_child(child_sigkill, &info); atf_process_status_t s; - RE(atf_process_status_init(&s, rawstatus)); + RE(atf_process_status_init(&s, &info)); ATF_CHECK(!atf_process_status_exited(&s)); ATF_CHECK(atf_process_status_signaled(&s)); ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGKILL); @@ -644,9 +644,9 @@ } { - const int rawstatus = fork_and_wait_child(child_sigterm); + fork_and_wait_child(child_sigterm, &info); atf_process_status_t s; - RE(atf_process_status_init(&s, rawstatus)); + RE(atf_process_status_init(&s, &info)); ATF_CHECK(!atf_process_status_exited(&s)); ATF_CHECK(atf_process_status_signaled(&s)); ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGTERM); @@ -678,9 +678,10 @@ atf_tc_skip("Coredumps disabled"); #endif - const int rawstatus = fork_and_wait_child(child_sigquit); + siginfo_t info; + fork_and_wait_child(child_sigquit, &info); atf_process_status_t s; - RE(atf_process_status_init(&s, rawstatus)); + RE(atf_process_status_init(&s, &info)); ATF_CHECK(!atf_process_status_exited(&s)); ATF_CHECK(atf_process_status_signaled(&s)); ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGQUIT); diff --git a/contrib/atf/atf-c/utils.c b/contrib/atf/atf-c/utils.c --- a/contrib/atf/atf-c/utils.c +++ b/contrib/atf/atf-c/utils.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -425,8 +426,9 @@ atf_utils_wait(const pid_t pid, const int exitstatus, const char *expout, const char *experr) { - int status; - ATF_REQUIRE(waitpid(pid, &status, 0) != -1); + siginfo_t info; + ATF_REQUIRE(waitid(P_PID, pid, &info, WEXITED) != -1); + ATF_REQUIRE(info.si_pid == pid); atf_dynstr_t out_name; init_out_filename(&out_name, pid, "out", true); @@ -437,8 +439,8 @@ atf_utils_cat_file(atf_dynstr_cstring(&out_name), "subprocess stdout: "); atf_utils_cat_file(atf_dynstr_cstring(&err_name), "subprocess stderr: "); - ATF_REQUIRE(WIFEXITED(status)); - ATF_REQUIRE_EQ(exitstatus, WEXITSTATUS(status)); + ATF_REQUIRE(info.si_code == CLD_EXITED); + ATF_REQUIRE_EQ(exitstatus, info.si_status); const char *save_prefix = "save:"; const size_t save_prefix_length = strlen(save_prefix); diff --git a/contrib/atf/atf-sh/atf-check.cpp b/contrib/atf/atf-sh/atf-check.cpp --- a/contrib/atf/atf-sh/atf-check.cpp +++ b/contrib/atf/atf-sh/atf-check.cpp @@ -201,12 +201,12 @@ { try { const int value = atf::text::to_type< int >(str); - if (value < 0 || value > 255) + if (value < INT_MIN || value > INT_MAX) throw std::runtime_error("Unused reason"); return value; } catch (const std::runtime_error&) { throw atf::application::usage_error("Invalid exit code for -s option; " - "must be an integer in range 0-255"); + "must be an integer in range [%d, %d]", INT_MIN, INT_MAX); } } diff --git a/contrib/atf/atf-sh/atf-check_test.sh b/contrib/atf/atf-sh/atf-check_test.sh --- a/contrib/atf/atf-sh/atf-check_test.sh +++ b/contrib/atf/atf-sh/atf-check_test.sh @@ -70,13 +70,12 @@ { h_pass "true" -s eq:0 h_pass "false" -s ne:0 - h_pass "exit 255" -s eq:255 + h_pass "exit 2147483647" -s eq:2147483647 h_pass "exit 0" -s ne:255 - h_fail "exit 256" -s eq:256 + h_fail "exit 2147483648" -s eq:2147483648 h_fail "exit -1" -s eq:-1 - h_fail "true" -s ne:256 - h_fail "true" -s ne:-1 + h_fail "true" -s ne:2147483649 } atf_test_case sflag_exit @@ -88,13 +87,12 @@ { h_pass 'true' -s exit:0 h_pass 'false' -s not-exit:0 - h_pass 'exit 255' -s exit:255 + h_pass 'exit 2147483647' -s exit:2147483647 h_pass 'exit 0' -s not-exit:255 - h_fail 'exit 256' -s exit:256 + h_fail 'exit 2147483648' -s exit:2147483648 h_fail 'exit -1' -s exit:-1 - h_fail 'true' -s not-exit:256 - h_fail 'true' -s not-exit:-1 + h_fail 'true' -s not-exit:2147483649 h_pass 'true' -s exit h_pass 'false' -s exit