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. * ****************************************************************************/
