I think it's a non-problem TBH. You can use process groups (yes like shells do). Alternatively you can track all child process ids and kill them all one by one explicitly and do that recursively in your process tree. Each sub-process in the tree that starts child processes is expected to do also this reliably.
The problem is, the children programs you launch may also use process groups to implement job control for their children, and process groups are not nested. Which means it's all very brittle, and e.g. sending SIGKILL will actually leave lots of orphans around instead of cleaning everything.
OK yeah I get that. Back in the day you used to we used to processes like containers. The system programmer would write the process executables or at least a process manager. If a process ever called setpgrp itself it did it for a controlled reason and because it was supposed to. You were in control of that because you wrote it so it's a non problem.
In modern times wer'e doing more thing like containerizing a bunch of processes they are weakly related instead of using a VM for that so the use case became more pressing. There is cgroups for managing such a group of processes. I'm suprised to learn there is no way to reliably send a signal to all processes in a cgroup though.
> SIGKILL will actually leave lots of orphans around instead of cleaning everything.
Well actually orphan processes exist for a reason. Your supposed to "wait" / reap them to make them non orphan.
Yeah and similarly, if you're a terminal program, using process groups for your children means that they'll keep running if the user presses Ctrl-C. Process groups really just weren't designed for anything that's not like a system shell.