diff options
author | Alex Brachet <alexbrachetmialot@gmail.com> | 2020-04-01 15:07:49 -0400 |
---|---|---|
committer | Alex Brachet <alexbrachetmialot@gmail.com> | 2020-04-01 15:07:49 -0400 |
commit | 123a5328f919bab8ea1344c05e9edc2c506c9d51 (patch) | |
tree | 83a1bf38222703f33f2612104f45b234e0336729 | |
parent | 3d9004879118c734fd9a5e112fb2bf22cf647668 (diff) | |
download | llvm-123a5328f919bab8ea1344c05e9edc2c506c9d51.zip llvm-123a5328f919bab8ea1344c05e9edc2c506c9d51.tar.gz llvm-123a5328f919bab8ea1344c05e9edc2c506c9d51.tar.bz2 |
[libc] Add sigfillset and sigdelset
Summary: Add's `sigfillset` and `sigdelset` which will be used in D76676.
Reviewers: sivachandra, PaulkaToast
Reviewed By: sivachandra
Subscribers: mgorny, MaskRay, tschuett, libc-commits
Differential Revision: https://reviews.llvm.org/D76936
-rw-r--r-- | libc/src/signal/linux/CMakeLists.txt | 26 | ||||
-rw-r--r-- | libc/src/signal/linux/sigdelset.cpp | 28 | ||||
-rw-r--r-- | libc/src/signal/linux/sigfillset.cpp | 28 | ||||
-rw-r--r-- | libc/src/signal/linux/signal.h | 13 | ||||
-rw-r--r-- | libc/src/signal/sigdelset.h | 20 | ||||
-rw-r--r-- | libc/src/signal/sigfillset.h | 20 | ||||
-rw-r--r-- | libc/test/src/signal/CMakeLists.txt | 31 | ||||
-rw-r--r-- | libc/test/src/signal/sigdelset_test.cpp | 36 | ||||
-rw-r--r-- | libc/test/src/signal/sigfillset_test.cpp | 29 |
9 files changed, 224 insertions, 7 deletions
diff --git a/libc/src/signal/linux/CMakeLists.txt b/libc/src/signal/linux/CMakeLists.txt index a3017e4..7992703 100644 --- a/libc/src/signal/linux/CMakeLists.txt +++ b/libc/src/signal/linux/CMakeLists.txt @@ -94,3 +94,29 @@ add_entrypoint_object( sigaction signal_h ) + +add_entrypoint_object( + sigfillset + SRCS + sigfillset.cpp + HDRS + signal.h + ../sigfillset.h + DEPENDS + __errno_location + errno_h + signal_h +) + +add_entrypoint_object( + sigdelset + SRCS + sigdelset.cpp + HDRS + signal.h + ../sigdelset.h + DEPENDS + __errno_location + errno_h + signal_h +) diff --git a/libc/src/signal/linux/sigdelset.cpp b/libc/src/signal/linux/sigdelset.cpp new file mode 100644 index 0000000..b04ec56 --- /dev/null +++ b/libc/src/signal/linux/sigdelset.cpp @@ -0,0 +1,28 @@ +//===----------------- Linux implementation of sigdelset ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/signal/sigdelset.h" +#include "include/errno.h" +#include "src/errno/llvmlibc_errno.h" +#include "src/signal/linux/signal.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +int LLVM_LIBC_ENTRYPOINT(sigdelset)(sigset_t *set, int signum) { + if (!set || (unsigned)(signum - 1) >= (8 * sizeof(sigset_t))) { + llvmlibc_errno = EINVAL; + return -1; + } + auto *sigset = reinterpret_cast<__llvm_libc::Sigset *>(set); + sigset->delset(signum); + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/signal/linux/sigfillset.cpp b/libc/src/signal/linux/sigfillset.cpp new file mode 100644 index 0000000..6c10da3 --- /dev/null +++ b/libc/src/signal/linux/sigfillset.cpp @@ -0,0 +1,28 @@ +//===----------------- Linux implementation of sigfillset -----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/signal/sigfillset.h" +#include "include/errno.h" +#include "src/errno/llvmlibc_errno.h" +#include "src/signal/linux/signal.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +int LLVM_LIBC_ENTRYPOINT(sigfillset)(sigset_t *set) { + if (!set) { + llvmlibc_errno = EINVAL; + return -1; + } + auto *sigset = reinterpret_cast<__llvm_libc::Sigset *>(set); + *sigset = __llvm_libc::Sigset::fullset(); + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/signal/linux/signal.h b/libc/src/signal/linux/signal.h index 93b33596..9a02ea7d 100644 --- a/libc/src/signal/linux/signal.h +++ b/libc/src/signal/linux/signal.h @@ -26,9 +26,9 @@ struct Sigset { constexpr static Sigset fullset() { return {-1UL}; } constexpr static Sigset emptySet() { return {0}; } - constexpr void addset(int signal) { - nativeSigset |= (1L << (signal - 1)); - } + constexpr void addset(int signal) { nativeSigset |= (1L << (signal - 1)); } + + constexpr void delset(int signal) { nativeSigset &= ~(1L << (signal - 1)); } operator sigset_t() const { return nativeSigset; } }; @@ -39,16 +39,15 @@ static inline int block_all_signals(Sigset &set) { sigset_t nativeSigset = all; sigset_t oldSet = set; int ret = __llvm_libc::syscall(SYS_rt_sigprocmask, SIG_BLOCK, &nativeSigset, - &oldSet, sizeof(sigset_t)); + &oldSet, sizeof(sigset_t)); set = {oldSet}; return ret; } static inline int restore_signals(const Sigset &set) { sigset_t nativeSigset = set; - return __llvm_libc::syscall(SYS_rt_sigprocmask, SIG_SETMASK, - &nativeSigset, nullptr, - sizeof(sigset_t)); + return __llvm_libc::syscall(SYS_rt_sigprocmask, SIG_SETMASK, &nativeSigset, + nullptr, sizeof(sigset_t)); } } // namespace __llvm_libc diff --git a/libc/src/signal/sigdelset.h b/libc/src/signal/sigdelset.h new file mode 100644 index 0000000..05cc47c --- /dev/null +++ b/libc/src/signal/sigdelset.h @@ -0,0 +1,20 @@ +//===------------- Implementation header for sigdelset ---------*- C++ -*--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SIGNAL_SIGDELSET_H +#define LLVM_LIBC_SRC_SIGNAL_SIGDELSET_H + +#include "include/signal.h" + +namespace __llvm_libc { + +int sigdelset(sigset_t *set, int signum); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_SIGNAL_SIGDELSET_H diff --git a/libc/src/signal/sigfillset.h b/libc/src/signal/sigfillset.h new file mode 100644 index 0000000..facf679 --- /dev/null +++ b/libc/src/signal/sigfillset.h @@ -0,0 +1,20 @@ +//===------------- Implementation header for sigfillset --------*- C++ -*--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SIGNAL_SIGFILLSET_H +#define LLVM_LIBC_SRC_SIGNAL_SIGFILLSET_H + +#include "include/signal.h" + +namespace __llvm_libc { + +int sigfillset(sigset_t *set); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_SIGNAL_SIGFILLSET_H diff --git a/libc/test/src/signal/CMakeLists.txt b/libc/test/src/signal/CMakeLists.txt index e198e41..67219c8 100644 --- a/libc/test/src/signal/CMakeLists.txt +++ b/libc/test/src/signal/CMakeLists.txt @@ -66,3 +66,34 @@ add_libc_unittest( __errno_location errno_h ) + +add_libc_unittest( + sigfillset_test + SUITE + libc_signal_unittests + SRCS + sigfillset_test.cpp + DEPENDS + sigfillset + sigprocmask + signal_h + raise + errno_h + __errno_location +) + +add_libc_unittest( + sigdelset_test + SUITE + libc_signal_unittests + SRCS + sigdelset_test.cpp + DEPENDS + sigdelset + sigfillset + sigprocmask + signal_h + raise + errno_h + __errno_location +) diff --git a/libc/test/src/signal/sigdelset_test.cpp b/libc/test/src/signal/sigdelset_test.cpp new file mode 100644 index 0000000..d6e259ca --- /dev/null +++ b/libc/test/src/signal/sigdelset_test.cpp @@ -0,0 +1,36 @@ +//===--------------------- Unittests for sigdelset ------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "include/errno.h" +#include "include/signal.h" +#include "src/signal/raise.h" +#include "src/signal/sigdelset.h" +#include "src/signal/sigfillset.h" +#include "src/signal/sigprocmask.h" + +#include "utils/UnitTest/ErrnoSetterMatcher.h" +#include "utils/UnitTest/Test.h" + +TEST(Sigdelset, Invalid) { + using __llvm_libc::testing::ErrnoSetterMatcher::Fails; + // Invalid set. + EXPECT_THAT(__llvm_libc::sigdelset(nullptr, SIGUSR1), Fails(EINVAL)); + + sigset_t set; + // Valid set, invalid signum. + EXPECT_THAT(__llvm_libc::sigdelset(&set, -1), Fails(EINVAL)); +} + +TEST(Sigdelset, UnblockOne) { + using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds; + sigset_t set; + EXPECT_THAT(__llvm_libc::sigfillset(&set), Succeeds()); + EXPECT_THAT(__llvm_libc::sigdelset(&set, SIGUSR1), Succeeds()); + EXPECT_THAT(__llvm_libc::sigprocmask(SIG_SETMASK, &set, nullptr), Succeeds()); + EXPECT_DEATH([] { __llvm_libc::raise(SIGUSR1); }, SIGUSR1); +} diff --git a/libc/test/src/signal/sigfillset_test.cpp b/libc/test/src/signal/sigfillset_test.cpp new file mode 100644 index 0000000..35e6721 --- /dev/null +++ b/libc/test/src/signal/sigfillset_test.cpp @@ -0,0 +1,29 @@ +//===-------------------- Unittests for sigfillset ------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "include/errno.h" +#include "include/signal.h" +#include "src/signal/raise.h" +#include "src/signal/sigfillset.h" +#include "src/signal/sigprocmask.h" + +#include "utils/UnitTest/ErrnoSetterMatcher.h" +#include "utils/UnitTest/Test.h" + +TEST(Sigfillset, Invalid) { + using __llvm_libc::testing::ErrnoSetterMatcher::Fails; + EXPECT_THAT(__llvm_libc::sigfillset(nullptr), Fails(EINVAL)); +} + +TEST(Sigfillset, BlocksAll) { + using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds; + sigset_t set; + EXPECT_THAT(__llvm_libc::sigfillset(&set), Succeeds()); + EXPECT_THAT(__llvm_libc::sigprocmask(SIG_SETMASK, &set, nullptr), Succeeds()); + EXPECT_EXITS([] { __llvm_libc::raise(SIGUSR1); }, 0); +} |