diff --git a/Tests/LibC/CMakeLists.txt b/Tests/LibC/CMakeLists.txt index 0e1bf952c5..6922f76505 100644 --- a/Tests/LibC/CMakeLists.txt +++ b/Tests/LibC/CMakeLists.txt @@ -6,6 +6,7 @@ set(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCExec.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCDirEnt.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCInodeWatcher.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCSetjmp.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TestLibCString.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TestStackSmash.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TestIo.cpp diff --git a/Tests/LibC/TestLibCSetjmp.cpp b/Tests/LibC/TestLibCSetjmp.cpp new file mode 100644 index 0000000000..8e4facddd9 --- /dev/null +++ b/Tests/LibC/TestLibCSetjmp.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2021, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +TEST_CASE(setjmp) +{ + jmp_buf env; + volatile int set = 1; + + if (setjmp(env)) { + EXPECT_EQ(set, 0); + return; + } + + EXPECT_EQ(set, 1); + set = 0; + longjmp(env, 1); + + VERIFY_NOT_REACHED(); +} + +TEST_CASE(setjmp_zero) +{ + jmp_buf env; + volatile int set = 1; + + switch (setjmp(env)) { + case 0: + EXPECT_EQ(set, 1); + set = 0; + longjmp(env, 0); + VERIFY_NOT_REACHED(); + + case 1: + EXPECT_EQ(set, 0); + break; + + default: + VERIFY_NOT_REACHED(); + }; +} + +TEST_CASE(setjmp_value) +{ + jmp_buf env; + volatile int set = 1; + + switch (setjmp(env)) { + case 0: + EXPECT_EQ(set, 1); + set = 0; + longjmp(env, 0x789ABCDE); + VERIFY_NOT_REACHED(); + + case 0x789ABCDE: + EXPECT_EQ(set, 0); + break; + + default: + VERIFY_NOT_REACHED(); + }; +} + +TEST_CASE(sigsetjmp) +{ + sigjmp_buf env; + volatile int set = 1; + + if (sigsetjmp(env, 0)) { + EXPECT_EQ(set, 0); + return; + } + + EXPECT_EQ(set, 1); + set = 0; + siglongjmp(env, 1); + + VERIFY_NOT_REACHED(); +} + +TEST_CASE(sigsetjmp_zero) +{ + sigjmp_buf env; + volatile int set = 1; + + switch (sigsetjmp(env, 0)) { + case 0: + EXPECT_EQ(set, 1); + set = 0; + siglongjmp(env, 0); + VERIFY_NOT_REACHED(); + + case 1: + EXPECT_EQ(set, 0); + break; + + default: + VERIFY_NOT_REACHED(); + }; +} + +TEST_CASE(sigsetjmp_value) +{ + sigjmp_buf env; + volatile int set = 1; + + switch (sigsetjmp(env, 0)) { + case 0: + EXPECT_EQ(set, 1); + set = 0; + siglongjmp(env, 0x789ABCDE); + VERIFY_NOT_REACHED(); + + case 0x789ABCDE: + EXPECT_EQ(set, 0); + break; + + default: + VERIFY_NOT_REACHED(); + }; +} + +TEST_CASE(sigsetjmp_signal_mask) +{ + sigjmp_buf env; + + sigset_t alternative_sigset; + sigfillset(&alternative_sigset); + + sigset_t initial_sigset; + sigprocmask(SIG_SETMASK, nullptr, &initial_sigset); + + EXPECT_NE(memcmp(&alternative_sigset, &initial_sigset, sizeof(sigset_t)), 0); + + if (sigsetjmp(env, 1)) { + sigprocmask(SIG_SETMASK, nullptr, &alternative_sigset); + EXPECT_EQ(memcmp(&alternative_sigset, &initial_sigset, sizeof(sigset_t)), 0); + return; + } + + sigprocmask(SIG_SETMASK, &alternative_sigset, nullptr); + siglongjmp(env, 1); + VERIFY_NOT_REACHED(); +}