Changeset View
Changeset View
Standalone View
Standalone View
contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c
Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
#include <unistd.h> | #include <unistd.h> | ||||
static void | static void | ||||
handler(int signo __unused) | handler(int signo __unused) | ||||
{ | { | ||||
/* Nothing. */ | /* Nothing. */ | ||||
} | } | ||||
static int got_info; | |||||
static void | |||||
info_handler(int signo __unused) | |||||
{ | |||||
got_info = 1; | |||||
} | |||||
ATF_TC(nanosleep_basic); | ATF_TC(nanosleep_basic); | ||||
ATF_TC_HEAD(nanosleep_basic, tc) | ATF_TC_HEAD(nanosleep_basic, tc) | ||||
{ | { | ||||
atf_tc_set_md_var(tc, "descr", "Test that nanosleep(2) works"); | atf_tc_set_md_var(tc, "descr", "Test that nanosleep(2) works"); | ||||
} | } | ||||
ATF_TC_BODY(nanosleep_basic, tc) | ATF_TC_BODY(nanosleep_basic, tc) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | ATF_TC_BODY(nanosleep_sig, tc) | ||||
(void)sleep(1); | (void)sleep(1); | ||||
(void)kill(pid, SIGINT); | (void)kill(pid, SIGINT); | ||||
(void)wait(&sta); | (void)wait(&sta); | ||||
if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) | if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) | ||||
atf_tc_fail("signal did not interrupt nanosleep(2)"); | atf_tc_fail("signal did not interrupt nanosleep(2)"); | ||||
} | } | ||||
ATF_TC(nanosleep_eintr); | |||||
ATF_TC_HEAD(nanosleep_eintr, tc) | |||||
{ | |||||
atf_tc_set_md_var(tc, "descr", "Test [EINTR] for nanosleep(2)"); | |||||
atf_tc_set_md_var(tc, "timeout", "7"); | |||||
} | |||||
ATF_TC_BODY(nanosleep_eintr, tc) | |||||
{ | |||||
struct sigaction act; | |||||
struct timespec tso, ts; | |||||
pid_t pid, floodpid; | |||||
int sta; | |||||
/* | |||||
* Test that [EINTR] properly handles rmtp for nanosleep(2). | |||||
*/ | |||||
pid = fork(); | |||||
ATF_REQUIRE(pid >= 0); | |||||
got_info = 0; | |||||
if (pid == 0) { | |||||
act.sa_handler = info_handler; | |||||
sigemptyset(&act.sa_mask); | |||||
act.sa_flags = 0; /* Don't allow restart. */ | |||||
ATF_REQUIRE(sigaction(SIGINFO, &act, NULL) == 0); | |||||
markj: I'm not sure that ATF_REQUIRE will DTRT in a child process. | |||||
Not Done Inline ActionsIt ends up exiting non-zero which the later wait does pickup on. See my testing example. bdrewery: It ends up exiting non-zero which the later wait does pickup on. See my testing example. | |||||
tso.tv_sec = 5; | |||||
tso.tv_nsec = 0; | |||||
ts.tv_sec = tso.tv_sec; | |||||
ts.tv_nsec = tso.tv_nsec; | |||||
errno = 0; | |||||
while (nanosleep(&ts, &ts) != 0) { | |||||
if (errno == EINTR && got_info == 1) { | |||||
ATF_REQUIRE_MSG(timespeccmp(&ts, &tso, <=), | |||||
"errno: %d got_info: %d " | |||||
"ts=%0.9f should be <= tso=%0.9f\n", | |||||
errno, got_info, | |||||
ts.tv_sec + ts.tv_nsec / 1e9, | |||||
tso.tv_sec + tso.tv_nsec / 1e9); | |||||
got_info = 0; | |||||
errno = 0; | |||||
continue; | |||||
} | |||||
_exit(EXIT_FAILURE); | |||||
} | |||||
if (errno != 0) | |||||
_exit(EXIT_FAILURE); | |||||
_exit(EXIT_SUCCESS); | |||||
} | |||||
/* Fork a process to signal flood the child. */ | |||||
floodpid = fork(); | |||||
ATF_REQUIRE(floodpid >= 0); | |||||
if (floodpid == 0) { | |||||
Not Done Inline ActionsI think it's reasonable to use ATF_REQUIRE to check the return values of these syscalls. markj: I think it's reasonable to use ATF_REQUIRE to check the return values of these syscalls. | |||||
Not Done Inline ActionsSure bdrewery: Sure | |||||
while (1) { | |||||
(void)kill(pid, SIGINFO); | |||||
(void)usleep(50000); | |||||
} | |||||
} | |||||
(void)waitpid(pid, &sta, 0); | |||||
(void)kill(floodpid, SIGKILL); | |||||
if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) | |||||
atf_tc_fail("nanosleep(2) handled rtmp incorrectly"); | |||||
} | |||||
ATF_TP_ADD_TCS(tp) | ATF_TP_ADD_TCS(tp) | ||||
{ | { | ||||
ATF_TP_ADD_TC(tp, nanosleep_basic); | ATF_TP_ADD_TC(tp, nanosleep_basic); | ||||
ATF_TP_ADD_TC(tp, nanosleep_err); | ATF_TP_ADD_TC(tp, nanosleep_err); | ||||
ATF_TP_ADD_TC(tp, nanosleep_sig); | ATF_TP_ADD_TC(tp, nanosleep_sig); | ||||
ATF_TP_ADD_TC(tp, nanosleep_eintr); | |||||
return atf_no_error(); | return atf_no_error(); | ||||
} | } |
I'm not sure that ATF_REQUIRE will DTRT in a child process.