Forum Programmation.c rattacher sur init

Posté par  .
Étiquettes : aucune
0
28
déc.
2006
bonjour à tous,

je commence à étudier le C et bien évidemment j'essaie les divers exercices proposés ça et là. Et voici que je bute sur un problème qui est peut-être lié aux avancés de gcc.
Voici le soucis: j'essaie de faire en sorte qu'un processus soit rattaché à init

ex:

#include sys/types.h
#include unistd.h

main() {
pid_t pid;
pid = fork();

if (!pid) {
sleep(3);
execl("./executable", NULL, NULL);
} else {
return;
}
}


mon soucis ici, c'est que executable reprend le pid du lanceur...
Merci d'avance pour vos lumières et désolé pour la question que certains jugeront stupide.
  • # Commentaires

    Posté par  . Évalué à 10.

    je commence à étudier le C
    Bon courage :)
    Et voici que je bute sur un problème qui est peut-être lié aux avancés de gcc.
    Ou peut-être à ton code ? Avant de jeter la pierre à tes outils (ok, tu as mis "peut-être"), il est parfois préférable d'y regarder à deux fois.
    mon soucis ici, c'est que executable reprend le pid du lanceur...
    J'ai du mal à comprendre ta phrase. Ici, le "lanceur", c'est le processus qui reçoit le 0 par le fork, ou le processus qui a lancé le programme (i.e. le shell, par exemple) ?
    #include sys/types.h
    #include unistd.h
    Je suppose que les < et > sont partis durant le copié-collé... (en passant, ce n'est pas du C "pur", mais l'extension au langage C fournie par la norme POSIX. Je précise juste pour qu'il n'y ait pas de confusion, vu que tu commences à étudier le C)
    main() {
    Non. main renvoie une valeur de type int. gcc accepte que main ne renvoie rien, mais c'est une extension non portable, à éviter. Par ailleurs, si tu n'utilises pas de paramètres, il est conseillé de mettre un void explicite comme liste de paramètres (le void n'est pas nécessaire pour main, mais permet d'être plus clair). D'où :
    int main(void)
    La suite :
            pid_t pid;
            pid = fork();
    
            if (!pid) {
    Pour des valeurs entières, je préfère le test plus explicite :
            if (pid == 0) {
    On remarque que tu n'as prévu que 2 cas dans ton code, alors qu'il y en a normalement 3 : l'erreur (-1), le succès et le processus fils qui continue (0) et le succès et le processus père qui continue (fork renvoie alors le PID du fils). Pour savoir ce qui se passe précisément, distinguer les 3 cas serait souhaitable. Si le forka échoué, le programme quitte sans appeler executable. S'il a réussi, le processus père quitte, et c'est seulement le processus fils qui remplacera sa propre image par celle de executable. Donc le processus exécutant executable aura le PID du fils, et non celui du père. Par contre, son PPID sera celui de son père. Et quand le père se termine, le PPID du fils est changé pour être celui d'un processus défini par l'implémentation (dixit SUSv3), usuellement init si je me souviens bien (ou le grand-père ?).
                    execl("./executable", NULL, NULL);
    Il serait bon de vérifier si l'appel fonctionne (-1 en cas d'erreur). Pour l'instant, ça a l'air de marcher, mais quand tu voudras changer le nom du programme appelé, ou que tu te placeras dans un autre dossier pour le lancer, ou... alors tu seras content d'avoir un message d'erreur explicite ;)
            } else {
    
                    return;
    
            }
    Comme tu n'as pas donné de type de retour à main il est cohérent de ne pas retourner de valeur, mais comme main doit renvoyer une valeur entière, il vaut mieux renvoyer 0 (ou EXIT_SUCCESS).
    • [^] # Re: Commentaires

      Posté par  . Évalué à 2.

      Bonjour
      Merci pour ta réponse et ces précisions :)
      Mon ouvrage de référence concernant l'étude de C est celui publié par Brian Kernighan et Denis Ritchie: "Le langage C - norme ANSI" aux éditions Masson.
      Le code que j'ai présenté dans mon premier post était intentionnellement réduit à sa plus simple expression afin de centrer exactement la source de mon problème. En évitant de surcharger «inutilement» mon exemple je me donnais l'avantage d'être lu par un maximum de personnes :) Quand c'est trop long beaucoup de lecteurs zappent.
      Ceci étant, je ne parviens toujours pas à lancer executable avec un PID égal à 1.
      Je continue mes recherches tout en appronfondissant... Un jour sûrement... ;)

      Merci encore en tout cas pour ces bons conseils :)
      D'ailleurs en passant, si vous avez des sites ou ouvrages à me recommander n'hésitez pas :)
      • [^] # Re: Commentaires

        Posté par  . Évalué à 3.

        J'ai peur de dire des conneries, mais je pense pas que tu puisses faire ça (en tout cas je sais pas comment le faire).

        Le fait d'avoir un PID == 1 n'est tout simplement pas possible. 1 est "reservé" à init qui est le premier porcess lancé et tout les autres dépendront de lui (même indirectement).
        DONC, avoir un process avec un pid 1, c'est mort.

        Maintenant, avoir un process qui dépende de 1 (PPID == 1), dépend plutot de comment tu le lances. En l'occurence, lance le avec un & à la fin et celui ci se "détachera" de ton shell et prendra comme PPID celui d'init.

        Concernant ton problème (celui exposé dans ton post initial), lis un peu de doc sur fork() et ça devrais allé.

        Plus globalement, qu'est-ce que tu veux faire ?

        Et enfin, le Kernighan & Ritchie est un très bon bouquin pour apprendre le c.

        Courage!
        • [^] # Re: Commentaires

          Posté par  . Évalué à 3.

          Maintenant, avoir un process qui dépende de 1 (PPID == 1), dépend plutot de comment tu le lances. En l'occurence, lance le avec un & à la fin et celui ci se "détachera" de ton shell et prendra comme PPID celui d'init.

          Le & fait dépendre le process d'init ? J'ai un doute, là... Il ne le lance pas plutôt dans un sous-shell, pour en garder le contrôle ? (je n'ai pas de shell sous la main pour faire le test)
          • [^] # Re: Commentaires

            Posté par  . Évalué à 2.

            J'ai un shell sous la main :)

            Effectivement, rajouter un & ne le fait pas dépendre d'init, mais bel et bien du shell qui l'as lancé.

            Par contre, quand on ferme le shell qui l'a lancer, le process se retrouve sans papa (orphelin) et init en reprend donc la garde.
      • [^] # Re: Commentaires

        Posté par  . Évalué à 3.

        Bon choix pour le K&R ;) Je suppose que c'est la 2è édition ? N'oublie pas http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html pour les errata.
        Ceci étant, je ne parviens toujours pas à lancer executable avec un PID égal à 1.
        Un PPID égal à 1, tu veux dire ?
        D'ailleurs en passant, si vous avez des sites ou ouvrages à me recommander n'hésitez pas :)
        J'ai déjà donné la FAQ de c.l.c. Il y a aussi :
        • celle de fr.comp.lang.c ;
        • celle de developpez.com ;
        • http://clc-wiki.net/ qui est un site assez récent (donc encore peu rempli), développé par des gens de comp.lang.c (donc bien) (mais j'ai souvent des problèmes pour m'y connecter). Il pointe lui-même sur des ressources intéressantes ;
        • et le site officiel du groupe au sein de l'ISO qui édite la norme C http://www.open-std.org/JTC1/SC22/WG14/ , sur lequel tu peux trouver principalement des versions de travail (drafts) de la norme (en suivant le lien "standards", le n1124 étant la dernière version C99 + correctifs) et le "Rationale" qui est un commentaire de la norme faite par le groupe de travail lui-même, et qui donne des explications détaillées sur le pourquoi du comment.
        • pour faire du POSIX, la norme elle-même est payante, mais la Single Unix Specification, qui englobe POSIX plus d'autres choses, est elle gratuite et dispo sur http://www.unix.org/single_unix_specification/ .
        • je suggèrerai aussi la doc de ton compilo, les man...
        • [^] # Re: Commentaires

          Posté par  . Évalué à 2.

          une lettre et tout change de sens...
          en effet, c'est bien du ppid dont il est question.
          Mon problème venait de là (pid != ppid)
          J'espère que ces fautes stupides d'écriture se feront plus rares au fil de ma progression. Grace à Vim je suis quasi assuré de ne pas oublier un guillemet mais pour le reste...

          J'ai de quoi faire maintenant avant de revenir vous ennuyer :)
          Un grand merci à vous deux (alveric et cereal killer) pour vos indications :)
          à la prochaine pour des interrogations surement beaucoup plus complexes :)
        • [^] # Re: Commentaires

          Posté par  . Évalué à 1.

          J'ai oublié de souligner :

          >Bon choix pour le K&R ;) Je suppose que c'est la 2è édition ?

          oui :)
          et merci pour les liens pointant sur les erratas :)
      • [^] # Re: Commentaires

        Posté par  . Évalué à 1.

        Je vous conseille le livre: Le Passeport unix et C,j'ai oublié l'auteur..
        mais c'est un bon livre

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.