diff --git a/include/signal.h b/include/signal.h index 9805b1e9fc4..7d089055c18 100644 --- a/include/signal.h +++ b/include/signal.h @@ -269,6 +269,7 @@ * being masked in the handler */ #define SA_RESETHAND (1 << 6) /* Clears the handler when the signal * is delivered */ +#define SA_KERNELHAND (1 << 7) /* Invoke the handler in kernel space directly */ /* These are the possible values of the signfo si_code field */ @@ -371,6 +372,7 @@ struct siginfo #if 0 /* Not implemented */ FAR void *si_addr; /* Report address with SIGFPE, SIGSEGV, or SIGBUS */ #endif + FAR void *si_user; /* The User info associated with sigaction */ }; #ifndef __SIGINFO_T_DEFINED @@ -401,6 +403,7 @@ struct sigaction } sa_u; sigset_t sa_mask; int sa_flags; + FAR void *sa_user; }; /* Definitions that adjust the non-standard naming */ diff --git a/sched/signal/sig_action.c b/sched/signal/sig_action.c index 6768ec38ee3..c58b2bf9613 100644 --- a/sched/signal/sig_action.c +++ b/sched/signal/sig_action.c @@ -373,6 +373,7 @@ int nxsig_action(int signo, FAR const struct sigaction *act, sigact->act.sa_handler = handler; sigact->act.sa_mask = act->sa_mask; sigact->act.sa_flags = act->sa_flags; + sigact->act.sa_user = act->sa_user; } return OK; diff --git a/sched/signal/sig_dispatch.c b/sched/signal/sig_dispatch.c index 6f8f3c120e6..77d0c5ef718 100644 --- a/sched/signal/sig_dispatch.c +++ b/sched/signal/sig_dispatch.c @@ -214,6 +214,24 @@ static FAR sigpendq_t * return sigpend; } +/**************************************************************************** + * Name: nxsig_dispatch_kernel_action + ****************************************************************************/ + +static void nxsig_dispatch_kernel_action(FAR struct tcb_s *stcb, + FAR siginfo_t *info) +{ + FAR struct task_group_s *group = stcb->group; + FAR sigactq_t *sigact; + + sigact = nxsig_find_action(group, info->si_signo); + if (sigact && (sigact->act.sa_flags & SA_KERNELHAND)) + { + info->si_user = sigact->act.sa_user; + (sigact->act.sa_sigaction)(info->si_signo, info, NULL); + } +} + /**************************************************************************** * Name: nxsig_add_pendingsignal * @@ -263,6 +281,7 @@ static void nxsig_add_pendingsignal(FAR struct tcb_s *stcb, flags = enter_critical_section(); sq_addlast((FAR sq_entry_t *)sigpend, &group->tg_sigpendingq); leave_critical_section(flags); + nxsig_dispatch_kernel_action(stcb, &sigpend->info); } }