zephyr/lib/posix/options/signal.c
Chris Friedt 1593954083 posix: add stubs for signal.h functions that need process support
Since Zephyr itself does not currently support processes, but
conformant applications should still be able to link, add stubs
for the remaining POSIX functions in the POSIX_SIGNALS Option
Group.

The POSIX_SIGNALS Option Group is required for PSE51, PSE52,
PSE53, PSE54, and likely many other POSIX Subprofiles.

Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
2024-08-23 10:35:11 -04:00

179 lines
3.3 KiB
C

/*
* Copyright (c) 2023 Meta
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "posix/strsignal_table.h"
#include <errno.h>
#include <stdio.h>
#include <zephyr/posix/pthread.h>
#include <zephyr/posix/signal.h>
#define SIGNO_WORD_IDX(_signo) (_signo / BITS_PER_LONG)
#define SIGNO_WORD_BIT(_signo) (_signo & BIT_MASK(LOG2(BITS_PER_LONG)))
BUILD_ASSERT(CONFIG_POSIX_RTSIG_MAX >= 0);
static inline bool signo_valid(int signo)
{
return ((signo > 0) && (signo < _NSIG));
}
static inline bool signo_is_rt(int signo)
{
return ((signo >= SIGRTMIN) && (signo <= SIGRTMAX));
}
int sigemptyset(sigset_t *set)
{
*set = (sigset_t){0};
return 0;
}
int sigfillset(sigset_t *set)
{
for (int i = 0; i < ARRAY_SIZE(set->sig); i++) {
set->sig[i] = -1;
}
return 0;
}
int sigaddset(sigset_t *set, int signo)
{
if (!signo_valid(signo)) {
errno = EINVAL;
return -1;
}
WRITE_BIT(set->sig[SIGNO_WORD_IDX(signo)], SIGNO_WORD_BIT(signo), 1);
return 0;
}
int sigdelset(sigset_t *set, int signo)
{
if (!signo_valid(signo)) {
errno = EINVAL;
return -1;
}
WRITE_BIT(set->sig[SIGNO_WORD_IDX(signo)], SIGNO_WORD_BIT(signo), 0);
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));
}
char *strsignal(int signum)
{
/* Using -INT_MAX here because compiler resolves INT_MIN to (-2147483647 - 1) */
static char buf[sizeof("RT signal -" STRINGIFY(INT_MAX))];
if (!signo_valid(signum)) {
errno = EINVAL;
return "Invalid signal";
}
if (signo_is_rt(signum)) {
snprintf(buf, sizeof(buf), "RT signal %d", signum - SIGRTMIN);
return buf;
}
if (IS_ENABLED(CONFIG_POSIX_SIGNAL_STRING_DESC)) {
if (strsignal_list[signum] != NULL) {
return (char *)strsignal_list[signum];
}
}
snprintf(buf, sizeof(buf), "Signal %d", signum);
return buf;
}
int sigprocmask(int how, const sigset_t *ZRESTRICT set, sigset_t *ZRESTRICT oset)
{
if (!IS_ENABLED(CONFIG_MULTITHREADING)) {
return pthread_sigmask(how, set, oset);
}
/*
* Until Zephyr supports processes and specifically querying the number of active threads in
* a process For more information, see
* https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html
*/
__ASSERT(false, "In multi-threaded environments, please use pthread_sigmask() instead of "
"%s()", __func__);
errno = ENOSYS;
return -1;
}
/*
* The functions below are provided so that conformant POSIX applications and libraries can still
* link.
*/
unsigned int alarm(unsigned int seconds)
{
ARG_UNUSED(seconds);
return 0;
}
int kill(pid_t pid, int sig)
{
ARG_UNUSED(pid);
ARG_UNUSED(sig);
errno = ENOSYS;
return -1;
}
#ifdef CONFIG_POSIX_SIGNALS_ALIAS_KILL
FUNC_ALIAS(kill, _kill, int);
#endif /* CONFIG_POSIX_SIGNALS_ALIAS_KILL */
int pause(void)
{
errno = ENOSYS;
return -1;
}
int sigaction(int sig, const struct sigaction *ZRESTRICT act, struct sigaction *ZRESTRICT oact)
{
ARG_UNUSED(sig);
ARG_UNUSED(act);
ARG_UNUSED(oact);
errno = ENOSYS;
return -1;
}
int sigpending(sigset_t *set)
{
ARG_UNUSED(set);
errno = ENOSYS;
return -1;
}
int sigsuspend(const sigset_t *sigmask)
{
ARG_UNUSED(sigmask);
errno = ENOSYS;
return -1;
}
int sigwait(const sigset_t *ZRESTRICT set, int *ZRESTRICT sig)
{
ARG_UNUSED(set);
ARG_UNUSED(sig);
errno = ENOSYS;
return -1;
}