2013-07-13 8 views
5

Ich versuche, eine multiple Rohr für meine Schale in C zu implementieren.Codieren mehrere Rohre in C

Alles, was ich habe, ist eine Rohrfunktion, die ein Rohr | b aber nicht ein | b | c.

int c[2]; 
int returnv; 
pid_t id; 

pipe(c); 
pid = fork()) == 0 
if (pid) 
{ 
    dup2(c[1], 0); 
    close(p[1]); 
    close(p[1]); 
    execvp(array(0), array); 
} 

if ((pid = fork()) == 0) 
{ 
    dup2(p[0], 1); 
    close(p(0)); 
    close(p[0]); 
    returnv = execvp(array[0], array); 
} 

close(p[1]); 
wait(NULL); 
wait(NULL); 
wait(NULL); 
return returnv; 

Und dies ist eine zweite Version:

int i = 0; 

while (i < x) 

{ 
pipe(c); 
if ((pid = fork()) == 0) 
{ 
    dup2(t[i], 1); 
    if (i < 2) 
     dup2(p[0], 1); 
    close(p[1]); 
r= execvp(cmd[i][0], cmd[i]); 
} 
    wait(NULL); 
    close(p[0]); 
    i += 1; 
    t[i] = p[1]; 

Wie kann ich das wenig etwas hinzufügen, die diesen Code machen mehr Rohr bitte managt? Vielen Dank im Voraus!

+0

Eigentlich rufen Sie fork() zweimal, während Sie nur einmal brauchen. Dies, weil fork() zweimal zurückgibt: 0 für den Sohnprozess und> 1 für den Vaterprozess (normalerweise ist es die PID des Sohns). Ich glaube nicht, dass Sie all diesen Code brauchen, um das zu tun, was Sie brauchen. – none

+0

Ich habe so viel Zeit auf diesem einen verbracht, das ist das einzige, was funktioniert ^^ Ich denke, es gibt nur einen Aufruf an execvp für Multi-Pip benötigt, aber ich kann es nicht funktionieren. :( – user2145240

+0

Entfernen Sie nicht den Code aus dem Post es ungültig macht die Antworten – FDinoff

Antwort

8

Edit: nach Ihren Kommentar

Um Multiples Rohre müssen Sie führen alle irgendwo Ihre Befehle speichern. Deshalb habe ich einen Tab der Struktur verwendet.

prüfen diese neue Version vielleicht einfacher

So müssen Sie zunächst eine Registerkarte oder etwas zu verstehen, alle Befehle speichern:

int main() 
{ 
    char *ls[] = {"ls", NULL}; 
    char *grep[] = {"grep", "pipe", NULL}; 
    char *wc[] = {"wc", NULL}; 
    char **cmd[] = {ls, grep, wc, NULL}; 

    loop_pipe(cmd); 
    return (0); 
} 

Dann ist die Funktion, die durch die Lasche ausgeführt wird, und starten Sie alles

void loop_pipe(char ***cmd) 
{ 
    int p[2]; 
    pid_t pid; 
    int fd_in = 0; 

    while (*cmd != NULL) 
    { 
     pipe(p); 
     if ((pid = fork()) == -1) 
     { 
      exit(EXIT_FAILURE); 
     } 
     else if (pid == 0) 
     { 
      dup2(fd_in, 0); //change the input according to the old one 
      if (*(cmd + 1) != NULL) 
      dup2(p[1], 1); 
      close(p[0]); 
      execvp((*cmd)[0], *cmd); 
      exit(EXIT_FAILURE); 
     } 
     else 
     { 
      wait(NULL); 
      close(p[1]); 
      fd_in = p[0]; //save the input for the next command 
      cmd++; 
     } 
    } 
} 
+2

@ user2145240 Ich habe meine Antwort geändert, die alte war ein bisschen chaotisch, weil ich es für viele andere Dinge verwendet habe;) – Alexis

+1

@ user2145240 können Sie zeigen, wie Sie nennen Sie es, weil ich es gut auf meinem Computer funktioniert, und auch auf ideone http://ideone.com/80e3nd – Alexis

+1

@ user2145240 Wenige Dinge zu überprüfen: printf ("9 - On rentre ici?"); Vergessen Sie bitte nicht das \ n am Ende, Fügen Sie einen Fehler unter der Exec, um sicher zu sein, dass Sie nicht etwas in der env – Alexis

0

Ich werde eine funktionierende Version des Zwei-Rohr-Modells und einen Hinweis für das Drei-Rohr-Modell geben. Probieren Sie es aus und sehen Sie, ob es funktioniert. Hinweis: Wenn Sie die richtigen Header-Dateien nicht enthalten, wird dup2() ein Alptraum sein.

#include <stdio.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/stat.h> 

int p[2]; 
int pid; 
int r; 

main() 
{ 
    char *ls_args[] = {"ls", NULL}; 
    char *grep_args[] = {"grep", "pipe", NULL}; 

    pipe(p); 

    pid = fork(); 
    if (pid != 0) { 
      // Parent: Output is to child via pipe[1] 

      // Change stdout to pipe[1] 
      dup2(p[1], 1); 
      close(p[0]); 

      r = execvp("ls", ls_args); 
    } else { 
      // Child: Input is from pipe[0] and output is via stdout. 
      dup2(p[0], 0); 
      close(p[1]); 

      r = execvp("grep", grep_args); 
      close(p[0]); 
    } 

    return r; 
} 

Für a | b | c ist der Hinweis zwei Rohre d.h. p1 verwenden [2] und p2 [2]. Probieren Sie es aus und lassen Sie uns wissen, wie es funktioniert.