Si tu n’as jamais été confrontée à la programmation système, ce n’est pas étonnant d’être un peu perdu au début car il est vrai que c’est déroutant.
Pour que ton exemple fonctionne comme attendu, il faudrait faire ça:
1
2
3
4
5
6
7
8
9
10
11
12 | int pid;
pid = fork ();
if (pid == 0)
execl("/bin/sh", "sh", "-c", "sleep 10; /tmp/monscript.sh", NULL);
pid = fork ();
if (pid == 0)
execl("/bin/sh", "sh", "-c", "sleep 10; hostname", NULL);
pid = fork ();
if (pid == 0)
execl("/bin/sh", "sh", "-c", "sleep 10; firefox", NULL);
|
Car comme j’ai expliqué, exec
remplace ton binaire par un autre. Donc tu arrives à la situation suivante.
Le processus père voit ton if
qui ne le concerne pas (il a le pid de son fils qui est forcément différent de 0). Dans ton cas il n’ira jamais dans le bloc avec tous tes exec
.
Le fils entre dedans, il exécute la fonction exec
qui remplace le binaire. La prochaine instruction du processus fils sera donc le sous-shell contenu dans l’appel d’exec. Mais pour le fils, tout ton code a maintenant disparu, les autres exec
ont disparu car maintenant le processus fils est un sous-shell. Il n’est plus le binaire que tu as écrit.
Donc pour que tes différents exec
fonctionnent, il faut faire autant de fork
que d’appels à exec
pour que tu aies toujours un processus fils capable d’exécuter le suivant.
C’est d’ailleurs ce que fait system
, chaque appel à cette fonction implique (de manière cachée) un fork
suivi d’un exec
pour le fils et d’un wait
pour le processus père appelant.
Pour l’histoire du script, oui, peut être fusionner tes appels dans un seul script serait plus simple. Je ne sais pas si ton deuxième code d’exemple reste juste une idée, mais si c’est globalement ce que tu veux faire, je suis quasiment convaincu qu’une situation plus élégante existe. Mais si tu n’expliques pas ton objectif concret on ne pourra rien te conseiller d’autres.