casaroli opened a new pull request, #21144:
URL: https://github.com/apache/nuttx/pull/21144

   ## Summary
   
   This PR fixes two parts of job control on a console: the Ctrl-C and Ctrl-Z 
characters that send a signal, and `kill()` to a process group.
   
   - **drivers/serial: Discard the INTR and SUSP characters that send a 
signal.** When `ISIG` is set and the terminal knows its foreground process, 
INTR (Ctrl-C) and SUSP (Ctrl-Z) send `SIGINT` and `SIGTSTP`. The serial driver 
also put the character into the receive buffer, so the next `read()` gave it to 
the program: after Ctrl-C, a shell read `^C` in front of the next command line. 
POSIX (General Terminal Interface, 11.1.9 "Special Characters") says that the 
terminal discards these characters when `ISIG` is set; the pty and telnet 
drivers already do. Now `uart_recvchars()` removes them in the `receive()` and 
`recvbuf()` paths. A character that sends no signal (no foreground process, or 
`ISIG` not set) stays in the data. The DMA path does not change. The commit 
also keeps the first signal of a batch: the check of each later character set 
the signal back to 0, so Ctrl-C followed by more characters in the same 
interrupt sent no signal.
   - **Documentation: Say that the serial driver discards Ctrl-C and Ctrl-Z.** 
One sentence in the job control paragraph of `serial.rst`.
   - **sched/signal: Send kill() to a process group as one process.** `kill()` 
failed with `ENOSYS` for a negative pid (a process group), and pid 0 (the 
process group of the caller) 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. Now pid 
0 is the caller and -pid is the process pid; pid -1 (all processes) still fails 
with `ENOSYS`. A shell with job control sends `kill %1` to the process group of 
the job.
   - **Documentation: Say that kill() sends to a process group of one 
process.** The `kill()` reference and `serial.rst` said that a signal to a 
process group is not supported.
   
   ## Impact
   
   Behaviour change, every build mode (flat too):
   
   - Serial consoles with `CONFIG_TTY_SIGINT` or `CONFIG_TTY_SIGTSTP` and a 
foreground process: the program no longer reads the Ctrl-C or Ctrl-Z character 
that sent the signal. Without a foreground process nothing changes: NSH sets 
the foreground process only while a foreground command runs (`TIOCSCTTY`, then 
`TIOCNOTTY`), so at the NSH prompt the readline editor still gets Ctrl-C.
   - `kill(0, sig)` now signals the caller (before: the idle task). `kill(-pid, 
sig)` now signals process pid (before: `ENOSYS`); a group that does not exist 
gives `ESRCH` (before: `ENOSYS`). `kill(-1, sig)` still fails with `ENOSYS`.
   
   In-tree users, nuttx and nuttx-apps master: `examples/nanoxterm` calls 
`kill(-pid, SIGHUP)`; it now reaches the child. NSH's `kill` command accepts 
only a pid >= 0, so `kill -9 0` now signals NSH itself (before: the idle task). 
All other `kill()` and `nxsig_kill()` callers pass a pid > 0 (a child, a 
daemon, the foreground PID of a terminal). The only ^C reader in nuttx-apps, 
`system/readline` (Ctrl-C cancels a Ctrl-R search), runs at the NSH prompt.
   
   ## Testing
   
   Tested on master 192ac6d3fbc and on this PR rebased on it, with QEMU (HVF), 
`CONFIG_TTY_SIGINT`, `CONFIG_TTY_SIGTSTP` and `CONFIG_SIG_DEFAULT`: 
`qemu-armv8a:knsh` (kernel build, programs on v9fs) and `qemu-armv8a:nsh` (flat 
build, the programs as NSH built-ins on the serial console).
   
   `isigtest.c` catches `SIGINT` and reads a line from the console; the test 
types Ctrl-C, then `abc` and Enter. The same result in the kernel and the flat 
build:
   
   | Case | master | this PR |
   |---|---|---|
   | one `SIGINT` | 1: PASS | 1: PASS |
   | the line that `read()` gives | `03 61 62 63 0a` (the Ctrl-C first): FAIL | 
`61 62 63 0a`: PASS |
   
   `killpgrp.c`; the child is the program itself, started with `posix_spawn()`. 
The same result in the kernel and the flat build:
   
   | Case | master | this PR |
   |---|---|---|
   | `getpgid(child) == child` | PASS | PASS |
   | `kill(-child, SIGTERM)` | -1, `ENOSYS`: FAIL | 0: PASS |
   | the child ends (`waitpid()`) | PASS (the test kills it) | PASS |
   | `kill(0, SIGUSR1)` runs the handler of the caller | no (the idle task got 
it): FAIL | PASS |
   | `kill(0, 0)` | 0: PASS | 0: PASS |
   | `kill(-1, 0)` | -1, `ENOSYS`: PASS | -1, `ENOSYS`: PASS |
   | `kill(-30000, 0)` (no such group) | -1, `ENOSYS`: FAIL | -1, `ESRCH`: PASS 
|
   
   ostest exits with status 0 on `qemu-armv8a:knsh` and `qemu-armv8a:nsh`, on 
master and with this PR.
   
   Builds, each OK and without new warnings: `lm3s6965-ek:nsh` (flat, 
Cortex-M3) with `CONFIG_SERIAL_TERMIOS`, `CONFIG_TTY_SIGINT` and 
`CONFIG_TTY_SIGTSTP`; `lm3s6965-ek:qemu-protected` (protected, Cortex-M3); 
`rv-virt:pnsh64` (protected, RISC-V) and `rv-virt:knsh64` (kernel, RISC-V) with 
`CONFIG_SERIAL_TERMIOS`, `CONFIG_TTY_SIGINT` and `CONFIG_TTY_SIGTSTP`.
   
   `tools/checkpatch.sh -c -u -m -g` passes.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to