IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

fork() et exec


Sujet :

Linux

  1. #1
    Membre habitué Avatar de Hakuna_Maths_ata
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 27
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 10
    Par défaut fork() et exec
    Bonsoir,


    voici l'énoncé de l'exercice sur lequel je travaille :

    Écrivez un programme C qui, par le biais de créations de processus et de recouvrements, exécute la suite de commandes who ; pwd ; ls -l

    et voici ma réponse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    int main(int argc, char **argv[])
    {
        int i;
     
        printf("Affiche--");
        char *myargs[]={"pwd","who","ls -l"};
        char *myargs2[]= {NULL};
        for(i=0; i<4; i++)
        {
            pid_t p=fork(); //creation de fils
            if (p<0)
            {
                perror("fork");
                exit(1);
            }
            else if (p==0)  //dans le fils
            {
                printf("%s",myargs[i]);
                execv(myargs[i],myargs2);
                perror("erreur exec");
                exit(1);
            }
        }
    }
    et voici ce qu'affiche le terminal :

    erreur exec: No such file or directory
    Affiche--pwdAffiche--erreur exec: No such file or directory
    Affiche--ls -lerreur exec: No such file or directory
    Affiche--who
    Mes questions sont alors :

    • pourquoi "Affiche--" apparait ? N'est-il pas sensé s'afficher qu'une fois (au début) et dans le père ?
    • pourquoi les commandes sont executées dans le désordre ?
    • Est-ce correct d'appeler en deuxième argument de execv, un tableau contenant NULL ? Car les commandes que l'on doit executer n'ont pas d'options...




    Merci d'avance !

  2. #2
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    difficile de répondre avec précision, tes balises [CODE][/CODE] sont un peu aléatoires

    pour le moins la structure globale du programme n'est pas la bonne, il s'agit de chainer les commandes (les point-virgules cmd1; cmd2; cmd3)
    le principe est donc le suivant schématiquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    debut du programme
          |
         fork
          |  \___ processus fils
          |              |
          |           exec who
          |
         fork
          |  \___ processus fils
          |              |
          |           exec pwd
          |
         fork
          |  \___ processus fils
          |              |
          |           exec ls -l
          v
    quant à l'invocation de execv() elle n'est effectivement pas bonne du coup, voir la manpage concernée

  3. #3
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    je reviens sur ta question ayant eu un peu plus de temps pour regarder de plus près

    • int main(int argc, char **argv[]), c'est soit **argv soit *argv[]
    • l'invocation via execv() doit ressembler à quelque chose comme ça : execv("/bin/ls", {"ls", NULL})
    • en général quand on fork un processus fils, on a coutume d'attendre qu'il termine correctement dans le processus père avec wait() ou waitpid()


    je te propose le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #include <stdio.h>                                                                                                                                                                                                                           
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
     
    int main(int argc, char **argv) {
       int i, j, status;
       pid_t pid;
       char *my_cmd[3] = { "/bin/pwd", "/usr/bin/who", "/bin/ls" };
       char *my_args[3][3] = { { "pwd", NULL }, { "who", NULL }, { "ls", "-l", NULL } };
     
       for (i = 0; i < 3; i++) {
          /* affichage pour faire joli */
          printf ("\n%d: cmd=\"%s\"\t", i, my_cmd[i]);
          j = 0;
          do {
             printf ("argv[%d]=\"%s\"\t", j, my_args[i][j]);
          } while (my_args[i][++j]);
          printf ("\n");
     
          /* le lancement des process a proprement parler */
          pid = fork();
     
          if (pid < 0) {
             perror("fork()");
             exit(-1);
          }
     
          if (pid == 0) { /* child */
             execv(my_cmd[i], my_args[i]);
             exit(-1);
          } else { /* parent */
             waitpid(pid, &status, 0);
          }
       }
       return 0;
    }

  4. #4
    Membre habitué Avatar de Hakuna_Maths_ata
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 27
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 10
    Par défaut
    C'est plus clair maintant... merci !

    Pardon pour le **argv[]...

    J'aurais encore une question : pourquoi n'écris-tu pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if (p==0){
    .
    .
    }
    else  if (p==0){
    .
    .
    }
    etc...
    ?

  5. #5
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    Citation Envoyé par Hakuna_Maths_ata Voir le message
    J'aurais encore une question : pourquoi n'écris-tu pas (...) ?
    j'imagine que tu parles de la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (pid < 0) {
       exit
    } else /* tu parles de ce else là qui est manquant je présume ? */
    if (pid == 0) { ... }
    else { ... }
    c'est simple, la première condition mène soit à la suite du programme soit à la fin du programme (exit), on a pas besoin de else, il est implicite et on ne peut pas se tromper

    si le pid est inférieur à zéro alors on quitte le programme, à l'inverse, si le pid n'est pas inférieur à zéro ça veut dire qu'on n'exécute pas le exit(), et donc tout ce qui s'exécute ensuite est nécessairement dans un else tacite

    du coup en faisant sauter un else on gagne aussi un niveau d'indentation et par là on gagne en lisibilité

    à titre perso je me le représente comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (condition) {
       action
    } else if (condidition) {
              action
           } else if (condition) {
                     action
                  }

  6. #6
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Par défaut
    Citation Envoyé par Hakuna_Maths_ata Voir le message
    pourquoi "Affiche--" apparait ? N'est-il pas sensé s'afficher qu'une fois (au début) et dans le père ?
    "Affiche--" s'affiche plusieurs fois car tu n'a pas vidé le buffer de sortie avant les fork qui se retrouvent donc tous avec "Affiche--" dans stdout.
    Il manque un fflush(stdout) ou un "\n" final.

  7. #7
    Membre habitué Avatar de Hakuna_Maths_ata
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 27
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 10
    Par défaut
    C'est clair maintenant...Merci beaucoup d'avoir pris le temps de me répondre

Discussions similaires

  1. process defunct avec fork et exec
    Par nabbo dans le forum Programmation et administration système
    Réponses: 5
    Dernier message: 13/09/2013, 15h41
  2. fork + exec + mémoire partagée ?
    Par italiasky dans le forum POSIX
    Réponses: 2
    Dernier message: 26/08/2009, 16h18
  3. Débutant sur les fork() et exec()
    Par Sin-an dans le forum Linux
    Réponses: 7
    Dernier message: 20/04/2009, 18h56
  4. Fork, pipe, exec
    Par shepounet dans le forum Linux
    Réponses: 2
    Dernier message: 21/03/2009, 14h08
  5. Exercice en c sur les forks+Pipe+exec
    Par Elendhil dans le forum Linux
    Réponses: 6
    Dernier message: 07/11/2007, 19h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo