diff --git a/doc/services/portability/posix.rst b/doc/services/portability/posix.rst index 0b6e0f54da9..fb06cba1c75 100644 --- a/doc/services/portability/posix.rst +++ b/doc/services/portability/posix.rst @@ -380,7 +380,7 @@ required for error and event handling. sigdelset(),yes sigemptyset(),yes sigfillset(),yes - igismember(), + sigismember(),yes signal(), sigpending(), sigprocmask(), diff --git a/include/zephyr/posix/signal.h b/include/zephyr/posix/signal.h index 462bff8ce4d..8c509954edd 100644 --- a/include/zephyr/posix/signal.h +++ b/include/zephyr/posix/signal.h @@ -59,6 +59,7 @@ int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t *set, int signo); int sigdelset(sigset_t *set, int signo); +int sigismember(const 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 d20557b3fc1..165d9aa9dbc 100644 --- a/lib/posix/signal.c +++ b/lib/posix/signal.c @@ -58,3 +58,13 @@ int sigdelset(sigset_t *set, int signo) return 0; } + +int sigismember(const sigset_t *set, int signo) +{ + if (!signo_valid(signo)) { + errno = EINVAL; + return -1; + } + + return 1 & (set->sig[SIGNO_WORD_IDX(signo)] >> SIGNO_WORD_BIT(signo)); +} diff --git a/tests/posix/common/src/signal.c b/tests/posix/common/src/signal.c index afc0fb9e60b..90fb001bc5b 100644 --- a/tests/posix/common/src/signal.c +++ b/tests/posix/common/src/signal.c @@ -157,3 +157,38 @@ ZTEST(posix_apis, test_signal_delset) ARRAY_SIZE(set.sig) - 1, set.sig[i], target.sig[i]); } } + +ZTEST(posix_apis, test_signal_ismember_oor) +{ + sigset_t set = {0}; + + zassert_equal(sigismember(&set, -1), -1, "rc should be -1"); + zassert_equal(errno, EINVAL, "errno should be %s", "EINVAL"); + + zassert_equal(sigismember(&set, 0), -1, "rc should be -1"); + zassert_equal(errno, EINVAL, "errno should be %s", "EINVAL"); + + zassert_equal(sigismember(&set, _NSIG), -1, "rc should be -1"); + zassert_equal(errno, EINVAL, "errno should be %s", "EINVAL"); +} + +ZTEST(posix_apis, test_signal_ismember) +{ + sigset_t set = (sigset_t){0}; + +#ifdef CONFIG_64BIT + set.sig[0] = BIT(SIGHUP) | BIT(SIGSYS) | BIT(SIGRTMIN); +#else /* 32BIT */ + set.sig[0] = BIT(SIGHUP) | BIT(SIGSYS); + set.sig[1] = BIT((SIGRTMIN)-BITS_PER_LONG); +#endif + WRITE_BIT(set.sig[SIGRTMAX / BITS_PER_LONG], SIGRTMAX % BITS_PER_LONG, 1); + + zassert_equal(sigismember(&set, SIGHUP), 1, "%s expected to be member", "SIGHUP"); + zassert_equal(sigismember(&set, SIGSYS), 1, "%s expected to be member", "SIGSYS"); + zassert_equal(sigismember(&set, SIGRTMIN), 1, "%s expected to be member", "SIGRTMIN"); + zassert_equal(sigismember(&set, SIGRTMAX), 1, "%s expected to be member", "SIGRTMAX"); + + zassert_equal(sigismember(&set, SIGKILL), 0, "%s not expected to be member", "SIGKILL"); + zassert_equal(sigismember(&set, SIGTERM), 0, "%s not expected to be member", "SIGTERM"); +} diff --git a/tests/posix/headers/src/signal_h.c b/tests/posix/headers/src/signal_h.c index 34703c0b2c0..5a78c0ec0a7 100644 --- a/tests/posix/headers/src/signal_h.c +++ b/tests/posix/headers/src/signal_h.c @@ -162,6 +162,7 @@ ZTEST(posix_headers, test_signal_h) zassert_not_null(sigfillset); zassert_not_null(sigaddset); zassert_not_null(sigdelset); + zassert_not_null(sigismember); #endif /* CONFIG_POSIX_SIGNAL */ if (IS_ENABLED(CONFIG_POSIX_API)) { @@ -177,7 +178,6 @@ ZTEST(posix_headers, test_signal_h) /* zassert_not_null(sighold); */ /* not implemented */ /* zassert_not_null(sigignore); */ /* not implemented */ /* zassert_not_null(siginterrupt); */ /* not implemented */ - /* zassert_not_null(sigismember); */ /* not implemented */ /* zassert_not_null(signal); */ /* not implemented */ /* zassert_not_null(sigpause); */ /* not implemented */ /* zassert_not_null(sigpending); */ /* not implemented */