ATF_TC_BODY (status_signaled, tc) { { const int rawstatus = fork_and_wait_child (child_sigkill); atf_process_status_t s; RE (atf_process_status_init (&s, rawstatus)); ATF_CHECK (!atf_process_status_exited (&s)); ATF_CHECK (atf_process_status_signaled (&s)); ATF_CHECK_EQ (atf_process_status_termsig (&s), SIGKILL); ATF_CHECK (!atf_process_status_coredump (&s)); atf_process_status_fini (&s); } { const int rawstatus = fork_and_wait_child (child_sigterm); atf_process_status_t s; RE (atf_process_status_init (&s, rawstatus)); ATF_CHECK (!atf_process_status_exited (&s)); ATF_CHECK (atf_process_status_signaled (&s)); ATF_CHECK_EQ (atf_process_status_termsig (&s), SIGTERM); ATF_CHECK (!atf_process_status_coredump (&s)); atf_process_status_fini (&s); } }
ATF_TC_BODY (status_exited, tc) { { const int rawstatus = fork_and_wait_child (child_exit_success); atf_process_status_t s; RE (atf_process_status_init (&s, rawstatus)); ATF_CHECK (atf_process_status_exited (&s)); ATF_CHECK_EQ (atf_process_status_exitstatus (&s), EXIT_SUCCESS); ATF_CHECK (!atf_process_status_signaled (&s)); atf_process_status_fini (&s); } { const int rawstatus = fork_and_wait_child (child_exit_failure); atf_process_status_t s; RE (atf_process_status_init (&s, rawstatus)); ATF_CHECK (atf_process_status_exited (&s)); ATF_CHECK_EQ (atf_process_status_exitstatus (&s), EXIT_FAILURE); ATF_CHECK (!atf_process_status_signaled (&s)); atf_process_status_fini (&s); } }
/* TODO: Investigate if it's worth to add this functionality as part of * the public API. I.e. a function to easily run a test case body in a * subprocess. */ void run_h_tc(atf_tc_t *tc, const char *outname, const char *errname, const char *resname) { atf_fs_path_t outpath, errpath; atf_process_stream_t outb, errb; atf_process_child_t child; atf_process_status_t status; RE(atf_fs_path_init_fmt(&outpath, outname)); RE(atf_fs_path_init_fmt(&errpath, errname)); struct run_h_tc_data data = { tc, resname }; RE(atf_process_stream_init_redirect_path(&outb, &outpath)); RE(atf_process_stream_init_redirect_path(&errb, &errpath)); RE(atf_process_fork(&child, run_h_tc_child, &outb, &errb, &data)); atf_process_stream_fini(&errb); atf_process_stream_fini(&outb); RE(atf_process_child_wait(&child, &status)); ATF_CHECK(atf_process_status_exited(&status)); atf_process_status_fini(&status); atf_fs_path_fini(&errpath); atf_fs_path_fini(&outpath); }
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); }
ATF_TC_BODY (exec_success, tc) { atf_process_status_t status; do_exec (tc, "exit-success", &status); ATF_CHECK (atf_process_status_exited (&status)); ATF_CHECK_EQ (atf_process_status_exitstatus (&status), EXIT_SUCCESS); atf_process_status_fini (&status); }
ATF_TC_BODY (exec_failure, tc) { atf_process_status_t status; do_exec (tc, "exit-failure", &status); ATF_CHECK (atf_process_status_exited (&status)); ATF_CHECK_EQ (atf_process_status_exitstatus (&status), EXIT_FAILURE); atf_process_status_fini (&status); }
ATF_TC_BODY (fork_cookie, tc) { atf_process_stream_t outsb, errsb; RE (atf_process_stream_init_inherit (&outsb)); RE (atf_process_stream_init_inherit (&errsb)); { atf_process_child_t child; atf_process_status_t status; RE (atf_process_fork (&child, child_cookie, &outsb, &errsb, NULL)); RE (atf_process_child_wait (&child, &status)); ATF_CHECK (atf_process_status_exited (&status)); ATF_CHECK_EQ (atf_process_status_exitstatus (&status), exit_v_null); atf_process_status_fini (&status); } { atf_process_child_t child; atf_process_status_t status; int dummy_int; RE (atf_process_fork (&child, child_cookie, &outsb, &errsb, &dummy_int)); RE (atf_process_child_wait (&child, &status)); ATF_CHECK (atf_process_status_exited (&status)); ATF_CHECK_EQ (atf_process_status_exitstatus (&status), exit_v_notnull); atf_process_status_fini (&status); } atf_process_stream_fini (&errsb); atf_process_stream_fini (&outsb); }
ATF_TC_BODY (status_coredump, tc) { struct rlimit rl; rl.rlim_cur = RLIM_INFINITY; rl.rlim_max = RLIM_INFINITY; if (setrlimit (RLIMIT_CORE, &rl) == -1) atf_tc_skip ("Cannot unlimit the core file size; check limits " "manually"); const int rawstatus = fork_and_wait_child (child_sigquit); atf_process_status_t s; RE (atf_process_status_init (&s, rawstatus)); ATF_CHECK (!atf_process_status_exited (&s)); ATF_CHECK (atf_process_status_signaled (&s)); ATF_CHECK_EQ (atf_process_status_termsig (&s), SIGQUIT); ATF_CHECK (atf_process_status_coredump (&s)); atf_process_status_fini (&s); }
ATF_TC_BODY (exec_list, tc) { atf_fs_path_t process_helpers; atf_list_t argv; atf_process_status_t status; RE (atf_list_init (&argv)); get_process_helpers_path (tc, true, &process_helpers); atf_list_append (&argv, strdup (atf_fs_path_cstring (&process_helpers)), true); atf_list_append (&argv, strdup ("echo"), true); atf_list_append (&argv, strdup ("test-message"), true); { atf_fs_path_t outpath; atf_process_stream_t outsb; RE (atf_fs_path_init_fmt (&outpath, "stdout")); RE (atf_process_stream_init_redirect_path (&outsb, &outpath)); RE (atf_process_exec_list (&status, &process_helpers, &argv, &outsb, NULL)); atf_process_stream_fini (&outsb); atf_fs_path_fini (&outpath); } atf_list_fini (&argv); ATF_CHECK (atf_process_status_exited (&status)); ATF_CHECK_EQ (atf_process_status_exitstatus (&status), EXIT_SUCCESS); { int fd = open ("stdout", O_RDONLY); ATF_CHECK (fd != -1); check_line (fd, "test-message"); close (fd); } atf_process_status_fini (&status); atf_fs_path_fini (&process_helpers); }
ATF_TC_BODY (child_wait_eintr, tc) { atf_process_child_t child; atf_process_status_t status; { atf_process_stream_t outsb, errsb; RE (atf_process_stream_init_capture (&outsb)); RE (atf_process_stream_init_inherit (&errsb)); RE (atf_process_fork (&child, child_spawn_loop_and_wait_eintr, &outsb, &errsb, NULL)); atf_process_stream_fini (&outsb); atf_process_stream_fini (&errsb); } { /* Wait until the child process performs the wait call. This is * racy, because the message we get from it is sent *before* * doing the real system call... but I can't figure any other way * to do this. */ char buf[16]; printf ("Waiting for child to issue wait(2)\n"); ATF_REQUIRE (read (atf_process_child_stdout (&child), buf, sizeof (buf)) > 0); sleep (1); } printf ("Interrupting child's wait(2) call\n"); kill (atf_process_child_pid (&child), SIGHUP); printf ("Waiting for child's completion\n"); RE (atf_process_child_wait (&child, &status)); ATF_REQUIRE (atf_process_status_exited (&status)); ATF_REQUIRE_EQ (atf_process_status_exitstatus (&status), EXIT_SUCCESS); atf_process_status_fini (&status); }
bool impl::status::exited(void) const { return atf_process_status_exited(&m_status); }