killbelow - send a signal to all descendant processes
#include <sys/killbelow.h>
int killbelow(int signal, int timeout);
killbelow() sends the signal signal to all descendant processes. The timeout argument specifies the maximal interval in miliseconds to wait until there are no descendant processes.
killbelow() is most useful if a process calling it is a reaper for its descendant processes. Reaper status can be aquired by using procctl(2) with PROC_REAP_ACQUIRE or prctl(2) with PR_SET_CHILD_SUBREAPER.
Signal will be delivered to every descendant process even if its user ID is different from the process calling killbelow().
On success, a value of 0 is returned; meaning that there are no running descendant processes. A value of 1 indicates that the call timed out and there is at least one descendant process left.
On error, -1 is returned, and errno is set appropriately.
killbelow() will fail and no signal will be sent if:
Unprivileged processes don't have instruments to reliably terminate all its descendant processes. That functionality is especially missing in scripts. A script can have processes in its sub-process tree, that have different user ID aquired by calling sudo(1)/doas(1). However it can't even terminate such processes.
chroot(2), cgroups(7) and jail(8) usually need higher privileges or interfacing with a separate daemon.
Process groups and sessions are not a solution, because every process can call setpgid(2) or setsid(2).
On Linux a partial solution, that should cover most cases is to use pid_namespaces(7).
Name is intended to convey a meaning of sending of a signal to processes below in the process tree.
Author of this page is aware, that he possibly does not understand Unix or English.
if (killbelow(SIGTERM, 5000) > 0) {
killbelow(SIGKILL, 0);
}
reinvent it, poorly.