From faf864b04f7b54bb35b52a32433fb3924fb4fb01 Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Mon, 12 Jan 2026 09:11:52 +0800 Subject: [PATCH] sched/signal: Add support for disabling all signal functions Signals in NuttX serve two primary purposes: 1. Synchronization and wake-up: Signals can be used to block threads on specific signal sets and later wake them up by delivering the corresponding signals to those threads. 2. Asynchronous notification: Signals can also be used to install callback handlers for specific signals, allowing threads to asynchronously invoke those handlers when the signals are delivered. This change introduces the ability to disable all signal functionality to reduce footprint for NuttX. Signed-off-by: Chengdong Wang wangchengdong@lixiang.com --- fs/procfs/fs_procfsproc.c | 3 ++- fs/vfs/Kconfig | 1 + include/nuttx/sched.h | 2 ++ include/sys/syscall_lookup.h | 2 ++ libs/libc/libc.csv | 10 ++++----- libs/libc/signal/CMakeLists.txt | 40 +++++++++++++++++---------------- libs/libc/signal/Make.defs | 2 ++ libs/libc/spawn/lib_psa_init.c | 2 ++ sched/Kconfig | 15 +++++++++++++ sched/group/CMakeLists.txt | 7 ++++-- sched/group/Make.defs | 6 ++++- sched/misc/assert.c | 4 ++++ sched/pthread/pthread_exit.c | 4 ++++ sched/signal/CMakeLists.txt | 36 +++++++++++++++-------------- sched/signal/Make.defs | 3 ++- sched/task/task_restart.c | 2 ++ sched/task/task_setup.c | 2 ++ sched/task/task_spawnparms.c | 2 ++ syscall/syscall.csv | 14 ++++++------ 19 files changed, 104 insertions(+), 53 deletions(-) diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index 310bd63e5fb..a1a58fe1b5a 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -640,10 +640,11 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile, } /* Show the signal mask. Note: sigset_t is uint32_t on NuttX. */ - +#ifndef CONFIG_DISABLE_ALL_SIGNALS linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s" SIGSET_FMT "\n", "SigMask:", SIGSET_ELEM(&tcb->sigprocmask)); +#endif copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, &offset); diff --git a/fs/vfs/Kconfig b/fs/vfs/Kconfig index b84b08778b8..ed51ee08391 100644 --- a/fs/vfs/Kconfig +++ b/fs/vfs/Kconfig @@ -51,6 +51,7 @@ endif # TIMER_FD config SIGNAL_FD bool "SignalFD" + depends on !DISABLE_ALL_SIGNALS default n ---help--- Create a file descriptor for accepting signals diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 10766b1a4f6..8a83aefc435 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -667,9 +667,11 @@ struct tcb_s sq_queue_t sigpendactionq; /* List of pending signal actions */ sq_queue_t sigpostedq; /* List of posted signals */ #endif /* CONFIG_ENABLE_ALL_SIGNALS*/ +#ifndef CONFIG_DISABLE_ALL_SIGNALS sigset_t sigprocmask; /* Signals that are blocked */ sigset_t sigwaitmask; /* Waiting for pending signals */ siginfo_t *sigunbinfo; /* Signal info when task unblocked */ +#endif /* !CONFIG_DISABLE_ALL_SIGNALS */ /* Robust mutex support ***************************************************/ diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h index 2d497b9e1c6..39ef26c16c4 100644 --- a/include/sys/syscall_lookup.h +++ b/include/sys/syscall_lookup.h @@ -158,11 +158,13 @@ SYSCALL_LOOKUP(tgkill, 3) SYSCALL_LOOKUP(sigaction, 3) SYSCALL_LOOKUP(sigpending, 1) #endif +#ifndef CONFIG_DISABLE_ALL_SIGNALS SYSCALL_LOOKUP(sigprocmask, 3) SYSCALL_LOOKUP(sigqueue, 3) SYSCALL_LOOKUP(sigsuspend, 1) SYSCALL_LOOKUP(sigtimedwait, 3) SYSCALL_LOOKUP(sigwaitinfo, 2) +#endif SYSCALL_LOOKUP(clock_nanosleep, 4) /* The following are only defined if the system clock is enabled in the diff --git a/libs/libc/libc.csv b/libs/libc/libc.csv index c3c0551521a..36627d9a743 100644 --- a/libs/libc/libc.csv +++ b/libs/libc/libc.csv @@ -269,11 +269,11 @@ "setlogmask","syslog.h","","int","int" "setpriority","sys/resource.h","","int","int","id_t","int" "shutdown","sys/socket.h","defined(CONFIG_NET)","int","int","int" -"sigaddset","signal.h","","int","FAR sigset_t *","int" -"sigdelset","signal.h","","int","FAR sigset_t *","int" -"sigemptyset","signal.h","","int","FAR sigset_t *" -"sigfillset","signal.h","","int","FAR sigset_t *" -"sigismember","signal.h","","int","FAR const sigset_t *","int" +"sigaddset","signal.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","FAR sigset_t *","int" +"sigdelset","signal.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","FAR sigset_t *","int" +"sigemptyset","signal.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","FAR sigset_t *" +"sigfillset","signal.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","FAR sigset_t *" +"sigismember","signal.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","FAR const sigset_t *","int" "signal","signal.h","defined(CONFIG_ENABLE_ALL_SIGNALS)","_sa_handler_t","int","_sa_handler_t" "sleep","unistd.h","","unsigned int","unsigned int" "snprintf","stdio.h","","int","FAR char *","size_t","FAR const IPTR char *","..." diff --git a/libs/libc/signal/CMakeLists.txt b/libs/libc/signal/CMakeLists.txt index 14ef7372aaa..7cf52f9c484 100644 --- a/libs/libc/signal/CMakeLists.txt +++ b/libs/libc/signal/CMakeLists.txt @@ -20,25 +20,27 @@ # # ############################################################################## -set(SRCS - sig_addset.c - sig_delset.c - sig_emptyset.c - sig_fillset.c - sig_nandset.c - sig_andset.c - sig_orset.c - sig_xorset.c - sig_isemptyset.c - sig_killpg.c - sig_altstack.c - sig_hold.c - sig_ismember.c - sig_pause.c - sig_psignal.c - sig_raise.c - sig_relse.c - sig_wait.c) +if(NOT CONFIG_DISABLE_ALL_SIGNALS) + set(SRCS + sig_addset.c + sig_delset.c + sig_emptyset.c + sig_fillset.c + sig_nandset.c + sig_andset.c + sig_orset.c + sig_xorset.c + sig_isemptyset.c + sig_killpg.c + sig_altstack.c + sig_hold.c + sig_ismember.c + sig_pause.c + sig_psignal.c + sig_raise.c + sig_relse.c + sig_wait.c) +endif() if(CONFIG_ENABLE_ALL_SIGNALS) list(APPEND SRCS sig_ignore.c sig_interrupt.c sig_set.c sig_signal.c) diff --git a/libs/libc/signal/Make.defs b/libs/libc/signal/Make.defs index cd20f64b109..7c2874c4e11 100644 --- a/libs/libc/signal/Make.defs +++ b/libs/libc/signal/Make.defs @@ -22,11 +22,13 @@ # Add the signal C files to the build +ifneq ($(CONFIG_DISABLE_ALL_SIGNALS),y) CSRCS += sig_addset.c sig_delset.c sig_emptyset.c sig_fillset.c CSRCS += sig_nandset.c sig_andset.c sig_orset.c sig_xorset.c CSRCS += sig_isemptyset.c sig_killpg.c sig_altstack.c CSRCS += sig_hold.c sig_ismember.c sig_pause.c sig_psignal.c CSRCS += sig_raise.c sig_relse.c sig_wait.c +endif ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y) CSRCS += sig_ignore.c sig_interrupt.c sig_set.c sig_signal.c diff --git a/libs/libc/spawn/lib_psa_init.c b/libs/libc/spawn/lib_psa_init.c index 306e68d1a98..aaff5ea5a9e 100644 --- a/libs/libc/spawn/lib_psa_init.c +++ b/libs/libc/spawn/lib_psa_init.c @@ -87,7 +87,9 @@ int posix_spawnattr_init(posix_spawnattr_t *attr) /* Empty signal mask */ +#ifndef CONFIG_DISABLE_ALL_SIGNALS sigemptyset(&attr->sigmask); +#endif #ifdef CONFIG_SCHED_SPORADIC /* Sporadic scheduling parameters */ diff --git a/sched/Kconfig b/sched/Kconfig index 28a2379c280..15cc90ff564 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -1578,6 +1578,21 @@ config ENABLE_PARTIAL_SIGNALS - Applications using basic signals without fork/exec - Resource-constrained real-time systems +config DISABLE_ALL_SIGNALS + bool "Disable all signal support" + select DISABLE_MQUEUE_NOTIFICATION + ---help--- + Disable all signal-related functionality, including signal + handling, thread cancellation, timers, and process-related + notifications. + + This option provides the smallest footprint and maximum + resource savings. + + Typical use cases: + - Hard real-time or safety-critical systems + - Applications that do not use POSIX signals or timers + endchoice config SIG_PREALLOC_ACTIONS diff --git a/sched/group/CMakeLists.txt b/sched/group/CMakeLists.txt index cec78f23513..6211a2c7c66 100644 --- a/sched/group/CMakeLists.txt +++ b/sched/group/CMakeLists.txt @@ -27,8 +27,11 @@ set(SRCS group_setupidlefiles.c group_setuptaskfiles.c group_foreachchild.c - group_killchildren.c - group_signal.c) + group_killchildren.c) + +if(NOT CONFIG_DISABLE_ALL_SIGNALS) + list(APPEND SRCS group_signal.c) +endif() if(CONFIG_SCHED_HAVE_PARENT) if(CONFIG_SCHED_CHILD_STATUS) diff --git a/sched/group/Make.defs b/sched/group/Make.defs index 61f0a03ec9a..336beda8f21 100644 --- a/sched/group/Make.defs +++ b/sched/group/Make.defs @@ -22,7 +22,11 @@ CSRCS += group_create.c group_join.c group_leave.c CSRCS += group_setupidlefiles.c group_setuptaskfiles.c -CSRCS += group_foreachchild.c group_killchildren.c group_signal.c +CSRCS += group_foreachchild.c group_killchildren.c + +ifneq ($(CONFIG_DISABLE_ALL_SIGNALS),y) +CSRCS += group_signal.c +endif ifeq ($(CONFIG_SCHED_HAVE_PARENT),y) ifeq ($(CONFIG_SCHED_CHILD_STATUS),y) diff --git a/sched/misc/assert.c b/sched/misc/assert.c index a5cd333d697..8da7a1a9953 100644 --- a/sched/misc/assert.c +++ b/sched/misc/assert.c @@ -405,7 +405,9 @@ static void dump_task(FAR struct tcb_s *tcb, FAR void *arg) #endif " %3d %-8s %-7s %-3c" " %-18s" +#ifndef CONFIG_DISABLE_ALL_SIGNALS " " SIGSET_FMT +#endif " %p" " %7zu" #ifdef CONFIG_STACK_COLORATION @@ -427,7 +429,9 @@ static void dump_task(FAR struct tcb_s *tcb, FAR void *arg) >> TCB_FLAG_TTYPE_SHIFT] , tcb->flags & TCB_FLAG_EXIT_PROCESSING ? 'P' : '-' , state +#ifndef CONFIG_DISABLE_ALL_SIGNALS , SIGSET_ELEM(&tcb->sigprocmask) +#endif , tcb->stack_base_ptr , tcb->adj_stack_size #ifdef CONFIG_STACK_COLORATION diff --git a/sched/pthread/pthread_exit.c b/sched/pthread/pthread_exit.c index 494a00c3409..c1c023672e6 100644 --- a/sched/pthread/pthread_exit.c +++ b/sched/pthread/pthread_exit.c @@ -65,7 +65,9 @@ void nx_pthread_exit(FAR void *exit_value) { FAR struct tcb_s *tcb = this_task(); +#ifndef CONFIG_DISABLE_ALL_SIGNALS sigset_t set; +#endif int status; sinfo("exit_value=%p\n", exit_value); @@ -76,8 +78,10 @@ void nx_pthread_exit(FAR void *exit_value) * are performing the JOIN handshake. */ +#ifndef CONFIG_DISABLE_ALL_SIGNALS sigfillset(&set); nxsig_procmask(SIG_SETMASK, &set, NULL); +#endif /* Complete pending join operations */ diff --git a/sched/signal/CMakeLists.txt b/sched/signal/CMakeLists.txt index e1e2ad910d9..9db325fec5e 100644 --- a/sched/signal/CMakeLists.txt +++ b/sched/signal/CMakeLists.txt @@ -20,23 +20,25 @@ # # ############################################################################## -set(SRCS - sig_procmask.c - sig_suspend.c - sig_kill.c - sig_tgkill.c - sig_queue.c - sig_waitinfo.c - sig_timedwait.c - sig_lowest.c - sig_notification.c - sig_dispatch.c - sig_pause.c - sig_nanosleep.c - sig_usleep.c - sig_sleep.c - sig_ppoll.c - sig_pselect.c) +if(NOT CONFIG_DISABLE_ALL_SIGNALS) + set(SRCS + sig_procmask.c + sig_suspend.c + sig_kill.c + sig_tgkill.c + sig_queue.c + sig_waitinfo.c + sig_timedwait.c + sig_lowest.c + sig_notification.c + sig_dispatch.c + sig_pause.c + sig_nanosleep.c + sig_usleep.c + sig_sleep.c + sig_ppoll.c + sig_pselect.c) +endif() if(CONFIG_ENABLE_ALL_SIGNALS) list( diff --git a/sched/signal/Make.defs b/sched/signal/Make.defs index a9eb9245a1f..b70ac2a8246 100644 --- a/sched/signal/Make.defs +++ b/sched/signal/Make.defs @@ -19,11 +19,12 @@ # under the License. # ############################################################################ - +ifneq ($(CONFIG_DISABLE_ALL_SIGNALS),y) CSRCS += sig_dispatch.c sig_kill.c sig_lowest.c sig_nanosleep.c CSRCS += sig_notification.c sig_pause.c sig_ppoll.c sig_procmask.c CSRCS += sig_pselect.c sig_queue.c sig_sleep.c sig_suspend.c sig_tgkill.c CSRCS += sig_timedwait.c sig_usleep.c sig_waitinfo.c +endif ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y) CSRCS += sig_action.c sig_allocpendingsigaction.c sig_cleanup.c sig_deliver.c diff --git a/sched/task/task_restart.c b/sched/task/task_restart.c index f2dcc4db628..d129945e89d 100644 --- a/sched/task/task_restart.c +++ b/sched/task/task_restart.c @@ -122,7 +122,9 @@ static void nxtask_reset_task(FAR struct tcb_s *tcb, bool remove) #ifdef CONFIG_ENABLE_ALL_SIGNALS nxsig_cleanup(tcb); /* Deallocate Signal lists */ #endif +#ifndef CONFIG_DISABLE_ALL_SIGNALS sigemptyset(&tcb->sigprocmask); /* Reset sigprocmask */ +#endif /* Reset the current task priority */ diff --git a/sched/task/task_setup.c b/sched/task/task_setup.c index 6748392401d..5c9cd83e764 100644 --- a/sched/task/task_setup.c +++ b/sched/task/task_setup.c @@ -461,7 +461,9 @@ static int nxthread_setup_scheduler(FAR struct tcb_s *tcb, int priority, * inherit the signal mask of the parent thread. */ +#ifndef CONFIG_DISABLE_ALL_SIGNALS tcb->sigprocmask = rtcb->sigprocmask; +#endif /* Initialize the task state. It does not get a valid state * until it is activated. diff --git a/sched/task/task_spawnparms.c b/sched/task/task_spawnparms.c index 7022b5d5767..b79fc460198 100644 --- a/sched/task/task_spawnparms.c +++ b/sched/task/task_spawnparms.c @@ -157,6 +157,7 @@ int spawn_execattrs(pid_t pid, FAR const posix_spawnattr_t *attr) /* Firstly, set the signal mask if requested to do so */ +#ifndef CONFIG_DISABLE_ALL_SIGNALS if ((attr->flags & POSIX_SPAWN_SETSIGMASK) != 0) { FAR struct tcb_s *tcb = nxsched_get_tcb(pid); @@ -165,6 +166,7 @@ int spawn_execattrs(pid_t pid, FAR const posix_spawnattr_t *attr) tcb->sigprocmask = attr->sigmask; } } +#endif /* If we are only setting the priority, then call sched_setparm() * to set the priority of the of the new task. diff --git a/syscall/syscall.csv b/syscall/syscall.csv index 08e02598b9c..531154b0c50 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -105,10 +105,10 @@ "pipe2","unistd.h","defined(CONFIG_PIPES) && CONFIG_DEV_PIPE_SIZE > 0","int","int [2]|FAR int *","int" "poll","poll.h","","int","FAR struct pollfd *","nfds_t","int" "posix_spawn","spawn.h","!defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_LIBC_EXECFUNCS)","int","FAR pid_t *","FAR const char *","FAR const posix_spawn_file_actions_t *","FAR const posix_spawnattr_t *","FAR char * const []|FAR char * const *","FAR char * const []|FAR char * const *" -"ppoll","poll.h","","int","FAR struct pollfd *","nfds_t","FAR const struct timespec *","FAR const sigset_t *" +"ppoll","poll.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","FAR struct pollfd *","nfds_t","FAR const struct timespec *","FAR const sigset_t *" "prctl","sys/prctl.h","","int","int","...","uintptr_t","uintptr_t" "pread","unistd.h","","ssize_t","int","FAR void *","size_t","off_t" -"pselect","sys/select.h","","int","int","FAR fd_set *","FAR fd_set *","FAR fd_set *","FAR const struct timespec *","FAR const sigset_t *" +"pselect","sys/select.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","int","FAR fd_set *","FAR fd_set *","FAR fd_set *","FAR const struct timespec *","FAR const sigset_t *" "pthread_cancel","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t" "pthread_cond_broadcast","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *" "pthread_cond_clockwait","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *","FAR pthread_mutex_t *","clockid_t","FAR const struct timespec *" @@ -177,11 +177,11 @@ "signal","signal.h","defined(CONFIG_ENABLE_ALL_SIGNALS)","_sa_handler_t","int","_sa_handler_t" "signalfd","sys/signalfd.h","defined(CONFIG_SIGNAL_FD)","int","int","FAR const sigset_t *","int" "sigpending","signal.h","defined(CONFIG_ENABLE_ALL_SIGNALS)","int","FAR sigset_t *" -"sigprocmask","signal.h","","int","int","FAR const sigset_t *","FAR sigset_t *" -"sigqueue","signal.h","","int","int","int","union sigval|FAR void *|sival_ptr" -"sigsuspend","signal.h","","int","FAR const sigset_t *" -"sigtimedwait","signal.h","","int","FAR const sigset_t *","FAR struct siginfo *","FAR const struct timespec *" -"sigwaitinfo","signal.h","","int","FAR const sigset_t *","FAR struct siginfo *" +"sigprocmask","signal.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","int","FAR const sigset_t *","FAR sigset_t *" +"sigqueue","signal.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","int","int","union sigval|FAR void *|sival_ptr" +"sigsuspend","signal.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","FAR const sigset_t *" +"sigtimedwait","signal.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","FAR const sigset_t *","FAR struct siginfo *","FAR const struct timespec *" +"sigwaitinfo","signal.h","!defined(CONFIG_DISABLE_ALL_SIGNALS)","int","FAR const sigset_t *","FAR struct siginfo *" "socket","sys/socket.h","defined(CONFIG_NET)","int","int","int","int" "socketpair","sys/socket.h","defined(CONFIG_NET)","int","int","int","int","int [2]|FAR int *" "stat","sys/stat.h","","int","FAR const char *","FAR struct stat *"