diff --git a/include/zephyr/posix/signal.h b/include/zephyr/posix/signal.h index 88b137e7547a..f86c99be1363 100644 --- a/include/zephyr/posix/signal.h +++ b/include/zephyr/posix/signal.h @@ -12,6 +12,62 @@ extern "C" { #endif +#ifdef CONFIG_POSIX_SIGNAL +enum { + SIGABRT = 1, + SIGALRM, + SIGBUS, + SIGCHLD, + SIGCONT, + SIGFPE, + SIGHUP, + SIGILL, + SIGINT, + SIGKILL, + SIGPIPE, + SIGQUIT, + SIGSEGV, + SIGSTOP, + SIGTERM, + SIGTSTP, + SIGTTIN, + SIGTTOU, + SIGUSR1, + SIGUSR2, + SIGPOLL, + SIGPROF, + SIGSYS, + SIGTRAP, + SIGURG, + SIGVTALRM, + SIGXCPU, + SIGXFSZ, +}; + +/* Signal set management definitions and macros. */ +#define MIN_SIGNO 1 /* Lowest valid signal number */ +#define MAX_SIGNO CONFIG_POSIX_SIGNAL_MAX /* Highest valid signal number */ + +/* Definitions for "standard" signals */ +#define SIGSTDMIN 1 /* First standard signal number */ +#define SIGSTDMAX CONFIG_POSIX_SIGNAL_STD_MAX /* Last standard signal number */ + +/* Definitions for "real time" signals */ +#define SIGRTMIN (SIGSTDMAX + 1) /* First real time signal */ +#define SIGRTMAX MAX_SIGNO /* Last real time signal */ +#define _NSIG (MAX_SIGNO + 1) /* Biggest signal number + 1 */ +#define NSIG _NSIG /* _NSIG variant commonly used */ + +/* sigset_t is represented as an array of 32-b unsigned integers. + * _SIGSET_NELEM is the allocated size of the array + */ +#define _SIGSET_NELEM ((_NSIG + 31) >> 5) + +#define _SIGSET_NDX(s) ((s) >> 5) /* Get array index from signal number */ +#define _SIGSET_BIT(s) ((s) & 0x1f) /* Get bit number from signal number */ +#define _SIGNO2SET(s) ((uint32_t)1 << _SIGSET_BIT(s)) +#endif /* CONFIG_POSIX_SIGNAL */ + #ifndef SIGEV_NONE #define SIGEV_NONE 1 #endif @@ -41,6 +97,16 @@ typedef struct sigevent { #endif } sigevent; +#ifdef CONFIG_POSIX_SIGNAL +typedef struct sigset { + uint32_t _elem[_SIGSET_NELEM]; +} sigset_t; + +int sigaddset(sigset_t *set, int signo); +int sigemptyset(sigset_t *set); +int sigfillset(sigset_t *set); +#endif /* CONFIG_POSIX_SIGNAL */ + #ifdef __cplusplus } #endif diff --git a/lib/posix/CMakeLists.txt b/lib/posix/CMakeLists.txt index cd6caf6b25eb..913a2df35dd0 100644 --- a/lib/posix/CMakeLists.txt +++ b/lib/posix/CMakeLists.txt @@ -38,6 +38,7 @@ zephyr_library_sources_ifdef(CONFIG_POSIX_FS fs.c) zephyr_library_sources_ifdef(CONFIG_EVENTFD eventfd.c) zephyr_library_sources_ifdef(CONFIG_FNMATCH fnmatch.c) add_subdirectory_ifdef(CONFIG_GETOPT getopt) +add_subdirectory_ifdef(CONFIG_POSIX_SIGNAL signal) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/lib/posix/Kconfig b/lib/posix/Kconfig index 7f510210d9c6..d8efa95d0a8a 100644 --- a/lib/posix/Kconfig +++ b/lib/posix/Kconfig @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 source "lib/posix/getopt/Kconfig" +source "lib/posix/signal/Kconfig" config POSIX_MAX_FDS int "Maximum number of open file descriptors" diff --git a/lib/posix/signal/CMakeLists.txt b/lib/posix/signal/CMakeLists.txt new file mode 100644 index 000000000000..ea3134aff009 --- /dev/null +++ b/lib/posix/signal/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_sources( + addset.c + emptyset.c + fillset.c +) diff --git a/lib/posix/signal/Kconfig b/lib/posix/signal/Kconfig new file mode 100644 index 000000000000..96dd831f221a --- /dev/null +++ b/lib/posix/signal/Kconfig @@ -0,0 +1,23 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + + +menuconfig POSIX_SIGNAL + bool "POSIX signal support" + default y if POSIX_API + help + This option adds support of POSIX signal. + +config POSIX_SIGNAL_MAX + int "Highest valid signal number" + depends on POSIX_SIGNAL + default 63 + help + Defines the highest valid signal number. + +config POSIX_SIGNAL_STD_MAX + int "Highest number for standard signal" + depends on POSIX_SIGNAL + default 31 + help + Defines the highest number for standard signal. diff --git a/lib/posix/signal/addset.c b/lib/posix/signal/addset.c new file mode 100644 index 000000000000..7ba4fe82cdac --- /dev/null +++ b/lib/posix/signal/addset.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int sigaddset(sigset_t *set, int signo) +{ + if ((set == NULL) || (signo <= 0) || (signo >= NSIG)) { + errno = EINVAL; + return -1; + } + + set->_elem[_SIGSET_NDX(signo)] |= _SIGNO2SET(signo); + + return 0; +} diff --git a/lib/posix/signal/emptyset.c b/lib/posix/signal/emptyset.c new file mode 100644 index 000000000000..79b345ebc854 --- /dev/null +++ b/lib/posix/signal/emptyset.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +int sigemptyset(sigset_t *set) +{ + for (int ndx = 0; ndx < _SIGSET_NELEM; ndx++) { + set->_elem[ndx] = 0; + } + + return 0; +} diff --git a/lib/posix/signal/fillset.c b/lib/posix/signal/fillset.c new file mode 100644 index 000000000000..d4aae254f4cf --- /dev/null +++ b/lib/posix/signal/fillset.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int sigfillset(sigset_t *set) +{ + for (int ndx = 0; ndx < _SIGSET_NELEM; ndx++) { + set->_elem[ndx] = UINT32_MAX; + } + + return 0; +} diff --git a/tests/posix/signal/CMakeLists.txt b/tests/posix/signal/CMakeLists.txt new file mode 100644 index 000000000000..d7fd56aff901 --- /dev/null +++ b/tests/posix/signal/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2023, Meta +# +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(signal) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/posix/signal/Kconfig b/tests/posix/signal/Kconfig new file mode 100644 index 000000000000..bf2fb3887105 --- /dev/null +++ b/tests/posix/signal/Kconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2023, Meta +# +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" diff --git a/tests/posix/signal/prj.conf b/tests/posix/signal/prj.conf new file mode 100644 index 000000000000..d189ad86a680 --- /dev/null +++ b/tests/posix/signal/prj.conf @@ -0,0 +1,3 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_POSIX_API=y diff --git a/tests/posix/signal/src/addset.c b/tests/posix/signal/src/addset.c new file mode 100644 index 000000000000..52283d262458 --- /dev/null +++ b/tests/posix/signal/src/addset.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include + +ZTEST(posix_signal_apis, test_posix_signal_addset) +{ + sigset_t set; + int signo; + int rc; + + for (int i = 0; i < ARRAY_SIZE(set._elem); i++) { + set._elem[i] = 0u; + } + + signo = 21; + zassert_ok(sigaddset(&set, signo)); + zassert_equal(set._elem[signo >> 5], BIT(signo), "Signal %d is not set", signo); + + signo = 42; + zassert_ok(sigaddset(&set, signo)); + zassert_equal(set._elem[21 >> 5], BIT(21), "Signal %d is not set", 21); + zassert_equal(set._elem[signo >> 5], BIT(signo % (8 * sizeof(set._elem[0]))), + "Signal %d is not set", signo); + + rc = sigaddset(&set, 0); + zassert_equal(rc, -1, "rc should be -1, not %d", rc); + zassert_equal(errno, EINVAL, "errno should be EINVAL, not %d", errno); + + rc = sigaddset(&set, NSIG); + zassert_equal(rc, -1, "rc should be -1, not %d", rc); + zassert_equal(errno, EINVAL, "errno should be EINVAL, not %d", errno); +} diff --git a/tests/posix/signal/src/emptyset.c b/tests/posix/signal/src/emptyset.c new file mode 100644 index 000000000000..7ff533d4020d --- /dev/null +++ b/tests/posix/signal/src/emptyset.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +ZTEST(posix_signal_apis, test_posix_signal_emptyset) +{ + sigset_t set; + + for (int i = 0; i < ARRAY_SIZE(set._elem); i++) { + set._elem[i] = 0xffffffffu; + } + + zassert_ok(sigemptyset(&set)); + + for (int i = 0; i < ARRAY_SIZE(set._elem); i++) { + zassert_equal(set._elem[i], 0, "signal is not empty"); + } +} diff --git a/tests/posix/signal/src/fillset.c b/tests/posix/signal/src/fillset.c new file mode 100644 index 000000000000..d96cae340d5a --- /dev/null +++ b/tests/posix/signal/src/fillset.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include + +ZTEST(posix_signal_apis, test_posix_signal_fillset) +{ + sigset_t set; + + for (int i = 0; i < ARRAY_SIZE(set._elem); i++) { + set._elem[i] = 0u; + } + + zassert_ok(sigfillset(&set)); + + for (int i = 0; i < ARRAY_SIZE(set._elem); i++) { + zassert_equal(set._elem[i], UINT32_MAX, "signal is not filled"); + } +} diff --git a/tests/posix/signal/src/main.c b/tests/posix/signal/src/main.c new file mode 100644 index 000000000000..c565a97be025 --- /dev/null +++ b/tests/posix/signal/src/main.c @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +ZTEST_SUITE(posix_signal_apis, NULL, NULL, NULL, NULL, NULL);