2016-06-17 12 views
2

Ich versuche, diese Übung zu lösen: "machen Sie ein Programm, das als Argument 2 andere Programme erhält (zB:" flow ls wc "). Es sollte beide Programme laufen, mit der Ausgabe der 1. Programm als die Eingabe des 2. und messen Sie die Menge der gesendeten Daten. Drucken Sie diesen Betrag jede Sekunde auf Ihrem Stand. "Stuck in einer Weile Schleife nach Gabelung

Ich habe dies:

int fluxo = 0; 

void fa(){ 
    printf("\nFlux: %d\n", fluxo); 
    fluxo = 0; 
    alarm(1); 
} 


int main(int argc,char **argv){ 
    int pd[2]; 
    pid_t p; 
    pipe(pd); 
    char *buf; 
    signal(SIGALRM,fa); 
    alarm(1); 

    if((p=fork())==0){  
     close(pd[0]); 
     dup2(pd[1],1); 
     close(pd[1]); 
     execlp(argv[1],argv[1],NULL); 
     exit(EXIT_FAILURE); 
    } 
    else{ 
     wait(NULL); 
     while(read(pd[0],&buf,1)==1) 
      fluxo++; 
     close(pd[1]); 
     dup2(pd[0],0); 
     close(pd[0]); 
     execlp(argv[2],argv[2],NULL); 
     exit(EXIT_FAILURE); 
    } 
    exit(EXIT_SUCCESS); 
} 

Ich verwende die while-Schleife um die Datenmenge zu messen. Allerdings bleibe ich dabei stecken, selbst nachdem das execlp im Child-Prozess seine Daten gesendet hat und daher das 2. Programm nicht ausführt. Es steckt die while-Schleife fest, selbst nachdem ich alle Daten in der Pipe gelesen habe. Warum?

+0

'char * buf; while (lesen (pd [0], & buf, 1) == 1) 'Nicht schlecht, aber riecht. Meinst du "char buf"? – MikeCAT

+0

Kann nicht lesen, wenn das "buf" ein char ist. Man liest liest (int fildes, void * buf, size_t nbyte); – ohiohai

+1

@MikeCAT Das ist jenseits eines Code-Geruchs, es ist sicherlich schlecht in meinem Buch. :) – unwind

Antwort

1

Zuerst deklarieren Sie char* buf, aber Ihr Zeiger ist nicht zugeordnet. Ich denke, Sie wollten char buf verwenden (da Sie &buf im gelesenen verwenden).

Ihre While-Schleife ist nicht verklemmt, der Anruf an read ist. In der Tat hat Ihr Elternprozess immer noch pd[1] Deskriptor geöffnet, wenn Sie read Funktion aufrufen. Wenn der Puffer leer ist, wartet er.

Sie sollten diese ersetzen:

else{ 
     wait(NULL); 
     while(read(pd[0],&buf,1)==1) 
      fluxo++; 
     close(pd[1]); 
     dup2(pd[0],0); 
     close(pd[0]); 
     execlp(argv[2],argv[2],NULL); 
     exit(EXIT_FAILURE); 
    } 

durch diese:

else{ 
     close(pd[1]); 
     wait(NULL); 
     while(read(pd[0],&buf,1)==1) 
      fluxo++; 
     dup2(pd[0],0); 
     close(pd[0]); 
     execlp(argv[2],argv[2],NULL); 
     exit(EXIT_FAILURE); 
    } 

EDIT: Hinweis: Lesen Byte pro Byte nicht effizient ist, werden Sie eine bessere Leistung mit einer größeren bekommen Puffer. Zum Beispiel: char buf[1024]

und Ihre Schleife:

for(;;){ 
    ssize_t rd = read(pd[0], buf, 1024); 
    if(rd==-1){ 
    perror("Reading"); 
    exit(EXIT_FAILURE); 
    } 
    if(rd==0) break; 
    fluxo+=rd; 
} 
+0

char buf ist in der Tat, was ich meinte. kopierte einen Teil eines Codes aus einem anderen Programm, in dem ich eine Zeichenfolge verwendete. mein Fehler. Sie haben Recht, wenn ich den Deskriptor nicht schließe, würde ich feststecken. Allerdings bekomme ich jetzt ein anderes Problem. Die Datenmenge ist korrekt, aber "wc" gibt jetzt 0 0 0 zurück. Ich nehme an, es liegt daran, dass ich die Daten aus dem Deskriptor genommen habe ...Ich kann das wahrscheinlich nicht lösen, ohne eine andere Gabel und Rohrleitung zu verwenden. – ohiohai

+0

Ja, durch das Lesen der Daten haben Sie es "herausgenommen". Was Sie tun können, ist es, es aus dem Puffer zu lesen und es dann in eine andere Pipe zu schreiben, ohne eine weitere Gabelung zu benötigen. Dieses andere Rohr wird das Rohr zu dup sein. Der einfachste Weg, dies zu tun, ist die Verwendung der for (;;) Ich schrieb über – Omar

+0

über Ihre letzte Bearbeitung, der Grund, warum ich kein Array verwendet, war, weil ich nicht sicher bin, wenn die Menge der gelesenen Daten dann größer wäre mein Array und das könnte mir einige andere seltsame Probleme geben. – ohiohai