diff --git a/drivers/syslog/syslog_write.c b/drivers/syslog/syslog_write.c index 889086c1b66..8b3fefda709 100644 --- a/drivers/syslog/syslog_write.c +++ b/drivers/syslog/syslog_write.c @@ -56,8 +56,9 @@ static bool syslog_safe_to_block(void) { +#ifdef CONFIG_ENABLE_ALL_SIGNALS FAR const struct tcb_s *rtcb; - +#endif /* It's not safe to block in interrupts or when executing the idle loop */ if (up_interrupt_context() || sched_idletask()) @@ -67,11 +68,13 @@ static bool syslog_safe_to_block(void) /* It's not safe to block if a signal is being delivered */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS rtcb = nxsched_self(); if (rtcb->sigdeliver != NULL) { return false; } +#endif return true; } diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 132c7e5f43d..4bc63497aae 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -615,8 +615,9 @@ int up_backtrace(FAR struct tcb_s *tcb, * handler now. * ****************************************************************************/ - +#ifdef CONFIG_ENABLE_ALL_SIGNALS void up_schedule_sigaction(FAR struct tcb_s *tcb); +#endif /**************************************************************************** * Name: up_task_start @@ -708,7 +709,8 @@ void up_pthread_start(pthread_trampoline_t startup, * ****************************************************************************/ -#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__) +#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__) && \ + defined(CONFIG_ENABLE_ALL_SIGNALS) void up_signal_dispatch(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info, FAR void *ucontext); #endif diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index facbff4d5c4..10766b1a4f6 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -514,8 +514,10 @@ struct task_group_s /* POSIX Signal Control Fields ********************************************/ +#ifdef CONFIG_ENABLE_ALL_SIGNALS sq_queue_t tg_sigactionq; /* List of actions for signals */ sq_queue_t tg_sigpendingq; /* List of pending signals */ +#endif /* CONFIG_ENABLE_ALL_SIGNALS */ #ifdef CONFIG_SIG_DEFAULT sigset_t tg_sigdefault; /* Set of signals set to the default action */ #endif @@ -660,10 +662,13 @@ struct tcb_s /* POSIX Signal Control Fields ********************************************/ - sigset_t sigprocmask; /* Signals that are blocked */ - sigset_t sigwaitmask; /* Waiting for pending signals */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS + sig_deliver_t sigdeliver; sq_queue_t sigpendactionq; /* List of pending signal actions */ sq_queue_t sigpostedq; /* List of posted signals */ +#endif /* CONFIG_ENABLE_ALL_SIGNALS*/ + sigset_t sigprocmask; /* Signals that are blocked */ + sigset_t sigwaitmask; /* Waiting for pending signals */ siginfo_t *sigunbinfo; /* Signal info when task unblocked */ /* Robust mutex support ***************************************************/ @@ -707,11 +712,6 @@ struct tcb_s struct xcptcontext xcp; /* Interrupt register save area */ - /* The following function pointer is non-zero if there are pending signals - * to be processed. - */ - - sig_deliver_t sigdeliver; #if CONFIG_TASK_NAME_SIZE > 0 char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NUL terminator) */ #endif diff --git a/include/nuttx/userspace.h b/include/nuttx/userspace.h index 2166c89e680..98ecd35aca0 100644 --- a/include/nuttx/userspace.h +++ b/include/nuttx/userspace.h @@ -106,8 +106,10 @@ struct userspace_s /* Signal handler trampoline */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS CODE void (*signal_handler)(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info, FAR void *ucontext); +#endif /* User-space work queue support */ diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h index dd42e41b795..2d497b9e1c6 100644 --- a/include/sys/syscall_lookup.h +++ b/include/sys/syscall_lookup.h @@ -154,8 +154,10 @@ SYSCALL_LOOKUP(nxsem_wait_slow, 1) SYSCALL_LOOKUP(kill, 2) SYSCALL_LOOKUP(tgkill, 3) +#ifdef CONFIG_ENABLE_ALL_SIGNALS SYSCALL_LOOKUP(sigaction, 3) SYSCALL_LOOKUP(sigpending, 1) +#endif SYSCALL_LOOKUP(sigprocmask, 3) SYSCALL_LOOKUP(sigqueue, 3) SYSCALL_LOOKUP(sigsuspend, 1) diff --git a/libs/libc/libc.csv b/libs/libc/libc.csv index 8aaf50630f5..c3c0551521a 100644 --- a/libs/libc/libc.csv +++ b/libs/libc/libc.csv @@ -274,7 +274,7 @@ "sigemptyset","signal.h","","int","FAR sigset_t *" "sigfillset","signal.h","","int","FAR sigset_t *" "sigismember","signal.h","","int","FAR const sigset_t *","int" -"signal","signal.h","","_sa_handler_t","int","_sa_handler_t" +"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 *","..." "sprintf","stdio.h","","int","FAR char *","FAR const IPTR char *","..." diff --git a/libs/libc/signal/CMakeLists.txt b/libs/libc/signal/CMakeLists.txt index 00ccefdda7a..14ef7372aaa 100644 --- a/libs/libc/signal/CMakeLists.txt +++ b/libs/libc/signal/CMakeLists.txt @@ -20,27 +20,28 @@ # # ############################################################################## -target_sources( - c - PRIVATE 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_interrupt.c - sig_hold.c - sig_ignore.c - sig_ismember.c - sig_pause.c - sig_psignal.c - sig_raise.c - sig_relse.c - sig_set.c - sig_signal.c - sig_wait.c) +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(CONFIG_ENABLE_ALL_SIGNALS) + list(APPEND SRCS sig_ignore.c sig_interrupt.c sig_set.c sig_signal.c) +endif() + +target_sources(c PRIVATE ${SRCS}) diff --git a/libs/libc/signal/Make.defs b/libs/libc/signal/Make.defs index 7d42a239add..cd20f64b109 100644 --- a/libs/libc/signal/Make.defs +++ b/libs/libc/signal/Make.defs @@ -24,9 +24,13 @@ 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 sig_interrupt.c -CSRCS += sig_hold.c sig_ignore.c sig_ismember.c sig_pause.c sig_psignal.c -CSRCS += sig_raise.c sig_relse.c sig_set.c sig_signal.c sig_wait.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 + +ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y) +CSRCS += sig_ignore.c sig_interrupt.c sig_set.c sig_signal.c +endif # Add the signal directory to the build diff --git a/sched/Kconfig b/sched/Kconfig index 7c3d8092533..28a2379c280 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -1547,6 +1547,39 @@ endmenu # RTOS hooks menu "Signal Configuration" +choice + prompt "Signal support level" + default ENABLE_ALL_SIGNALS if !DEFAULT_SMALL + default ENABLE_PARTIAL_SIGNALS if DEFAULT_SMALL + +config ENABLE_ALL_SIGNALS + bool "Enable full signal support" + ---help--- + Enable full POSIX signal support, including signal handling, + thread cancellation, timers, and process-related notifications. + + This option provides the most complete signal functionality, + but increases code size and resource usage. + + Typical use cases: + - Applications relying on POSIX signals or timers + - Systems where memory and CPU resources are sufficient + +config ENABLE_PARTIAL_SIGNALS + bool "Enable partial signal support" + ---help--- + Disable process-related signal functionality while keeping + basic signal handling support. + + This option provides a balance between reduced resource usage + and limited signal functionality. + + Typical use cases: + - Applications using basic signals without fork/exec + - Resource-constrained real-time systems + +endchoice + config SIG_PREALLOC_ACTIONS int "Number of pre-allocated sigactions" default 4 diff --git a/sched/group/group_leave.c b/sched/group/group_leave.c index 5e69dc2d349..4ba91b1af97 100644 --- a/sched/group/group_leave.c +++ b/sched/group/group_leave.c @@ -86,7 +86,9 @@ static inline void group_release(FAR struct task_group_s *group) /* Release pending signals */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS nxsig_release(group); +#endif #ifndef CONFIG_DISABLE_PTHREAD /* Release pthread resources */ diff --git a/sched/group/group_signal.c b/sched/group/group_signal.c index a15b364ae86..f3c734b47a0 100644 --- a/sched/group/group_signal.c +++ b/sched/group/group_signal.c @@ -77,7 +77,9 @@ static int group_signal_handler(pid_t pid, FAR void *arg) { FAR struct group_signal_s *info = (FAR struct group_signal_s *)arg; FAR struct tcb_s *tcb; +#ifdef CONFIG_ENABLE_ALL_SIGNALS FAR sigactq_t *sigact; +#endif int ret; /* Get the TCB associated with the group member */ @@ -141,6 +143,7 @@ static int group_signal_handler(pid_t pid, FAR void *arg) /* Is there also a action associated with the task group? */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS sigact = nxsig_find_action(tcb->group, info->siginfo->si_signo); if (sigact) { @@ -164,6 +167,7 @@ static int group_signal_handler(pid_t pid, FAR void *arg) return 1; /* Terminate the search */ } } +#endif } return 0; /* Keep searching */ diff --git a/sched/init/nx_start.c b/sched/init/nx_start.c index be28b4565ca..1c7b931b050 100644 --- a/sched/init/nx_start.c +++ b/sched/init/nx_start.c @@ -644,7 +644,9 @@ void nx_start(void) /* Initialize the signal facility (if in link) */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS nxsig_initialize(); +#endif #if !defined(CONFIG_DISABLE_MQUEUE) || !defined(CONFIG_DISABLE_MQUEUE_SYSV) /* Initialize the named message queue facility (if in link) */ diff --git a/sched/signal/CMakeLists.txt b/sched/signal/CMakeLists.txt index 715db0a776b..e1e2ad910d9 100644 --- a/sched/signal/CMakeLists.txt +++ b/sched/signal/CMakeLists.txt @@ -21,27 +21,16 @@ # ############################################################################## set(SRCS - sig_initialize.c - sig_action.c sig_procmask.c - sig_pending.c sig_suspend.c sig_kill.c sig_tgkill.c sig_queue.c sig_waitinfo.c sig_timedwait.c - sig_findaction.c - sig_allocpendingsigaction.c - sig_releasependingsigaction.c - sig_unmaskpendingsignal.c - sig_removependingsignal.c - sig_releasependingsignal.c sig_lowest.c sig_notification.c - sig_cleanup.c sig_dispatch.c - sig_deliver.c sig_pause.c sig_nanosleep.c sig_usleep.c @@ -49,6 +38,23 @@ set(SRCS sig_ppoll.c sig_pselect.c) +if(CONFIG_ENABLE_ALL_SIGNALS) + list( + APPEND + SRCS + sig_action.c + sig_allocpendingsigaction.c + sig_cleanup.c + sig_deliver.c + sig_findaction.c + sig_initialize.c + sig_pending.c + sig_releasependingsigaction.c + sig_releasependingsignal.c + sig_removependingsignal.c + sig_unmaskpendingsignal.c) +endif() + if(CONFIG_SIG_DEFAULT) list(APPEND SRCS sig_default.c) endif() diff --git a/sched/signal/Make.defs b/sched/signal/Make.defs index cfb2ddc0060..a9eb9245a1f 100644 --- a/sched/signal/Make.defs +++ b/sched/signal/Make.defs @@ -20,15 +20,16 @@ # ############################################################################ -CSRCS += sig_initialize.c -CSRCS += sig_action.c sig_procmask.c sig_pending.c sig_suspend.c -CSRCS += sig_kill.c sig_tgkill.c sig_queue.c sig_waitinfo.c sig_timedwait.c -CSRCS += sig_findaction.c sig_allocpendingsigaction.c -CSRCS += sig_releasependingsigaction.c sig_unmaskpendingsignal.c -CSRCS += sig_removependingsignal.c sig_releasependingsignal.c sig_lowest.c -CSRCS += sig_notification.c sig_cleanup.c sig_dispatch.c sig_deliver.c -CSRCS += sig_pause.c sig_nanosleep.c sig_usleep.c sig_sleep.c -CSRCS += sig_ppoll.c sig_pselect.c +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 + +ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y) +CSRCS += sig_action.c sig_allocpendingsigaction.c sig_cleanup.c sig_deliver.c +CSRCS += sig_findaction.c sig_initialize.c sig_pending.c sig_releasependingsigaction.c +CSRCS += sig_releasependingsignal.c sig_removependingsignal.c sig_unmaskpendingsignal.c +endif ifeq ($(CONFIG_SIG_DEFAULT),y) CSRCS += sig_default.c diff --git a/sched/signal/sig_dispatch.c b/sched/signal/sig_dispatch.c index d9ca78f9d21..0a189e86c2d 100644 --- a/sched/signal/sig_dispatch.c +++ b/sched/signal/sig_dispatch.c @@ -50,6 +50,7 @@ * Private Types ****************************************************************************/ +#ifdef CONFIG_ENABLE_ALL_SIGNALS struct sig_arg_s { pid_t pid; @@ -437,6 +438,7 @@ static int nxsig_alloc_dyn_pending(FAR irqstate_t *flags) return ret; } +#endif /**************************************************************************** * Public Functions @@ -468,11 +470,13 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info, bool group_dispatch) { FAR struct tcb_s *rtcb = this_task(); - FAR sigactq_t *sigact; irqstate_t flags; int masked; int ret = OK; +#ifdef CONFIG_ENABLE_ALL_SIGNALS + FAR sigactq_t *sigact; FAR sigpendq_t *sigpend = NULL; +#endif sinfo("TCB=%p pid=%d signo=%d code=%d value=%d masked=%s\n", stcb, stcb->pid, info->si_signo, info->si_code, @@ -497,10 +501,6 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info, /************************** MASKED SIGNAL ACTIONS *************************/ - /* Find if there is a group sigaction associated with this signal */ - - sigact = nxsig_find_action(stcb->group, info->si_signo); - flags = enter_critical_section(); /* Make sure that there is always at least one sigpednq and sigq structure @@ -509,12 +509,14 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info, * needs to be done here before using the task state or sigprocmask. */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS ret = nxsig_alloc_dyn_pending(&flags); if (ret < 0) { leave_critical_section(flags); return ret; } +#endif masked = nxsig_ismember(&stcb->sigprocmask, info->si_signo); @@ -582,16 +584,19 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info, up_switch_context(this_task(), rtcb); } -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ENABLE_ALL_SIGNALS +# ifdef CONFIG_LIB_SYSCALL /* Must also add signal action if in system call */ if (masked == 0) { sigpend = nxsig_add_pendingsignal(stcb, info, group_dispatch); } +# endif #endif } +#ifdef CONFIG_ENABLE_ALL_SIGNALS /* Its not one we are waiting for... Add it to the list of pending * signals. */ @@ -600,16 +605,22 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info, { sigpend = nxsig_add_pendingsignal(stcb, info, group_dispatch); } +#endif } /************************* UNMASKED SIGNAL ACTIONS ************************/ else { +#ifdef CONFIG_ENABLE_ALL_SIGNALS + /* Find if there is a group sigaction associated with this signal */ + + sigact = nxsig_find_action(stcb->group, info->si_signo); + /* Queue any sigaction's requested by this task. */ ret = nxsig_queue_action(stcb, sigact, info); - +#endif /* Deliver of the signal must be performed in a critical section */ /* Check if the task is waiting for an unmasked signal. If so, then @@ -706,12 +717,14 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info, leave_critical_section(flags); +#ifdef CONFIG_ENABLE_ALL_SIGNALS /* Dispatch kernel action, if needed, in case a pending signal was added */ if (sigpend != NULL) { nxsig_dispatch_kernel_action(stcb, &sigpend->info); } +#endif /* In case nxsig_ismember failed due to an invalid signal number */ diff --git a/sched/signal/sig_procmask.c b/sched/signal/sig_procmask.c index b9a180170cf..1428877e086 100644 --- a/sched/signal/sig_procmask.c +++ b/sched/signal/sig_procmask.c @@ -145,7 +145,9 @@ int nxsig_procmask(int how, FAR const sigset_t *set, FAR sigset_t *oset) /* Now, process any pending signals that were just unmasked */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS nxsig_unmask_pendingsignal(); +#endif } return ret; diff --git a/sched/signal/sig_timedwait.c b/sched/signal/sig_timedwait.c index 096bae1cbaf..02a8b1131ae 100644 --- a/sched/signal/sig_timedwait.c +++ b/sched/signal/sig_timedwait.c @@ -334,8 +334,10 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info, FAR const struct timespec *timeout) { FAR struct tcb_s *rtcb; +#ifdef CONFIG_ENABLE_ALL_SIGNALS sigset_t intersection; FAR sigpendq_t *sigpend; +#endif irqstate_t flags; siginfo_t unbinfo; int ret; @@ -351,6 +353,7 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info, flags = enter_critical_section(); rtcb = this_task(); +#ifdef CONFIG_ENABLE_ALL_SIGNALS /* Check if there is a pending signal corresponding to one of the * signals in the pending signal set argument. */ @@ -387,6 +390,7 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info, /* We will have to wait for a signal to be posted to this task. */ else +#endif { rtcb->sigunbinfo = (info == NULL) ? &unbinfo : info; diff --git a/sched/signal/signal.h b/sched/signal/signal.h index 28fe4a9d02b..549745c659f 100644 --- a/sched/signal/signal.h +++ b/sched/signal/signal.h @@ -120,7 +120,9 @@ typedef struct sigq_s sigq_t; * structures buffers structures. */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS extern sigactq_t g_sigactions[CONFIG_SIG_PREALLOC_ACTIONS]; +#endif /* The g_sigfreeaction data structure is a list of available signal action * structures. @@ -164,7 +166,9 @@ struct task_group_s; /* sig_initializee.c */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS void nxsig_initialize(void); +#endif /* sig_action.c */ @@ -190,8 +194,10 @@ int nxsig_dispatch(pid_t pid, FAR siginfo_t *info, /* sig_cleanup.c */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS void nxsig_cleanup(FAR struct tcb_s *stcb); void nxsig_release(FAR struct task_group_s *group); +#endif /* sig_timedwait.c */ diff --git a/sched/task/task_exithook.c b/sched/task/task_exithook.c index 268931b247d..4d34ecf0025 100644 --- a/sched/task/task_exithook.c +++ b/sched/task/task_exithook.c @@ -455,7 +455,9 @@ void nxtask_exithook(FAR struct tcb_s *tcb, int status) /* Deallocate anything left in the TCB's queues */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS nxsig_cleanup(tcb); /* Deallocate Signal lists */ +#endif #ifdef CONFIG_SCHED_DUMP_LEAK if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL) diff --git a/sched/task/task_restart.c b/sched/task/task_restart.c index 07566a3d99e..f2dcc4db628 100644 --- a/sched/task/task_restart.c +++ b/sched/task/task_restart.c @@ -119,7 +119,9 @@ static void nxtask_reset_task(FAR struct tcb_s *tcb, bool remove) /* Deallocate anything left in the TCB's signal queues */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS nxsig_cleanup(tcb); /* Deallocate Signal lists */ +#endif sigemptyset(&tcb->sigprocmask); /* Reset sigprocmask */ /* Reset the current task priority */ diff --git a/syscall/syscall.csv b/syscall/syscall.csv index f4a403fafec..08e02598b9c 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -173,10 +173,10 @@ "shmdt","sys/shm.h","defined(CONFIG_MM_SHM)","int","FAR const void *" "shmget","sys/shm.h","defined(CONFIG_MM_SHM)","int","key_t","size_t","int" "shutdown","sys/socket.h","defined(CONFIG_NET)","int","int","int" -"sigaction","signal.h","","int","int","FAR const struct sigaction *","FAR struct sigaction *" -"signal","signal.h","","_sa_handler_t","int","_sa_handler_t" +"sigaction","signal.h","defined(CONFIG_ENABLE_ALL_SIGNALS)","int","int","FAR const struct sigaction *","FAR struct sigaction *" +"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","","int","FAR sigset_t *" +"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 *"