Comment tuer un processus d'arbre par programme sur Linux à l'aide de C

Je suis en train d'écrire une fonction qui génère un processus enfant, permet de l'exécuter pour un certain laps de temps et puis la tue si elle n'a pas fini d':

int sysExecTimeout(const char * exePath, int timeoutSec);

Dans la fonction, j'utilise fork et execl à pondre l'enfant, et, quand il expire, j'utilise kill(pid, SIGTERM) et kill(pid, SIGKILL) après 2 secondes, pour s'assurer du décès de l'enfant:

pid_t pid = fork();

if(pid == 0) {
    execl("/bin/sh", "sh", "-c", exePath);
    exit(127);
} else if(pid != -1) {
    //timeout code
    if(timeout) {
        kill(pid, SIGTERM);
        sleep(2);
        kill(pid, SIGKILL);
    }
}

Je suis sous Linux, et il semble que lorsqu'un parent meurt, l'enfant n'est pas tué automatiquement. Donc, les deux kill appels il suffit de tuer le /bin/sh processus et de laisser le exePath commande en cours d'exécution, car il est un processus enfant de /bin/sh.

Je suis en train d'écrire le sysExecTimeout fonction telle qu'il tue tout le processus arbre enraciné au pid, où pid est le PID de pid = fork()

J'ai besoin de cette parce que le exePath commande va lancer d'autres commandes, qui peuvent également engendrer d'autres commandes, ce qui pourrait se coincer et de consommer les ressources.

Je n'ai pas de contrôle sur le exePath fichiers binaires et des scripts que exécutée, donc je ne peux pas écrire mon propre parent-meurt-si-tuer-les-enfants logique.

J'ai essayé d'utiliser kill(0, SIGTERM), qui a presque fait le travail, sauf qu'il a aussi tué mon propre processus 🙂

Je me demande si il y a un drapeau je peux l'activer par programmation en C qui dit "hey man, quand je mourrai, tous mes enfants et de les tuer, et de répéter de manière récursive pour leurs enfants" ce qui fait que l'ensemble du processus de l'arbre a commencé à partir de ce programme meurt (en supposant que le PID/PPID de la chaîne peut être suivie).

Je pouvais le drapeau ici:

if(pid == 0) {
    turnOnRecursiveDeathFlag();

    system(exePath);
    //execl("/bin/sh", "sh", "-c", exePath);
    exit(127);
}

Est-il un moyen de le faire? J'ai cherché pendant un certain temps, mais tout ce que je peux trouver sont des hacks à l'aide de ps -ef, ou de modifier les processus enfants que vous êtes en cours d'exécution, etc.

} else if(pid == -1) { : cela indique un problème avec fork(), pas le processus de l'enfant..
Oui, désolé, c'est une faute de frappe 🙂

OriginalL'auteur Alin Tomescu | 2013-03-28