2015-08-29 1 views
0

J'écris un programme qui enchaîne simplement 3 programmes, etc. "ls | sort | wc". J'ai regardé à travers les autres messages que j'ai trouvé sur google à propos de plusieurs pipes mais je n'arrive toujours pas à comprendre ce que j'ai fait de mal. Été bloqué sur cela pendant un moment. Je crois que mon programme est logiquement correct, mais pour une raison quelconque, il ne fonctionne pas. Qu'est-ce que je rate?Collé sur l'utilisation de plusieurs tuyaux dans C

pipe(pipe1); 
pipe(pipe2); 

pid = fork(); 
if(pid > 0){ 
    close(pipe2[1]); 
    dup2(pipe2[0], 0); 
    execlp(argv[3], argv[3], NULL); 
} 
else if(pid == 0){ 
    pid2 = fork(); 
    if(pid2 == 0){ 
     close(pipe1[0]); 
     dup2(pipe1[1], 1); 
     execlp(argv[1], argv[1], NULL); 
    } 
    else if(pid2 > 0){ 
     close(pipe1[1]); 
     dup2(pipe1[0], 0); 
     close(pipe2[0]); 
     dup2(pipe2[1], 1); 
     execlp(argv[2], argv[2], NULL); 
    } 
} 
+0

Comment votre look commande? – Downvoter

+0

Je cours de la ligne de commande et je l'ai juste pris 3 arguments, ainsi ce sera ./programname ls sort wc. La sortie ne montre rien, mais ne sort pas, donc je suppose qu'il y a une boucle infinie quelque part parce que j'ai en quelque sorte foiré ma connexion de tuyau? – ryye

Répondre

0

Vous devez bifurquer trois fois dans les cas parents et exécuter vos commandes uniquement dans les cas enfants. Jetez un oeil here

ajusté à votre cas:

#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 

int main(int argc, char **argv) { 

    int pid; 
    int pipe1[2]; 
    int pipe2[2]; 

    // create pipe1 
    if (pipe(pipe1) == -1) { 
    perror("bad pipe1"); 
    exit(1); 
    } 

    // fork (ps aux) 
    if ((pid = fork()) == -1) { 
    perror("bad fork1"); 
    exit(1); 
    } 
    else if (pid == 0) { 
    // stdin --> ps --> pipe1 
    // input from stdin (already done), output to pipe1 
    dup2(pipe1[1], 1); 
    // close fds 
    close(pipe1[0]); 
    close(pipe1[1]); 

    execlp(argv[1], argv[1], NULL); 
    // exec didn't work, exit 
    perror("bad exec ps"); 
    _exit(1); 
    } 
    // parent 

    // create pipe2 
    if (pipe(pipe2) == -1) { 
    perror("bad pipe2"); 
    exit(1); 
    } 

    // fork (grep root) 
    if ((pid = fork()) == -1) { 
    perror("bad fork2"); 
    exit(1); 
    } 
    else if (pid == 0) { 
    // pipe1 --> grep --> pipe2 
    // input from pipe1 
    dup2(pipe1[0], 0); 
    // output to pipe2 
    dup2(pipe2[1], 1); 
    // close fds 
    close(pipe1[0]); 
    close(pipe1[1]); 
    close(pipe2[0]); 
    close(pipe2[1]); 

    execlp(argv[2], argv[2], NULL); 
    // exec didn't work, exit 
    perror("bad exec grep root"); 
    _exit(1); 
    } 
    // parent 

    // close unused fds 
    close(pipe1[0]); 
    close(pipe1[1]); 

    // fork (grep sbin) 
    if ((pid = fork()) == -1) { 
    perror("bad fork3"); 
    exit(1); 
    } 
    else if (pid == 0) { 
    // pipe2 --> grep --> stdout 
    // input from pipe2 
    dup2(pipe2[0], 0); 
    // output to stdout (already done). Close fds 
    close(pipe2[0]); 
    close(pipe2[1]); 

    execlp(argv[3], argv[3], NULL); 
    // exec didn't work, exit 
    perror("bad exec grep sbin"); 
    _exit(1); 
    } 
    // parent 

    return 0; 
} 
+1

Merci, j'ai compris ce qui n'allait pas avec mon code. Je pensais pourquoi forger 3 fois dans le parent serait différent de ce que j'ai fait, et je ne pense pas qu'il y ait une différence. Mais ce que j'ai mal fait, c'est que je n'ai pas fermé pipe1 dans le processus parent comme vous l'avez fait. J'ai ajouté cela et le code fonctionne maintenant. – ryye

+0

oh je n'ai pas remarqué ça. Bon travail ;) – chefarov