From 0b7f18635b98300583f99738db9b96bfaec65aae Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Thu, 6 Jul 2023 15:46:29 +0800 Subject: [PATCH] posix: signal: implement sigaddset Implementation and ztest for sigaddset. Signed-off-by: Yong Cong Sin --- include/zephyr/posix/signal.h | 1 + lib/posix/signal.c | 28 +++++++++++ tests/posix/common/src/signal.c | 83 +++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) diff --git a/include/zephyr/posix/signal.h b/include/zephyr/posix/signal.h index 647c979f716213e..6615fbdae7f40a5 100644 --- a/include/zephyr/posix/signal.h +++ b/include/zephyr/posix/signal.h @@ -61,6 +61,7 @@ typedef struct { int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); +int sigaddset(sigset_t *set, int signo); #endif /* CONFIG_POSIX_SIGNAL */ #ifndef SIGEV_NONE diff --git a/lib/posix/signal.c b/lib/posix/signal.c index 448ea1ed4ff6485..3aaad5cf046ae59 100644 --- a/lib/posix/signal.c +++ b/lib/posix/signal.c @@ -4,10 +4,26 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include +static inline int signo_word_idx(int signo) +{ + return (signo - 1) / _NSIG_BPW; +} + +static inline int signo_word_bit(int signo) +{ + return (signo - 1) % _NSIG_BPW; +} + +static inline bool signo_invalid(int signo) +{ + return ((signo <= 0) || (signo > _NSIG)) ? true : false; +} + int sigemptyset(sigset_t *set) { memset(set, 0, sizeof(*set)); @@ -21,3 +37,15 @@ int sigfillset(sigset_t *set) return 0; } + +int sigaddset(sigset_t *set, int signo) +{ + if (signo_invalid(signo)) { + errno = EINVAL; + return -1; + } + + WRITE_BIT(set->sig[signo_word_idx(signo)], signo_word_bit(signo), 1); + + return 0; +} diff --git a/tests/posix/common/src/signal.c b/tests/posix/common/src/signal.c index 8e6c1c4189cf17f..043237a105057d1 100644 --- a/tests/posix/common/src/signal.c +++ b/tests/posix/common/src/signal.c @@ -5,7 +5,9 @@ */ #include +#include +#include #include ZTEST(posix_apis, test_signal_emptyset) @@ -31,3 +33,84 @@ ZTEST(posix_apis, test_signal_fillset) zassert_equal(set.sig[i], -1, "set.sig[%d] is not filled: 0x%lx", i, set.sig[i]); } } + +ZTEST(posix_apis, test_signal_addset_oor) +{ + int rc; + sigset_t set = {0}; + + rc = sigaddset(&set, -1); + zassert_equal(rc, -1, "rc should be -1"); + zassert_equal(errno, EINVAL, "errno should be %s", "EINVAL"); + + rc = sigaddset(&set, 0); + zassert_equal(rc, -1, "rc should be -1"); + zassert_equal(errno, EINVAL, "errno should be %s", "EINVAL"); + + rc = sigaddset(&set, _NSIG + 1); + zassert_equal(rc, -1, "rc should be -1"); + zassert_equal(errno, EINVAL, "errno should be %s", "EINVAL"); +} + +#define SIG_WD_IDX(_signo) ((int)((_signo - 1) / BITS_PER_LONG)) +#define SIG_MSK_SET(_signo) (WRITE_BIT(sig_mask[SIG_WD_IDX(_signo)], (_signo - 1) % _NSIG_BPW, 1)) +ZTEST(posix_apis, test_signal_addset) +{ + int signo; + sigset_t set = {0}; + unsigned long sig_mask[_NSIG_WORDS] = {0}; + + signo = SIGHUP; + SIG_MSK_SET(signo); + zassert_ok(sigaddset(&set, signo)); + for (int i = 0; i < _NSIG_WORDS; i++) { + zassert_equal(set.sig[i], sig_mask[i], + "set.sig[%d of %d] has content: %lx, expected %lx", i, _NSIG_WORDS, + set.sig[i], sig_mask[i]); + } + + signo = SIGKILL; + SIG_MSK_SET(signo); + zassert_ok(sigaddset(&set, signo)); + for (int i = 0; i < _NSIG_WORDS; i++) { + zassert_equal(set.sig[i], sig_mask[i], + "set.sig[%d of %d] has content: %lx, expected %lx", i, _NSIG_WORDS, + set.sig[i], sig_mask[i]); + } + + signo = SIGSYS; + SIG_MSK_SET(signo); + zassert_ok(sigaddset(&set, signo)); + for (int i = 0; i < _NSIG_WORDS; i++) { + zassert_equal(set.sig[i], sig_mask[i], + "set.sig[%d of %d] has content: %lx, expected %lx", i, _NSIG_WORDS, + set.sig[i], sig_mask[i]); + } + + signo = SIGRTMIN; + SIG_MSK_SET(signo); + zassert_ok(sigaddset(&set, signo)); + for (int i = 0; i < _NSIG_WORDS; i++) { + zassert_equal(set.sig[i], sig_mask[i], + "set.sig[%d of %d] has content: %lx, expected %lx", i, _NSIG_WORDS, + set.sig[i], sig_mask[i]); + } + + signo = SIGRTMIN + 1; + SIG_MSK_SET(signo); + zassert_ok(sigaddset(&set, signo)); + for (int i = 0; i < _NSIG_WORDS; i++) { + zassert_equal(set.sig[i], sig_mask[i], + "set.sig[%d of %d] has content: %lx, expected %lx", i, _NSIG_WORDS, + set.sig[i], sig_mask[i]); + } + + signo = SIGRTMAX; + SIG_MSK_SET(signo); + zassert_ok(sigaddset(&set, signo)); + for (int i = 0; i < _NSIG_WORDS; i++) { + zassert_equal(set.sig[i], sig_mask[i], + "set.sig[%d of %d] has content: %lx, expected %lx", i, _NSIG_WORDS, + set.sig[i], sig_mask[i]); + } +}