Partage
  • Partager sur Facebook
  • Partager sur Twitter

pipe deviation stdout

Sujet résolu
    10 septembre 2021 à 3:59:37

    Bonjour.

    Je tente de dévier la sortie stdout vers un pipe pour la récupérer dans une string mais il y a un point que je ne comprend pas bien. Pour moi les 2 code ci-dessous devraient avoir le même comportement, et pourtant... non :s

    int main(int argc, char* argv[]){
    
        int bufferStdout;
    
        int deviation[2];
        pipe(deviation);
    
        int id = fork();
        if(id == 0){
            close(deviation[0]);
    
            bufferStdout = dup(STDOUT_FILENO);
            dup2(deviation[1], STDOUT_FILENO);
    
            char *programName = "ls";
            char *args[] = {programName, "-lh", "/home", NULL};
            execvp(programName, args);
    
            dup2(bufferStdout, STDOUT_FILENO);
    
        }else{
            wait(NULL);
    
            close(deviation[1]);
    
            char buf[512];
            read(deviation[0], buf, 511);
    
            close(deviation[0]);
    
    
            printf("This is my pipe diation : \n%s\n\n", buf);
        }
    }
    



    int main(int argc, char* argv[]){
    
        int bufferStdout;
    
        int deviation[2];
        pipe(deviation);
    
        bufferStdout = dup(STDOUT_FILENO);
        dup2(deviation[1], STDOUT_FILENO);
    
        char *programName = "ls";
        char *args[] = {programName, "-lh", "/home", NULL};
        execvp(programName, args);
    
        dup2(bufferStdout, STDOUT_FILENO);
    
        close(deviation[1]);
    
        char buf[512];
        read(deviation[0], buf, 511);
    
        close(deviation[0]);
    
        printf("This is my pipe diation : \n%s\n\n", buf);
    }
    


    EDIT :

    les codes sont "équivalent" avec system a la place de execv. Ce qu'il se passe sur execv est un mystère :s

    int main(int argc, char* argv[]){
    
        int bufferStdout;
    
        int deviation[2];
        pipe(deviation);
    
        bufferStdout = dup(STDOUT_FILENO);
        dup2(deviation[1], STDOUT_FILENO);
    
        system("ls");
    
        dup2(bufferStdout, STDOUT_FILENO);
    
        close(deviation[1]);
    
        char buf[512];
        read(deviation[0], buf, 511);
    
        close(deviation[0]);
    
        printf("This is my pipe diation : \n%s\n\n", buf);
    }
    



    -
    Edité par -Crixus- 10 septembre 2021 à 4:21:40

    • Partager sur Facebook
    • Partager sur Twitter

    "Etre vrai, peu le peuvent."
    Friedrich Nietzsche

      10 septembre 2021 à 8:21:16

      Bonjour,

      Le même comportement ? bah non … si tu prends le temps de lire la doc :

      AME
             execl, execlp, execle, execv, execvp, execvpe - execute a file
      
      SYNOPSIS
      ...
      
      DESCRIPTION
             The  exec() family of functions replaces the current process image with a new process image. 

      En des termes peut être plus simples : le programme courant est remplacé par le nouveau programme … remplacé, il n'existe plus.

      C'est tout l'intérêt de forker … le fils (qui est une copie du père en gros) est remplacé par le nouveau programme et le père attend la complétion.

      C'est aussi ce que fait system, car si on en consulte la doc :

      NAME
             system - execute a shell command
      
      SYNOPSIS
      ...
      
      DESCRIPTION
             The  system()  library function uses fork(2) to create a child process that executes the shell command specified in com‐
             mand using execl(3) as follows:
      
                 execl("/bin/sh", "sh", "-c", command, (char *) NULL);
      
             system() returns after the command has been completed.
      



      Voilà voilà …

      • Partager sur Facebook
      • Partager sur Twitter
        10 septembre 2021 à 13:17:45

        Hello.

        Merci pour la petite précision :) Oui du coup le code 1 et 3 sont bien équivalent... mais je ne comprend pas pour quoi dans le cas 2 cela ne fonctionne pas. Pour quoi sommes nous obligé de passer par un child ? J'ai bien dévier mon stdout dans mon pipe et j'avoue ne vraiment pas voire la necessiter des fork(er) mes processus.

        Est-ce que quand vous dite remplacer vous dites que mon file descriptor (mon pipre) n'éxiste plus ? En fait que l'on a 2 contexte d'execution différent ? C'est un peu flou :s

        -
        Edité par -Crixus- 10 septembre 2021 à 13:23:47

        • Partager sur Facebook
        • Partager sur Twitter

        "Etre vrai, peu le peuvent."
        Friedrich Nietzsche

          10 septembre 2021 à 13:51:30

          La famille de fonctions exec* ne crée pas un nouveau processus, elle remplace le processus en cours par un nouveau en cas de succès. En cas d'échec, le premier processus reste actif et la fonction exec* retourne un code d'erreur. C'est pourquoi ce n'est pas que «ça fonctionne pas» dans le cas 2, mais que le fonctionnement n'est pas celui attendu.

          Pour créer un nouveau processus linux propose la fonction fork qui duplique le processus en cours. Le second processus (le fils) reprend l'exécution après le fork, seule la valeur de retour diffère entre le parent et l'enfant. Sous linux, il y a aussi un appel système clone* qui permet d'avoir la possibilité de choisir finement ce qui est ou non partagé entre le parent et le fils.

          Si on veut lancer une commande en parallèle dans un autre processus alors on n'a pas le choix, on commence par forker le processus en cours et le fils se fait remplacer par la commande souhaitée par un exec*.

          • Partager sur Facebook
          • Partager sur Twitter

          pipe deviation stdout

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          • Editeur
          • Markdown