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 2d93ed66c8e03c48213904df24e4d3699307e406 Author: Marco Casaroli <[email protected]> AuthorDate: Fri Oct 23 17:50:24 2026 +0200 drivers/serial: Read the process group of TIOCSPGRP through the pointer. tcsetpgrp() passes a pointer to the process group ID to TIOCSPGRP, as POSIX and Linux do, and include/nuttx/serial/tioctl.h says so. The serial and the pty drivers read the argument as the ID itself, so tcsetpgrp() set the address as the foreground process: the next TIOCGPGRP gave it back, and SIGINT from Ctrl-C went to no task. When the address was above 0x7fffffff, tcsetpgrp() failed with EINVAL. Now TIOCSPGRP reads the ID through the pointer and fails with EINVAL for a NULL pointer or an ID that is not positive. TIOCSCTTY keeps its argument, a flag or the PID itself, which NSH uses. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- drivers/serial/pty.c | 21 ++++++++++++++++++++- drivers/serial/serial.c | 21 ++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/serial/pty.c b/drivers/serial/pty.c index 0726a824487..e005afbfbd6 100644 --- a/drivers/serial/pty.c +++ b/drivers/serial/pty.c @@ -894,7 +894,6 @@ static int pty_ioctl(FAR struct file *filep, int cmd, unsigned long arg) /* Make the controlling terminal of the calling process */ case TIOCSCTTY: - case TIOCSPGRP: { /* Save the PID of the foreground process group that is to receive * tty-generated signals. A zero 'arg' selects the calling task @@ -914,6 +913,26 @@ static int pty_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } break; + /* Set the foreground process group: as tcsetpgrp() passes it, 'arg' + * points to the process group ID. + */ + + case TIOCSPGRP: + { + FAR const pid_t *pgrp = (FAR const pid_t *)((uintptr_t)arg); + + if (pgrp == NULL || *pgrp <= 0) + { + ret = -EINVAL; + } + else + { + dev->pd_pid = *pgrp; + ret = 0; + } + } + break; + case TIOCNOTTY: { dev->pd_pid = INVALID_PROCESS_ID; diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index d8743938160..c151bf194b1 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -1969,7 +1969,6 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) /* Make the controlling terminal of the calling process */ case TIOCSCTTY: - case TIOCSPGRP: { /* Save the PID of the foreground process group that is to * receive tty-generated signals (SIGINT/SIGTSTP). @@ -1993,6 +1992,26 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } break; + /* Set the foreground process group: as tcsetpgrp() passes it, + * 'arg' points to the process group ID. + */ + + case TIOCSPGRP: + { + FAR const pid_t *pgrp = (FAR const pid_t *)((uintptr_t)arg); + + if (pgrp == NULL || *pgrp <= 0) + { + ret = -EINVAL; + } + else + { + dev->pid = *pgrp; + ret = 0; + } + } + break; + case TIOCNOTTY: { dev->pid = INVALID_PROCESS_ID;
