From 35f11b3981b6078c7aaacc63ad4dbf8b99609af9 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sat, 29 Jul 2023 11:48:35 -0400 Subject: [PATCH 1/4] libc: minimal: declare sig_atomic_t and signal() We don't actually implement signal() in Zephyr, but some users require the declaration. Additionally, typedef sig_atomic_t since it is part of ISO. Signed-off-by: Christopher Friedt --- lib/libc/minimal/CMakeLists.txt | 1 + lib/libc/minimal/include/signal.h | 29 +++++++++++++++++++++++++ lib/libc/minimal/source/signal/signal.c | 12 ++++++++++ 3 files changed, 42 insertions(+) create mode 100644 lib/libc/minimal/include/signal.h create mode 100644 lib/libc/minimal/source/signal/signal.c diff --git a/lib/libc/minimal/CMakeLists.txt b/lib/libc/minimal/CMakeLists.txt index 71a404e7870926..61f7a48ff804bd 100644 --- a/lib/libc/minimal/CMakeLists.txt +++ b/lib/libc/minimal/CMakeLists.txt @@ -10,6 +10,7 @@ set(STRERROR_TABLE_H ${GEN_DIR}/libc/minimal/strerror_table.h) zephyr_library_cc_option(-fno-builtin) zephyr_library_sources( + source/signal/signal.c source/stdlib/atoi.c source/stdlib/strtol.c source/stdlib/strtoul.c diff --git a/lib/libc/minimal/include/signal.h b/lib/libc/minimal/include/signal.h new file mode 100644 index 00000000000000..f465db67d87572 --- /dev/null +++ b/lib/libc/minimal/include/signal.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LIB_LIBC_MINIMAL_INCLUDE_SIGNAL_H_ +#define ZEPHYR_LIB_LIBC_MINIMAL_INCLUDE_SIGNAL_H_ + +#define SIG_DFL ((sighandler_t)0) +#define SIG_ERR ((sighandler_t)1) +#define SIG_IGN ((sighandler_t)-1) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int sig_atomic_t; /* Atomic entity type (ANSI) */ + +/* Note: sighandler_t is a gnu-ism, but it simplifies the declaration below */ +typedef void (*sighandler_t)(int signo); + +sighandler_t signal(int signum, sighandler_t handler); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_LIB_LIBC_MINIMAL_INCLUDE_SIGNAL_H_ */ diff --git a/lib/libc/minimal/source/signal/signal.c b/lib/libc/minimal/source/signal/signal.c new file mode 100644 index 00000000000000..eb371ab652fd0c --- /dev/null +++ b/lib/libc/minimal/source/signal/signal.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +sighandler_t signal(int signum, sighandler_t handler) +{ + return SIG_DFL; +} From f3df0c252c4ca63fa54579422ead324702c65a30 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sun, 30 Jul 2023 09:56:27 -0400 Subject: [PATCH 2/4] posix: signal: some declarations were not visible Some declarations were not visible when including the POSIX version of `` or ``. Signed-off-by: Christopher Friedt --- include/zephyr/posix/posix_types.h | 3 --- include/zephyr/posix/signal.h | 15 ++++++++++----- lib/posix/Kconfig.signal | 3 ++- lib/posix/Kconfig.timer | 4 ++++ lib/posix/signal.c | 2 ++ 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/include/zephyr/posix/posix_types.h b/include/zephyr/posix/posix_types.h index fbfc976d6fb976..0f3e0319e30d24 100644 --- a/include/zephyr/posix/posix_types.h +++ b/include/zephyr/posix/posix_types.h @@ -35,7 +35,6 @@ typedef uint32_t clockid_t; typedef unsigned long timer_t; #endif -#ifdef CONFIG_PTHREAD_IPC /* Thread attributes */ struct pthread_attr { int priority; @@ -101,8 +100,6 @@ typedef struct pthread_rwlock_obj { k_tid_t wr_owner; } pthread_rwlock_t; -#endif /* CONFIG_PTHREAD_IPC */ - #ifdef __cplusplus } #endif diff --git a/include/zephyr/posix/signal.h b/include/zephyr/posix/signal.h index 0cfa5649b387cf..86b37c8b710da6 100644 --- a/include/zephyr/posix/signal.h +++ b/include/zephyr/posix/signal.h @@ -8,11 +8,10 @@ #include "posix_types.h" -#ifdef __cplusplus -extern "C" { -#endif +#define SIG_DFL ((sighandler_t)0) +#define SIG_ERR ((sighandler_t)1) +#define SIG_IGN ((sighandler_t)-1) -#ifdef CONFIG_POSIX_SIGNAL #define SIGHUP 1 /**< Hangup */ #define SIGINT 2 /**< Interrupt */ #define SIGQUIT 3 /**< Quit */ @@ -51,6 +50,10 @@ extern "C" { BUILD_ASSERT(CONFIG_POSIX_RTSIG_MAX >= 0); +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { unsigned long sig[DIV_ROUND_UP(_NSIG, BITS_PER_LONG)]; } sigset_t; @@ -61,7 +64,6 @@ 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 #define SIGEV_NONE 1 @@ -92,6 +94,9 @@ typedef struct sigevent { #endif } sigevent; +typedef void (*sighandler_t)(int signo); +sighandler_t signal(int signum, sighandler_t handler); + #ifdef __cplusplus } #endif diff --git a/lib/posix/Kconfig.signal b/lib/posix/Kconfig.signal index c51e68f1f36a49..7e50bf0515bf9f 100644 --- a/lib/posix/Kconfig.signal +++ b/lib/posix/Kconfig.signal @@ -8,7 +8,6 @@ config POSIX_SIGNAL help Enable support for POSIX signal APIs. -if POSIX_SIGNAL config POSIX_RTSIG_MAX int "Maximum number of realtime signals" default 31 @@ -16,6 +15,8 @@ config POSIX_RTSIG_MAX Define the maximum number of realtime signals (RTSIG_MAX). The range of realtime signals is [SIGRTMIN .. (SIGRTMIN+RTSIG_MAX)] +if POSIX_SIGNAL + config POSIX_SIGNAL_STRING_DESC bool "Use full description for the strsignal API" default y diff --git a/lib/posix/Kconfig.timer b/lib/posix/Kconfig.timer index 28173692e0ce84..b904d942a88962 100644 --- a/lib/posix/Kconfig.timer +++ b/lib/posix/Kconfig.timer @@ -7,6 +7,10 @@ type = timer_t type-function = timer_create source "lib/posix/Kconfig.template.pooled_type" +config POSIX_TIMER + bool + imply POSIX_SIGNAL + config TIMER_CREATE_WAIT int "Time to wait for timer availability (in msec) in POSIX application" default 100 diff --git a/lib/posix/signal.c b/lib/posix/signal.c index d2153238ff8fc5..6bf65c7373d301 100644 --- a/lib/posix/signal.c +++ b/lib/posix/signal.c @@ -10,6 +10,8 @@ #include +BUILD_ASSERT(CONFIG_POSIX_RTSIG_MAX >= 0); + #define SIGNO_WORD_IDX(_signo) (signo / BITS_PER_LONG) #define SIGNO_WORD_BIT(_signo) (signo & BIT_MASK(LOG2(BITS_PER_LONG))) From d585d09940e66a50957bac9f143aa6d80bcb9777 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sat, 29 Jul 2023 11:49:17 -0400 Subject: [PATCH 3/4] tests: c_lib: test for declaration of signal() We don't actually implement signal() in Zephyr, but some users require the declaration. Signed-off-by: Christopher Friedt --- tests/lib/c_lib/src/test_signal_decl.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/lib/c_lib/src/test_signal_decl.c diff --git a/tests/lib/c_lib/src/test_signal_decl.c b/tests/lib/c_lib/src/test_signal_decl.c new file mode 100644 index 00000000000000..fa9490f911df5d --- /dev/null +++ b/tests/lib/c_lib/src/test_signal_decl.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +ZTEST(test_c_lib, test_signal_decl) +{ + /* + * Even though the use of the ANSI-C function "signal()" is not yet + * supported in Zephyr, some users depend on it being declared (i.e. + * without CONFIG_POSIX_API=y and with with CONFIG_POSIX_SIGNAL=n). + */ + + zassert_not_null(signal); +} From d566e1f117c556f45fa4ea154882f4a0d3cd231e Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sun, 30 Jul 2023 09:52:07 -0400 Subject: [PATCH 4/4] tests: posix: signal: account for ANSI / ISO C signal bits The `signal()` function was part of ANSI-C and predates POSIX, so it should be visible (even if it completely unsupported in Zephyr currently). The `sig_atomic_t` type is part of ISO C, regardless of whether POSIX is enabled. Signed-off-by: Christopher Friedt --- tests/posix/headers/prj.conf | 1 + tests/posix/headers/src/signal_h.c | 60 +++++++++++++++--------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/tests/posix/headers/prj.conf b/tests/posix/headers/prj.conf index 43b6bc147c46c3..1005d7f577c38f 100644 --- a/tests/posix/headers/prj.conf +++ b/tests/posix/headers/prj.conf @@ -18,3 +18,4 @@ CONFIG_POSIX_CLOCK=y CONFIG_POSIX_MQUEUE=y CONFIG_EVENTFD=y CONFIG_GETOPT=y +CONFIG_POSIX_SIGNAL=y diff --git a/tests/posix/headers/src/signal_h.c b/tests/posix/headers/src/signal_h.c index 852cddf3df0f83..3b34d5a039a394 100644 --- a/tests/posix/headers/src/signal_h.c +++ b/tests/posix/headers/src/signal_h.c @@ -19,12 +19,17 @@ */ ZTEST(posix_headers, test_signal_h) { + /* part of ANSI C */ + zassert_not_null(signal); + /* part of ISO C */ + zassert_not_equal(sizeof(sig_atomic_t), 0); + +#ifdef CONFIG_POSIX_API /* zassert_not_equal(-1, SIG_DFL); */ /* not implemented */ /* zassert_not_equal(-1, SIG_ERR); */ /* not implemented */ /* zassert_not_equal(-1, SIG_HOLD); */ /* not implemented */ /* zassert_not_equal(-1, SIG_IGN); */ /* not implemented */ - /* zassert_not_equal((sig_atomic_t)-1, (sig_atomic_t)0); */ /* not implemented */ /* zassert_not_equal((pid_t)-1, (pid_t)0); */ /* not implemented */ zassert_not_equal(-1, offsetof(struct sigevent, sigev_notify)); @@ -130,7 +135,6 @@ ZTEST(posix_headers, test_signal_h) /* zassert_not_equal(-1, SI_ASYNCIO); */ /* not implemented */ /* zassert_not_equal(-1, SI_MESGQ); */ /* not implemented */ -#ifdef CONFIG_POSIX_SIGNAL zassert_true(SIGRTMIN >= 0); zassert_true(SIGRTMAX >= SIGRTMIN); zassert_not_equal(-1, SIGABRT); @@ -157,38 +161,34 @@ ZTEST(posix_headers, test_signal_h) zassert_not_equal(-1, SIGURG); zassert_not_equal(-1, SIGXCPU); zassert_not_equal(-1, SIGXFSZ); - zassert_not_equal(((sigset_t){.sig[0] = 0}).sig[0], ((sigset_t){.sig[0] = -1}).sig[0]); + zassert_not_equal(sizeof(sigset_t), 0); zassert_not_null(sigemptyset); zassert_not_null(sigfillset); zassert_not_null(sigaddset); zassert_not_null(sigdelset); zassert_not_null(sigismember); zassert_not_null(strsignal); -#endif /* CONFIG_POSIX_SIGNAL */ - - if (IS_ENABLED(CONFIG_POSIX_API)) { - /* zassert_not_null(kill); */ /* not implemented */ - /* zassert_not_null(killpg); */ /* not implemented */ - /* zassert_not_null(psiginfo); */ /* not implemented */ - /* zassert_not_null(psignal); */ /* not implemented */ - /* zassert_not_null(pthread_kill); */ /* not implemented */ - /* zassert_not_null(pthread_sigmask); */ /* not implemented */ - /* zassert_not_null(raise); */ /* not implemented */ - /* zassert_not_null(sigaction); */ /* not implemented */ - /* zassert_not_null(sigaltstack); */ /* not implemented */ - /* zassert_not_null(sighold); */ /* not implemented */ - /* zassert_not_null(sigignore); */ /* not implemented */ - /* zassert_not_null(siginterrupt); */ /* not implemented */ - /* zassert_not_null(signal); */ /* not implemented */ - /* zassert_not_null(sigpause); */ /* not implemented */ - /* zassert_not_null(sigpending); */ /* not implemented */ - /* zassert_not_null(sigprocmask); */ /* not implemented */ - /* zassert_not_null(sigqueue); */ /* not implemented */ - /* zassert_not_null(sigrelse); */ /* not implemented */ - /* zassert_not_null(sigset); */ /* not implemented */ - /* zassert_not_null(sigsuspend); */ /* not implemented */ - /* zassert_not_null(sigtimedwait); */ /* not implemented */ - /* zassert_not_null(sigwait); */ /* not implemented */ - /* zassert_not_null(sigwaitinfo); */ /* not implemented */ - } + /* zassert_not_null(kill); */ /* not implemented */ + /* zassert_not_null(killpg); */ /* not implemented */ + /* zassert_not_null(psiginfo); */ /* not implemented */ + /* zassert_not_null(psignal); */ /* not implemented */ + /* zassert_not_null(pthread_kill); */ /* not implemented */ + /* zassert_not_null(pthread_sigmask); */ /* not implemented */ + /* zassert_not_null(raise); */ /* not implemented */ + /* zassert_not_null(sigaction); */ /* not implemented */ + /* zassert_not_null(sigaltstack); */ /* not implemented */ + /* zassert_not_null(sighold); */ /* not implemented */ + /* zassert_not_null(sigignore); */ /* not implemented */ + /* zassert_not_null(siginterrupt); */ /* not implemented */ + /* zassert_not_null(sigpause); */ /* not implemented */ + /* zassert_not_null(sigpending); */ /* not implemented */ + /* zassert_not_null(sigprocmask); */ /* not implemented */ + /* zassert_not_null(sigqueue); */ /* not implemented */ + /* zassert_not_null(sigrelse); */ /* not implemented */ + /* zassert_not_null(sigset); */ /* not implemented */ + /* zassert_not_null(sigsuspend); */ /* not implemented */ + /* zassert_not_null(sigtimedwait); */ /* not implemented */ + /* zassert_not_null(sigwait); */ /* not implemented */ + /* zassert_not_null(sigwaitinfo); */ /* not implemented */ +#endif }