langage C unix
Répondre à la discussion
Affichage des résultats 1 à 16 sur 16

langage C unix



  1. #1
    Zone-x

    langage C unix


    ------

    bonjour
    j'ai rélisé un code qui donne le PID de fils a travers le père (pid > 0) ,le programme marche mais le problème ici c'est quand je fais la fonction execl(....) ,la fonction marche maiss toutes les lignes qui se trouvent apres cette fonction ne s'affichent pas par exemple des printf , voici donc le programme que j'ai réalisé :



    #include <stdio.h>
    #include <unistd.h>
    #include <srdlib.h>
    #include <sys/types.h>
    main(int agc,char *argv[]){
    int i,pid;
    pid=fork();
    int x;
    if (pid>0){
    execl("/bin/sleep","sleep","3",NULL);
    //apres la commande execl les 2 printf ne s'affichent pas
    printf("le pid de mon fils est %d ",x);
    printf(" je suis le pere);
    }
    else
    {
    printf("je suis le fils");
    }
    }


    et merci

    -----

  2. #2
    kwariz

    Re : langage C unix

    Bonsoir,

    pense aux balises codes quand tu insères du code ...

    Ensuite, il ya une chose super importante avec la famille de fonction exec qui est bien documenté dans la man page :
    Citation Envoyé par Man page exec
    [...]
    La famille de fonctions exec remplace l'image mémoire du processus en cours par un nouveau processus. Les fonctions décrites dans cette page sont en réalité des frontaux pour l'appel système execve(2). (Voir la page de execve pour des informations détaillées sur le remplacement du processus en cours.)
    [...]
    puis en consultant la man page d'execve (comme recommandé) :
    Citation Envoyé par Man page execve
    [...]
    En cas de réussite, execve() ne revient pas à l'appelant
    [...]
    Cela explique pourquoi les lignes suivant l'appel à execl ne sont pas exécutées. Si tu veux faire un pause dans ton processus utilise la fonction sleep directement, un appel à waitpid de la part de père peut s'avérer aussi utile (pour attendre la fin du processus fils avant de terminer). Encore deux détails, on préfère utiliser le type pid_t plutôt que int et surtout vérifier que le fork c'est bien déroulé (très important).

    Un petit programme d'exemple peut être :
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    
    int main()
    {
      /* Le fameux type pid_t ... */
      pid_t pid;
    
    
      /* On forke, au retour de la fonction pid peut valoir :                                                                       
       *   -1 : Il y a eu une erreur                                                                                                
       *    0 : On se trouve dans le processus fils                                                                                 
       *   >0 : On est dans le processus père et pid contient                                                                       
                le process id du processus fils                                                                                     
      */
      pid=fork();
      /* Comme prévu on checke s'il y a eu une erreur ...                                                                           
       * auquel cas on stoppe tout en prévenant l'utilisateur                                                                       
       */
      if (pid==-1) {
        puts("Erreur au fork()");
        exit(EXIT_FAILURE);
      } else if (pid==0) {
        /* Seul le processus fils exécutera cette partie du if */
        puts("Hello du fils");
        sleep(2); /* cet appel provoque une pause de 2 secondes */
        execl("/bin/ls", "ls", "-lh", NULL); /* on lance un ls */
        /* tout ce qui suit ne sera pas exécuté car le execl                                                                        
         * a "écrasé" tout le code ...                                                                                              
         */
        puts("Cette chaîne ne sera jamais affichée !");
      } else {
        /* Seul le père exécutera cette partie du if */
        puts("Hello du père");
        /* On attend la fin du processus fils                                                                                       
         * execl a créé un nouveau processus mais celui-ci                                                                          
         * héritera du même id que le processus qui l'a créé                                                                        
         * comme c'est le fils qui l'a créé, le ls aura le même                                                                     
         * id que le fils ... donc ça marche                                                                                        
         * sans le waitpid le père rend la main tout de suite                                                                       
         * et si les fils font par exemple une sortie sur STDOUT                                                                    
         * des lignes vont s'afficher sur ta console inopinément                                                                    
         * Tu peux essayer de mettre la ligne suivante en commentaire                                                               
         * pour voir ce que ça donne                                                                                                
         */
        waitpid(pid,NULL,WUNTRACED);
      }
    
    
      return 0;
    }
    Après compilation et exécution on obtient :
    Code:
    $> gcc -Wall -Wextra -g -o test test.c$> ./test 
    Hello du père
    Hello du fils
    total 16K
    -rwxrwxr-x 1 kwariz kwariz  11K Apr 12 02:43 test
    -rw-rw-r-- 1 kwariz kwariz 1.7K Apr 12 02:43 test.c
    $>
    Et en mettant la ligne en commentaire comme indiqué dans le code :
    Code:
    $> ./test 
    Hello du père
    Hello du fils
    $> total 16K
    -rwxrwxr-x 1 kwariz kwariz  11K Apr 12 02:43 test
    -rw-rw-r-- 1 kwariz kwariz 1.7K Apr 12 02:43 test.c

  3. #3
    kwariz

    Re : langage C unix

    Pour être complet j'aurais du quand même tester le retour de execl, en effet le programme passé en paramètre peut ne pas exister et dans ce cas execl rend la main ...

  4. #4
    Zone-x

    Re : langage C unix

    mais le probème lorsque je fais pid >0 dans cette condition tout ce qui suit la fonction execl ne s'affiche pas !

  5. A voir en vidéo sur Futura
  6. #5
    kwariz

    Re : langage C unix

    Oui, c;est normal ... c'est ce que je t'expliquais dans mon post précédent ...
    Un execl ne rend jamais la main ... le processus qui lance un execl est remplacé, mais vraiment remplacé = ton programme est retiré de la mémoire et est écrasé par le programme que tu as donné en paramètre à execl ...

  7. #6
    Zone-x

    Re : langage C unix

    donc il ya aucune solution pour regler ce problème ?

  8. #7
    kwariz

    Re : langage C unix

    Tu as lu mes posts ? Tu as lu mon code et ses (merveilleux ) commentaires ?
    Ce n'est pas un problème, c'est le comportement normal de la famille de fonctions exec ...
    C'est pour ça qu'on fait un fork ... le père crée un fils qui se fera écraser par la commande, le père attend la fin de la commande et hop tout continue normalement ...
    Tu ne m'as toujours pas dit pourquoi tu appelles la commande sleep d'ailleurs ...
    Si tu commençais par nous dire ce que tu essaye de faire ?

  9. #8
    Zone-x

    Re : langage C unix

    mon programme :
    le fils affiche premièrement "je suis le fils" ,et le père après 3 secondes il donne le pid de son fils et affiche "je suis le père" donc mon problème c'est après la commande execl il dois afficher avec des printf quelque chose
    j'ai lu ton programme et merci pour ca ais moi je veux trouver une solution pour executer quelque chose apres execl !
    Dernière modification par Zone-x ; 12/04/2013 à 20h49.

  10. #9
    kwariz

    Re : langage C unix

    ok ... alors utilise la fonction sleep directement pour faire une pause comme je te l'indique dans mon premier post ...
    regarde mon code c'est ainsi que je fais ... et oublie la famille de fonctions exec (elles ne sont à utiliser quand dans des cas particuliers).

  11. #10
    Zone-x

    Re : langage C unix

    sleep c'est la seul commande qu'elle marche sans exel , quand je tape d'autres commandes (date,who ...) directement le programme ne l'acceptent pas il faut que je passe par execl ,comment faire pour regler ca,j'ai entendu dire pour que ca marche apres execl ,il faut que je fais un printf("\n") c'est vrai?

  12. #11
    kwariz

    Re : langage C unix

    C'est un exercice pour programmer un shell ?

  13. #12
    Zone-x

    Re : langage C unix

    ui ce sont exactement des tp en shell processus

  14. #13
    kwariz

    Re : langage C unix

    Alors il faut reprendre les cours un peu et consulter quelques tutoriels.
    L'idée de base va être la suivante :
    1. ton shell lit une commande
    2. il forke, le père attend la fin du processus fils et ne fait de particulier (sauf attendre)
    3. le fils se «sacrifie» et lance un execl pour éxecuter la commande ... attention si execl rend la main c'est que ça c'est mal passé !
    4. le père reçoit le message que le fils c'est bien terminé et recommence, il lit une nouvelle commande

    ça c'est un shell super simplifié.

    Ma question est : pourquoi veux-tu faire quelque chose après le execl dans le fils ???

  15. #14
    Zone-x

    Re : langage C unix

    bon quelque chose pour dire que la commande a été bien executée

  16. #15
    kwariz

    Re : langage C unix

    Dans ce cas tu ne peux pas le faire ainsi car execl ne rend la main au fils que s'il y a eu un problème.
    Donc imagine que tu as une variable commande_ok que tu initialises à 1 avant le fork puis que tu changes à 0 seulement après le execl. Le père attend la fin de son fils avec un waitpid, une fois qu'il a la main soit commande_ok vaut 1 et tout c'et bien passé, soit commande_ok vaut 0 et il y a eu un problème.

  17. #16
    Zone-x

    Smile Re : langage C unix

    ah ok je vois maintennant ,donc dans tous les cas c'et impossible d'executer quelque chose apres un execl
    merci encore pour ton aide

Discussions similaires

  1. le langage C est t il un langage qui a de l'avenir ?
    Par vince6629 dans le forum Programmation et langages, Algorithmique
    Réponses: 13
    Dernier message: 12/11/2014, 12h01
  2. Programmation langage UNIX
    Par inviteb77375f9 dans le forum Logiciel - Software - Open Source
    Réponses: 4
    Dernier message: 01/07/2008, 20h53
  3. Questions sur le langage de commande UNIX
    Par inviteb4fcae87 dans le forum Logiciel - Software - Open Source
    Réponses: 19
    Dernier message: 18/11/2007, 17h53
  4. unix
    Par chwebij dans le forum Logiciel - Software - Open Source
    Réponses: 33
    Dernier message: 09/02/2007, 10h20