This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 9244b5a737c9222aa3df3eac167f76ce7e7e50b8
Author: dongjiuzhu1 <[email protected]>
AuthorDate: Thu Dec 22 20:46:12 2022 +0800

    signal: Support sigaction:sa_user, siginfo_t:si_user with user info
    
    When the signal sent by the sender is blocked in the target task,
    if the target task has an action registered with sa_flags SA_KENELHAND,
    it will directly respond to the action in the context of the sender.
    When the action is executed, it will have the parameters set by the
    target task with sigaction:sa_user.
    
    Signed-off-by: dongjiuzhu1 <[email protected]>
---
 include/signal.h            |  3 +++
 sched/signal/sig_action.c   |  1 +
 sched/signal/sig_dispatch.c | 19 +++++++++++++++++++
 3 files changed, 23 insertions(+)

diff --git a/include/signal.h b/include/signal.h
index 9805b1e9fc..7d089055c1 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 6768ec38ee..c58b2bf961 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 6f8f3c120e..77d0c5ef71 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);
         }
     }
 

Reply via email to