diff options
Diffstat (limited to 'apps/examples/ostest/sighand.c')
-rw-r--r-- | apps/examples/ostest/sighand.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/apps/examples/ostest/sighand.c b/apps/examples/ostest/sighand.c index eabfe5646..32b182c21 100644 --- a/apps/examples/ostest/sighand.c +++ b/apps/examples/ostest/sighand.c @@ -54,12 +54,37 @@ static sem_t sem; static bool sigreceived = false; static bool threadexited = false; +#ifdef CONFIG_SCHED_HAVE_PARENT +static void death_of_child(int signo, siginfo_t *info, void *ucontext) +{ + /* Use of printf in a signal handler is NOT safe! It can cause deadlocks! + * Also, signals are not queued by NuttX. As a consequence, some + * notifications will get lost (or the info data can be overwrittedn)! + * Because POSIX does not require signals to be queued, I do not think + * that this is a bug (the overwriting is a bug, however). + */ + + if (info) + { + printf("death_of_child: PID %d received signal=%d code=%d pid=%d status=%d\n", + getpid(), signo, info->si_code, info->si_pid, info->si_status); + } + else + { + printf("death_of_child: PID %d received signal=%d (no info?)\n", + getpid(), signo); + } +} +#endif + static void wakeup_action(int signo, siginfo_t *info, void *ucontext) { sigset_t oldset; sigset_t allsigs; int status; + /* Use of printf in a signal handler is NOT safe! It can cause deadlocks! */ + printf("wakeup_action: Received signal %d\n" , signo); sigreceived = true; @@ -186,6 +211,11 @@ static int waiter_main(int argc, char *argv[]) void sighand_test(void) { +#ifdef CONFIG_SCHED_HAVE_PARENT + struct sigaction act; + struct sigaction oact; + sigset_t sigset; +#endif struct sched_param param; union sigval sigvalue; pid_t waiterpid; @@ -195,6 +225,32 @@ void sighand_test(void) printf("sighand_test: Initializing semaphore to 0\n" ); sem_init(&sem, 0, 0); +#ifdef CONFIG_SCHED_HAVE_PARENT + printf("sighand_test: Unmasking SIGCHLD\n"); + + (void)sigemptyset(&sigset); + (void)sigaddset(&sigset, SIGCHLD); + status = sigprocmask(SIG_UNBLOCK, &sigset, NULL); + if (status != OK) + { + printf("sighand_test: ERROR sigprocmask failed, status=%d\n", + status); + } + + printf("sighand_test: Registering SIGCHLD handler\n" ); + act.sa_sigaction = death_of_child; + act.sa_flags = SA_SIGINFO; + + (void)sigfillset(&act.sa_mask); + (void)sigdelset(&act.sa_mask, SIGCHLD); + + status = sigaction(SIGCHLD, &act, &oact); + if (status != OK) + { + printf("waiter_main: ERROR sigaction failed, status=%d\n" , status); + } +#endif + /* Start waiter thread */ printf("sighand_test: Starting waiter task\n" ); @@ -262,6 +318,13 @@ void sighand_test(void) printf("sighand_test: ERROR signal handler did not run\n" ); } + /* Detach the signal handler */ + +#ifdef CONFIG_SCHED_HAVE_PARENT + act.sa_sigaction = SIG_DFL; + status = sigaction(SIGCHLD, &act, &oact); +#endif + printf("sighand_test: done\n" ); FFLUSH(); } |