Changeset View
Changeset View
Standalone View
Standalone View
contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c
Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
The NetBSD Foundation, inc. All rights reserved."); | The NetBSD Foundation, inc. All rights reserved."); | ||||
__RCSID("$NetBSD: t_setjmp.c,v 1.2 2017/01/14 21:08:17 christos Exp $"); | __RCSID("$NetBSD: t_setjmp.c,v 1.2 2017/01/14 21:08:17 christos Exp $"); | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <setjmp.h> | #include <setjmp.h> | ||||
#include <signal.h> | #include <signal.h> | ||||
#include <stdbool.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <atf-c.h> | #include <atf-c.h> | ||||
#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) | #define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) | ||||
#define TEST_SETJMP 0 | #define TEST_SETJMP 0 | ||||
#define TEST_U_SETJMP 1 | #define TEST_U_SETJMP 1 | ||||
#define TEST_SIGSETJMP_SAVE 2 | #define TEST_SIGSETJMP_SAVE 2 | ||||
#define TEST_SIGSETJMP_NOSAVE 3 | #define TEST_SIGSETJMP_NOSAVE 3 | ||||
#define TEST_LONGJMP_ZERO 4 | |||||
#define TEST_U_LONGJMP_ZERO 5 | |||||
static int expectsignal; | static int expectsignal; | ||||
static void | static void | ||||
aborthandler(int signo __unused) | aborthandler(int signo __unused) | ||||
{ | { | ||||
ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded"); | ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded"); | ||||
atf_tc_pass(); | atf_tc_pass(); | ||||
} | } | ||||
static void | static void | ||||
h_check(int test) | h_check(int test) | ||||
{ | { | ||||
struct sigaction sa; | struct sigaction sa; | ||||
jmp_buf jb; | jmp_buf jb; | ||||
sigjmp_buf sjb; | sigjmp_buf sjb; | ||||
sigset_t ss; | sigset_t ss; | ||||
int i, x; | int i, x; | ||||
volatile bool did_longjmp; | |||||
i = getpid(); | i = getpid(); | ||||
did_longjmp = false; | |||||
if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE) | if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE || | ||||
test == TEST_LONGJMP_ZERO) | |||||
expectsignal = 0; | expectsignal = 0; | ||||
else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE) | else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE || | ||||
test == TEST_U_LONGJMP_ZERO) | |||||
expectsignal = 1; | expectsignal = 1; | ||||
else | else | ||||
atf_tc_fail("unknown test"); | atf_tc_fail("unknown test"); | ||||
sa.sa_handler = aborthandler; | sa.sa_handler = aborthandler; | ||||
sigemptyset(&sa.sa_mask); | sigemptyset(&sa.sa_mask); | ||||
sa.sa_flags = 0; | sa.sa_flags = 0; | ||||
REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1); | REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1); | ||||
REQUIRE_ERRNO(sigemptyset(&ss) != -1); | REQUIRE_ERRNO(sigemptyset(&ss) != -1); | ||||
REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1); | REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1); | ||||
REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1); | REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1); | ||||
if (test == TEST_SETJMP) | if (test == TEST_SETJMP || test == TEST_LONGJMP_ZERO) | ||||
x = setjmp(jb); | x = setjmp(jb); | ||||
else if (test == TEST_U_SETJMP) | else if (test == TEST_U_SETJMP || test == TEST_U_LONGJMP_ZERO) | ||||
x = _setjmp(jb); | x = _setjmp(jb); | ||||
else | else | ||||
x = sigsetjmp(sjb, !expectsignal); | x = sigsetjmp(sjb, !expectsignal); | ||||
if (x != 0) { | if (x != 0) { | ||||
if (test == TEST_LONGJMP_ZERO || test == TEST_U_LONGJMP_ZERO) | |||||
ATF_REQUIRE_MSG(x == 1, "setjmp returned wrong value"); | |||||
else | |||||
ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value"); | ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value"); | ||||
kill(i, SIGABRT); | kill(i, SIGABRT); | ||||
ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed"); | ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed"); | ||||
atf_tc_pass(); | atf_tc_pass(); | ||||
} else if (did_longjmp) { | |||||
atf_tc_fail("setjmp returned zero after longjmp"); | |||||
} | } | ||||
REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1); | REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1); | ||||
did_longjmp = true; | |||||
if (test == TEST_SETJMP) | if (test == TEST_SETJMP) | ||||
longjmp(jb, i); | longjmp(jb, i); | ||||
else if (test == TEST_LONGJMP_ZERO) | |||||
longjmp(jb, 0); | |||||
else if (test == TEST_U_SETJMP) | else if (test == TEST_U_SETJMP) | ||||
_longjmp(jb, i); | _longjmp(jb, i); | ||||
else if (test == TEST_U_LONGJMP_ZERO) | |||||
_longjmp(jb, 0); | |||||
else | else | ||||
siglongjmp(sjb, i); | siglongjmp(sjb, i); | ||||
atf_tc_fail("jmp failed"); | atf_tc_fail("jmp failed"); | ||||
} | } | ||||
ATF_TC(setjmp); | ATF_TC(setjmp); | ||||
ATF_TC_HEAD(setjmp, tc) | ATF_TC_HEAD(setjmp, tc) | ||||
Show All 30 Lines | |||||
{ | { | ||||
atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask disabled"); | atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask disabled"); | ||||
} | } | ||||
ATF_TC_BODY(sigsetjmp_nosave, tc) | ATF_TC_BODY(sigsetjmp_nosave, tc) | ||||
{ | { | ||||
h_check(TEST_SIGSETJMP_NOSAVE); | h_check(TEST_SIGSETJMP_NOSAVE); | ||||
} | } | ||||
ATF_TC(longjmp_zero); | |||||
ATF_TC_HEAD(longjmp_zero, tc) | |||||
{ | |||||
atf_tc_set_md_var(tc, "descr", "Checks longjmp(3) with a zero value"); | |||||
} | |||||
ATF_TC_BODY(longjmp_zero, tc) | |||||
{ | |||||
h_check(TEST_LONGJMP_ZERO); | |||||
} | |||||
ATF_TC(_longjmp_zero); | |||||
ATF_TC_HEAD(_longjmp_zero, tc) | |||||
{ | |||||
atf_tc_set_md_var(tc, "descr", "Checks _longjmp(3) with a zero value"); | |||||
} | |||||
ATF_TC_BODY(_longjmp_zero, tc) | |||||
{ | |||||
h_check(TEST_U_LONGJMP_ZERO); | |||||
} | |||||
ATF_TP_ADD_TCS(tp) | ATF_TP_ADD_TCS(tp) | ||||
{ | { | ||||
ATF_TP_ADD_TC(tp, setjmp); | ATF_TP_ADD_TC(tp, setjmp); | ||||
ATF_TP_ADD_TC(tp, _setjmp); | ATF_TP_ADD_TC(tp, _setjmp); | ||||
ATF_TP_ADD_TC(tp, sigsetjmp_save); | ATF_TP_ADD_TC(tp, sigsetjmp_save); | ||||
ATF_TP_ADD_TC(tp, sigsetjmp_nosave); | ATF_TP_ADD_TC(tp, sigsetjmp_nosave); | ||||
ATF_TP_ADD_TC(tp, longjmp_zero); | |||||
ATF_TP_ADD_TC(tp, _longjmp_zero); | |||||
return atf_no_error(); | return atf_no_error(); | ||||
} | } |