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

POSIX C Discussion :

[Implémentation] Pipe en C


Sujet :

POSIX C

  1. #1
    Membre émérite Avatar de Tuxico
    Profil pro
    Étudiant
    Inscrit en
    Août 2003
    Messages
    662
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2003
    Messages : 662
    Par défaut [Implémentation] Pipe en C
    Bonjour à tous,

    voilà je m'entraine sur les fonctions dup2,pipe,read,...et je suis un peu perdu malgré les quelques tutos trouvés sur le net .

    Donc mon but est de ré-implémenter le pipe unix càd : ./pipe_c "more test.c" "grep int"

    affichera les lignes contenant int dans test.c

    Je dois donc utiliser un pipe et rediriger la sortie standard de argv[1] vers l'entrée standard de argv[2] en utilisant dup2 mais bon comme je l'ai dis ci dessus ...je suis un peu à la masse :s
    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
    39
    40
    41
    42
    43
    44
    45
    46
     
    /***************************************************************************
     *            pipe_c.c
     *
     *  Sat Nov 11 11:23:52 2006
     *  2006  Tuxico
     ****************************************************************************/
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
     
    int main(int argc, char *argv[])
    {
      int pid;
      int fdpipe[2];
     
      if ( pipe(fdpipe) == -1 )
      {
        perror("pipe");
        exit(-1);
      }
      switch(pid = fork()) {
          case -1:
              perror("fork");
              exit(-1);       
          case 0:
              /* cette portion de code est exécutée par le fils */
              /* lorsque le processus écrira sur l'entrée standard (1) il le fera en fait dans le pipe fdpipe[1]) */
              dup2(fdpipe[1], 1);
              close(fdpipe[0]);
              close(fdpipe[1]);
              execlp(argv[1], argv[1],NULL);
              /* pas besoin de break, ce code n'existe déjà plus à l'exécution */
          default :
              /* cette portion de code est exécutée par le père */    
       	   dup2(fdpipe[1], 0);
              close(fdpipe[0]);
              close(fdpipe[1]);
              execlp(argv[2],argv[2], NULL);
      }
     
     
    return(0);
    }
    mais je n'obtiens pas le résultat escompté...

    Dois-je utiliser read pour récupérer fdpipe[1] comme entrée pour argv[2]?

    suis-je complètement à coté de la plaque?

    merci de votre aide...

  2. #2
    Membre émérite
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Par défaut
    Qu'as-tu comme comportement ?

    Sinon quelques remarques:
    - si tu ferme tous les File Descriptors, je ne vois pas trop comment ca peut marcher
    - le pere doit utiliser fdpipe[0], pas fdpipe[1]
    - execlp() est mal utilisé (le premier argument doit etre un executable, pas une commande ("more test.c")

  3. #3
    Membre émérite Avatar de Tuxico
    Profil pro
    Étudiant
    Inscrit en
    Août 2003
    Messages
    662
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2003
    Messages : 662
    Par défaut
    bon apres une heure j'ai réussi à faire ceci :

    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
    39
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <wait.h>
     
    int main(int argc, char *argv[])
    {
        int fds[2];
        pipe(fds);
        if (fork() == 0) {
            close(fds[0]);                
            dup2(fds[1], STDOUT_FILENO);  
    		close(fds[1]);
     
            char *const args[] = { argv[1], NULL };
            execv(args[0], args);
            _exit(EXIT_FAILURE);
        }
     
        if (fork() == 0) {
            close(fds[1]);               
            dup2(fds[0], STDIN_FILENO); 
    	close(fds[0]);
     
            char *const args[] = { argv[2], NULL };
            execv(args[0], args);
            _exit(EXIT_FAILURE);
        }
     
        close(fds[0]);
        close(fds[1]);
     
        wait(NULL);
        wait(NULL);
     
        return 0;
    }

    problème :

    quand je définis directement la commande dans args[], cela fonctionne mais si je fais référence à argv, non .

    donc quand je fais :

    char *const args[] = { "/bin/ls", NULL }; pour le premier et

    char *const args[] = { "/bin/grep","test.c", NULL }; pour le deuxième

    cela fonctionne

    mais avec argv[1] et argv[2] comme dans mon code cela ne fonctionne pas, why?

  4. #4
    Membre émérite
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Par défaut
    Attention, argv[2] ne va contenir que "grep test.c" !
    Il faut que tu split tes deux chaines "more test.c" (de ton premier exemple) en "more", "test.c" !

  5. #5
    Membre émérite Avatar de Tuxico
    Profil pro
    Étudiant
    Inscrit en
    Août 2003
    Messages
    662
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2003
    Messages : 662
    Par défaut
    t'entends quoi par "splitter", j'interprete ca comment?

    j'ai remplacé ceci :

    char *const args[] = { argv[2], NULL };

    par :

    char *const args[] = { argv[2], argv[3], NULL };


    mais bon je suis un peu a la masse la :s

  6. #6
    Membre Expert
    Avatar de hiko-seijuro
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 011
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 011
    Par défaut
    bah faudrait que tu te geres des options :

    par exemple la ligne suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    .\pipe -in /bin/ls -out /bin/grep pipe.c
    il suffit juste de parser la ligne pour obtenir tes arguments

    Ce que tu fias toi est un cas particulier

  7. #7
    Membre émérite Avatar de Tuxico
    Profil pro
    Étudiant
    Inscrit en
    Août 2003
    Messages
    662
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2003
    Messages : 662
    Par défaut
    bon j'ai plus ou moins compris et j'ai donc essayé la concatenation des arguments mais nada ca ne marche toujours pas :/

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <wait.h>
    #include <string.h>
     
    int main(int argc, char *argv[])
    {
     
        int fds[2];
        char *commande;
     
        pipe(fds);
        if (fork() == 0) {
            close(fds[0]);                
            dup2(fds[1], STDOUT_FILENO);  
    		close(fds[1]);
     
            if(argc = 5){
    	      commande = strcat(argv[1]," ");
    	      commande = strcat(commande,argv[2]);
    	      commande = strcat("/bin/",commande);
                  char *const args[] = { commande, NULL };
                  execv(args[0], args);
            }
    	    else{
    	      commande = strcat("/bin/",argv[1]);
    	      char *const args[] = { commande, NULL };
    	      execv(args[0], args);
            }
     
            _exit(EXIT_FAILURE);
        }
     
        if (fork() == 0) {
            close(fds[1]);      
            dup2(fds[0], STDIN_FILENO);
    	    close(fds[0]);               
     
            if(argc = 5){
    	      commande = strcat(argv[3]," ");
    	      commande = strcat(commande,argv[4]);
                  commande = strcat("/bin/",commande);
                  char *const args[] = { commande, NULL };
                  execv(args[0], args);
    	    }
    	    else{
     	      commande = strcat("/bin/",argv[3]);
    	      char *const args[] = { commande, NULL };
    	      execv(args[0], args);
    	    }
     
            _exit(EXIT_FAILURE);
        }
     
        close(fds[0]);
        close(fds[1]);
     
        wait(NULL);
        wait(NULL);
     
        return 0;
    }
    à mon avis, je me suis enmelé les pinceaux dans ma concaténation de chaine ou dans mon algo tout simplement?

    merci

    Edit: aucune erreur a l exécution mais rien ne s'affiche

  8. #8
    Membre émérite Avatar de Tuxico
    Profil pro
    Étudiant
    Inscrit en
    Août 2003
    Messages
    662
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2003
    Messages : 662
    Par défaut
    problème réglé

    j'ai utilisé system(); plutôt qu'execv et donc cela donne ceci si cela interesse des gens :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <wait.h>
    #include <string.h>
     
     
    int main(int argc, char *argv[])
    {
    	int fds[2];
    	pipe(fds);
     
        if (fork() == 0) {
            close(fds[0]);                
            dup2(fds[1], STDOUT_FILENO);  
    	close(fds[1]);
    	system(argv[1]);
            _exit(EXIT_FAILURE);
        }
     
        if (fork() == 0) {
            close(fds[1]);               
            dup2(fds[0], STDIN_FILENO); 
            close(fds[0]);
            system(argv[2]);
            _exit(EXIT_FAILURE);
        }
        close(fds[0]);
        close(fds[1]);
     
        wait(NULL);
        wait(NULL);
     
        return 0;
    }
    exemple: ./pipe_c "ls -la" "grep test.c"

  9. #9
    Candidat au Club
    Inscrit en
    Mars 2011
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 3
    Par défaut une remarque !
    Je reste circonspect sur le sens de ce programme.
    Tu fais un fork pour dupliquer ton programme et tu restes dans le même procesus (le fils car fork == 0).
    Je pense que ton programme marche mais ne fait pas ce que tu penses...
    A méditer !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [C/S] Boken Pipe
    Par Gogoye dans le forum POSIX
    Réponses: 4
    Dernier message: 23/10/2003, 10h48
  2. Réponses: 3
    Dernier message: 21/08/2003, 14h47
  3. Problème : bloquage d'un pipe
    Par Nicaisse dans le forum POSIX
    Réponses: 10
    Dernier message: 24/07/2003, 11h06
  4. Réponses: 2
    Dernier message: 06/07/2002, 12h36
  5. Implémentation des fonctions mathématiques
    Par mat.M dans le forum Mathématiques
    Réponses: 9
    Dernier message: 17/06/2002, 16h19

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