2017-02-11 2 views
4

Existe-t-il une méthode ou une API dans Linux/POSIX pour déterminer si le processus en cours est un fork? C'est à dire. si elle a été créée en appelant fork() sans appel ultérieur à la famille execve()?Comment tester si le processus d'appel est une branche

Je ne contrôle pas le code précédant ce point (il s'exécute dans une liaison de langage de haut niveau). J'ai juste besoin de savoir si le processus actuel exécute le programme de niveau supérieur, ou dans une fourchette de celui-ci.

Le meilleur que je suis venu avec teste si le processus a le même GID que son parent:

int is_fork = getpgid(0) == getpgid(getppid()); 

Cependant, cela ne fonctionne que si le parent a appelé setpgid() qui apparemment execve() ne le fait pas par défaut. Cela entraîne donc beaucoup de faux positifs.

+0

Contrôlez-vous le programme? Si oui, la seule façon de savoir quelque chose comme cela, je peux penser serait d'avoir une variable d'état défini dans le processus de l'enfant après 'fourchue fork()'. – cfromme

+3

Votre formulation est un peu étrange. ** Chaque processus ** (sauf init) est créé par 'fork()' Votre question devrait donc être: mon processus est-il un chef de groupe de processus? – wildplasser

+0

@wildplasser Je ne connais pas vraiment la terminologie. Mais je pense que le chef de groupe de processus est le proc ancêtre qui a appelé 'setpgid()', pas celui qui appelle 'exec()'? – Jeroen

Répondre

0

Peut-être que vous pouvez utiliser tms_utime, tms_stime, tms_cutime ou tms_cstime (voir http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html). Ces variables sont définies sur 0 dans le processus fils.

non testé

+1

Elles sont définies sur 0 à la fourche, mais elles ne restent pas nulles pendant l'exécution du processus. De plus, ceci ne fait pas la différence entre 'fork()' et 'fork()' suivi de 'exec()'. – user4815162342

1

Sur Linux, un contrôle quelque peu imprécis serait de voir si l'exécutable du processus (/proc/$pid/exe) est identique à celle de son parent. Cependant, cela ne fonctionnera pas si un processus exec est son propre exécutable, ce qui pourrait être commun dans certains environnements (par exemple. Coquilles).

+0

Désolé, je n'ai pas vu ta réponse! J'ai supprimé le mien. S'il vous plaît, pardonnez-moi. –

+0

@ jean-baptiste: pas de soucis. Pas un gros problème. – rici

0

Si vous pouvez contrôler l'environnement de l'exécutable de niveau supérieur, vous pouvez utiliser LD_PRELOAD pour précharger une bibliothèque partagée qui installe un gestionnaire pthread_atfork qui marque l'enfant comme étant un fork en définissant un global visible. Votre code de test peut alors vérifier la valeur de la variable pour savoir si le processus a été fourchue sans intervention exec.

-1
/* ppid.c 
cc -Wall ppid.c -o ppid 
*/ 

#include <stdio.h> 
#include <unistd.h> 

int main(int argc, char **argv) 
{ 
int pid, ppid, pgid; 

pid = getpid(); 
ppid = getppid(); 
pgid = getpgid(0); 

printf("[%s] Pid=%d Ppid=%d Pgid=%d\n" 
     , argv[0], pid, ppid, pgid); 

return 0; 
} 

/* testppid.c 
cc -Wall testppid.c -c testppid 
*/ 

#include <stdio.h> 
#include <unistd.h> 

int main(void) 
{ 
int pid, pid2; 

pid = fork(); 
if (pid == -1) return 1; 

if (pid) { /* parent */ 
     char *args[] = { "Parent", NULL}; 
     sleep(3); 
     execve("./ppid", args, NULL); 
} else { /* child */ 

     pid = getpid(); 
     setpgid(pid,pid); 
     pid2 = fork(); 
     if (pid2 == -1) return 1; 

     if (pid2) { /* child1 */ 
       char *args[] = { "Child1", NULL}; 
       sleep(2); 
       execve("./ppid", args, NULL); 

     } else { /* grandchild */ 
       char *args[] = { "Child2", NULL}; 
       sleep(1); 
       execve("./ppid", args, NULL); 
       } 
     } 

return 0; 
} 

sortie:


$ ./testppid 
[Child2] Pid=6220 Ppid=6219 Pgid=6219 
[Child1] Pid=6219 Ppid=6218 Pgid=6219 
[Parent] Pid=6218 Ppid=27410 Pgid=6218 
$ 

Ceci indique que la coque (pid = 27410) fait essentiellement le même pour le processus parent comme Child1 ne befo re invoque Child2: {fork, setpgid, exec}. Child1 est le leader du groupe pour lui-même et procès- Enfant2 (le petit-enfant)

+0

Merci pour la critique. J'avais vraiment besoin de ça. – wildplasser