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]
