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

   ## Summary
   
   The child of `fork()` and `vfork()` started with no signal actions. The 
action list of its new task group was empty, and so was the set of the signals 
that have the default action (only `nxtask_start()` fills it). So no signal had 
its default action in the child: a child that had not called exec ignored 
SIGTERM, SIGINT and even SIGKILL, and a handler of the parent did not run in 
the child. A shell forks for a subshell, for a pipeline and for a command in 
the background, so `kill` could not stop these.
   
   POSIX says that the child has the signal actions of the parent, the signal 
mask of the calling thread and no pending signals. This PR adds 
`nxsig_dupactions()`, which copies the action list and the set of the signals 
with the default action to the new group, and calls it in 
`nxtask_setup_fork()`. The signal mask is already copied by 
`nxtask_setup_scheduler()`.
   
   ## Impact
   
   All build modes and architectures with `fork()` or `vfork()` 
(`CONFIG_ARCH_HAVE_FORK`) and `CONFIG_ENABLE_ALL_SIGNALS`. A child that calls 
exec gets the actions that exec sets, as before. No interface or structure 
changes.
   
   ## Testing
   
   Tested on master aeab6fbf989 and on this PR rebased on it.
   
   Test program `forksig.c` on `qemu-armv8a:knsh` (QEMU with HVF, 
`CONFIG_SCHED_CHILD_STATUS=y`). A child that does not end sleeps 5 s and exits 
with 99.
   
   | Case | master | this PR |
   |---|---|---|
   | SIGTERM to a child that sleeps | child runs on, exits with 99 after 4.85 s 
| child ends at once |
   | SIGINT to a child that sleeps | child runs on, exits with 99 | child ends 
at once |
   | SIGKILL to a child that sleeps | child runs on, exits with 99 | child ends 
at once |
   | a SIGUSR1 handler of the parent runs in the child | no | yes |
   | SIGTERM that the parent ignores is ignored in the child | yes | yes |
   | a signal that the parent blocks is blocked in the child | yes | yes |
   | `forkkill.c`: `waitpid()` of a fork() child that SIGTERM ends | hangs 
(EINTR after a 5 s alarm) | returns the child |
   | ostest, `qemu-armv8a:knsh` and `qemu-armv8a:nsh` | status 0 | status 0 |
   
   `forkkill.c` also checks `WTERMSIG()` of the status: that part needs the 
exit status fix for a child ended by a signal, which is not in this PR.
   
   The flat build has only `vfork()`, where the parent waits for the child; 
there ostest (with its `vfork()` test) is the check.
   
   Build, each OK: `qemu-armv8a:nsh` (flat, arm64), `qemu-armv8a:knsh` (kernel, 
arm64), `lm3s6965-ek:qemu-protected` (protected, armv7-m), `qemu-armv7a:knsh` 
(kernel, armv7-a), `rv-virt:pnsh64` (protected, rv64), `rv-virt:knsh64` 
(kernel, rv64).
   
   `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