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

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

commit 61a5d5134fb614fac364a516af64c554c184a07d
Author: Marco Casaroli <[email protected]>
AuthorDate: Fri Oct 23 18:11:27 2026 +0200

    sched/signal: Send kill() to a process group as one process.
    
    kill() failed with ENOSYS for a negative pid (a process group), and for
    pid 0 (the process group of the caller) it sent the signal to the idle
    task.  In NuttX a process group is one process: getpgid() and
    setpgid() use the process ID as the group ID, and killpg() already
    sends the signal to that process.  A shell with job control sends
    "kill %1" to the process group of the job and failed.
    
    Now pid 0 is the caller and -pid is the process pid, as killpg() does.
    pid -1 (all processes) still fails with ENOSYS.
    
    Some functions used kill(pid, 0) to find a process, and a negative pid
    failed there.  So that it still fails: clock_getcpuclockid() and
    setpgid() (ESRCH) reject a negative pid, and waitpid() and waitid()
    look for the child with nxsched_get_tcb(), which is what kill(pid, 0)
    did.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 libs/libc/sched/clock_getcpuclockid.c |  2 +-
 libs/libc/unistd/lib_setpgid.c        |  7 +++++-
 sched/sched/sched_waitid.c            |  9 +++-----
 sched/sched/sched_waitpid.c           |  9 +++-----
 sched/signal/sig_kill.c               | 42 +++++++++++++++++++++++++----------
 5 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/libs/libc/sched/clock_getcpuclockid.c 
b/libs/libc/sched/clock_getcpuclockid.c
index d40caf0f477..6ab7f47ff50 100644
--- a/libs/libc/sched/clock_getcpuclockid.c
+++ b/libs/libc/sched/clock_getcpuclockid.c
@@ -60,7 +60,7 @@ int clock_getcpuclockid(pid_t pid, FAR clockid_t *clockid)
     {
       pid = _SCHED_GETPID();
     }
-  else if (_SIG_KILL(pid, 0) < 0)
+  else if (pid < 0 || _SIG_KILL(pid, 0) < 0)
     {
       return ERROR;
     }
diff --git a/libs/libc/unistd/lib_setpgid.c b/libs/libc/unistd/lib_setpgid.c
index 55d72659a68..5de2195c023 100644
--- a/libs/libc/unistd/lib_setpgid.c
+++ b/libs/libc/unistd/lib_setpgid.c
@@ -64,7 +64,12 @@ int setpgid(pid_t pid, pid_t pgid)
       return -1;
     }
 
-  if (pid == 0)
+  if (pid < 0)
+    {
+      set_errno(ESRCH);
+      return -1;
+    }
+  else if (pid == 0)
     {
       pid = _SCHED_GETPID();
     }
diff --git a/sched/sched/sched_waitid.c b/sched/sched/sched_waitid.c
index 8d78733736a..0fb082d516d 100644
--- a/sched/sched/sched_waitid.c
+++ b/sched/sched/sched_waitid.c
@@ -157,12 +157,9 @@ int waittcb(FAR struct tcb_s *rtcb, idtype_t idtype, int 
options,
         }
       else
         {
-          /* We can use nxsig_kill() with signal number 0 to determine if
-           * that task is still alive.
-           */
+          /* Is that task still alive? */
 
-          ret = nxsig_kill((pid_t)id, 0);
-          if (ret < 0)
+          if (nxsched_get_tcb((pid_t)id) == NULL)
             {
               /* It is no longer running.  We know that the child task
                * was running okay when we started, so we must have lost
@@ -183,7 +180,7 @@ int waittcb(FAR struct tcb_s *rtcb, idtype_t idtype, int 
options,
        */
 
       if (rtcb->group->tg_nchildren == 0 ||
-          (idtype == P_PID && (ret = nxsig_kill((pid_t)id, 0)) < 0))
+          (idtype == P_PID && nxsched_get_tcb((pid_t)id) == NULL))
         {
           /* We know that the child task was running okay we started,
            * so we must have lost the signal.  What can we do?
diff --git a/sched/sched/sched_waitpid.c b/sched/sched/sched_waitpid.c
index 484a2ce3307..9b5a2cb1db0 100644
--- a/sched/sched/sched_waitpid.c
+++ b/sched/sched/sched_waitpid.c
@@ -141,12 +141,9 @@ int waittcb(FAR struct tcb_s *rtcb, pid_t pid, int options,
         }
       else
         {
-          /* We can use nxsig_kill() with signal number 0 to determine if
-           * that task is still alive.
-           */
+          /* Is that task still alive? */
 
-          ret = nxsig_kill(pid, 0);
-          if (ret < 0)
+          if (nxsched_get_tcb(pid) == NULL)
             {
               /* It is no longer running.  We know that the child task
                * was running okay when we started, so we must have lost
@@ -169,7 +166,7 @@ int waittcb(FAR struct tcb_s *rtcb, pid_t pid, int options,
        */
 
       if (rtcb->group->tg_nchildren == 0 ||
-          (pid != INVALID_PROCESS_ID && nxsig_kill(pid, 0) < 0))
+          (pid != INVALID_PROCESS_ID && nxsched_get_tcb(pid) == NULL))
         {
           /* We know that the child task was running okay when we started,
            * so we must have lost the signal.  What can we do?
diff --git a/sched/signal/sig_kill.c b/sched/signal/sig_kill.c
index 75bbc5f2661..3320dbc8157 100644
--- a/sched/signal/sig_kill.c
+++ b/sched/signal/sig_kill.c
@@ -29,6 +29,7 @@
 #include <sys/types.h>
 #include <sched.h>
 #include <errno.h>
+#include <limits.h>
 #include <unistd.h>
 #include <nuttx/debug.h>
 
@@ -52,14 +53,14 @@
  *   the POSIX standard kill() function but does not modify the application
  *   errno variable.
  *
- *   Limitation: Sending of signals to 'process groups' is not
- *   supported in NuttX
+ *   A process group is one process in NuttX: a process group ID is the
+ *   ID of its only process.  A signal to all processes (pid -1) is not
+ *   supported.
  *
  * Input Parameters:
  *   pid - The id of the task to receive the signal.  The POSIX nxsig_kill
  *     specification encodes process group information as zero and
- *     negative pid values.  Only positive, non-zero values of pid are
- *     supported by this implementation.
+ *     negative pid values: 0 is the caller and -pid is the process pid.
  *   signo - The signal number to send.  If signo is zero, no signal is
  *     sent, but all error checking is performed.
  *
@@ -72,7 +73,7 @@
  *    EPERM  The process does not have permission to send the
  *           signal to any of the target processes.
  *    ESRCH  The pid or process group does not exist.
- *    ENOSYS Do not support sending signals to process groups.
+ *    ENOSYS pid is -1: a signal to all processes is not supported.
  *
  ****************************************************************************/
 
@@ -85,12 +86,29 @@ int nxsig_kill(pid_t pid, int signo)
   siginfo_t info;
 #endif
 
-  /* We do not support sending signals to process groups */
+  /* NuttX has no process group with more than one process: the process
+   * group of a process is the process itself (getpgid(), setpgid() and
+   * killpg() say so).  So pid 0 (the process group of the caller) is the
+   * caller, and -pid (the process group pid) is the process pid.  All the
+   * processes of the system (-1) are not supported.
+   */
 
-  if (pid < 0)
+  if (pid == 0)
+    {
+      pid = nxsched_getpid();
+    }
+  else if (pid == -1)
     {
       return -ENOSYS;
     }
+  else if (pid < 0 && pid != INT_MIN)
+    {
+      /* The process pid.  INT_MIN stays as it is (-INT_MIN does not
+       * fit): no process has it, so the signal fails with ESRCH.
+       */
+
+      pid = -pid;
+    }
 
   if (signo == 0)
     {
@@ -132,14 +150,14 @@ int nxsig_kill(pid_t pid, int signo)
  *   The kill() system call can be used to send any signal to any task
  *   group.
  *
- *   Limitation: Sending of signals to 'process groups' is not
- *   supported in NuttX
+ *   A process group is one process in NuttX: a process group ID is the
+ *   ID of its only process.  A signal to all processes (pid -1) is not
+ *   supported.
  *
  * Input Parameters:
  *   pid - The id of the task to receive the signal.  The POSIX kill
  *     specification encodes process group information as zero and
- *     negative pid values.  Only positive, non-zero values of pid are
- *     supported by this implementation.
+ *     negative pid values: 0 is the caller and -pid is the process pid.
  *   signo - The signal number to send.  If signo is zero, no signal is
  *     sent, but all error checking is performed.
  *
@@ -152,7 +170,7 @@ int nxsig_kill(pid_t pid, int signo)
  *      EPERM  The process does not have permission to send the
  *             signal to any of the target processes.
  *      ESRCH  The pid or process group does not exist.
- *      ENOSYS Do not support sending signals to process groups.
+ *      ENOSYS pid is -1: a signal to all processes is not supported.
  *
  ****************************************************************************/
 

Reply via email to