Comment puis-je lancer un démon dans uClinux en utilisant vfork?
Question
Ce serait facile avec une fourchette (), mais je n'ai pas de MMU. J'ai entendu dire que les blocs vfork () le processus parent jusqu'à ce que les sorties de l'enfant ou exécute exec (). Comment pourrais-je accomplir quelque chose comme ceci:
pid_t pid = vfork();
if (pid == -1) {
// fail
exit(-1);
}
if (pid == 0) {
// child
while(1) {
// Do my daemon stuff
}
// Let's pretend it exits sometime
exit();
}
// Continue execution in parent without blocking.....
La solution
Il semble qu'il n'y a aucun moyen de le faire exactement comme vous l'avez ici. exec
ou _exit
doivent obtenir appelé pour le parent de poursuivre l'exécution. Soit mettre le code du démon dans un autre exécutable et exec
, ou utiliser l'enfant pour frayer la tâche d'origine. La seconde approche est la façon sournoise, et est décrite ici.
Autres conseils
démon () ( ), par Jamie Lokier, au format patch
Vous ne pouvez pas faire daemon () avec vfork (). Pour créer quelque chose de semblable à un démon sur! MMU en utilisant vfork (), le processus parent ne meurt pas (donc il y a des processus supplémentaires), et vous devriez appeler votre démon sur le fond (c.-en annexant et à la ligne de commande sur la shell).
D'autre part, Linux fournit clone (). Armé de cette connaissance et de soins, il est possible de mettre en œuvre le démon () pour! MMU. Jamie Lokier a une fonction pour le faire que sur ARM et i386, faites-le
J'aurais pensé que ce serait le type de problème que beaucoup d'autres se sont heurtées, mais je l'ai eu du mal à trouver quelqu'un parler des problèmes « tuer le parent ». Je pensais d'abord que vous devriez être en mesure de le faire avec un (pas tout à fait, mais en quelque sorte) simple appel à Sauf que la détermination du pile_fils et la child_func de travailler la manière dont il le fait avec vfork est assez difficile car child_func devrait être l'adresse de retour de l'appel clone et le pile_fils devrait être le sommet de la pile au point de l'appel système réel (sys_clone) est réalisée. Vous pouvez probablement essayer d'appeler Ce que je pense pourrait obtenir ce que vous voulez. NULL comme passage second argument, qui est le pointeur pile_fils, provoque le noyau à faire la même chose comme dans vfork et une fourchette, ce qui est d'utiliser la même pile que le parent. Je ne l'ai jamais utilisé est équivalent à Si cela ne fonctionne pas (et vous ne pouvez pas savoir comment faire quelque chose de similaire), vous pourriez être en mesure d'utiliser l'appel clone régulier avec les appels clone
, comme ceci: pid_t new_vfork(void) {
return clone(child_func, /* child function */
child_stack, /* child stack */
SIGCHLD | CLONE_VM, /* flags */
NULL, /* argument to child */
NULL, /* pid of the child */
NULL, /* thread local storage for child */
NULL); /* thread id of child in child's mem */
}
sys_clone
directement avec pid_t new_vfork(void) {
return sys_clone( SIGCHLD | CLONE_VM, NULL);
}
sys_clone
directement et n'a pas testé, mais je pense que cela devrait fonctionner. Je crois que: sys_clone( SIGCHLD | CLONE_VM | CLONE_VFORK, NULL);
vfork
. setjump
et longjmp
à imiter, ou vous pourrez peut-être contourner la nécessité de la sémantique « de retour deux fois » de fork
et vfork
.