Pipe simulieren



  • Hallo ich würde gerne ein Prog schreiben was die linux pipe simuliert:
    ./prog who sort .... ist wie who | sort

    So würde das gerne mit 2 child prozessen machen. Also der erste den ersten Befehl und der 2te mit dem stdin vom ersten.

    Wie kann ich das realisieren?

    ich kann den ersten child den ersten befehl ausführen lassen und dann den stout abfangen mit ner pipe ins 2te child geben und den 2ten befehl mit dem child ausführen lassen.

    Aber ich kann das nicht wirklich umsetzen.

    LG



  • Orientiere dich an den Vorbildern für 'pipe' - das waren Dateien. In ANSI-C hast du mit Dateien allerdings das Problem der Zugriffskonflikte (Synchronisierierung) selbst zu regeln. Viel Spass! :p



  • Allein mit Standard-C geht das nicht.

    Unter Unix gibt es dazu Systemaufrufe wie pipe(), fork() und exec().



  • Minimalbeispiel:

    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    #include <stdio.h>
    
    int main() {
      pid_t pid, pid2;
      int pipes[2];
    
      pipe(pipes);
    
      pid = fork();
    
      if(pid == 0) {
        close(STDOUT_FILENO);
        dup(pipes[1]);
        close(pipes[0]);
    
        execlp("who", "who", NULL);
      }
    
      pid2 = fork();
    
      if(pid2 == 0)  {
        close(STDIN_FILENO);
        dup(pipes[0]);
        close(pipes[1]);
    
        execlp("sort", "sort", NULL);
      }
    
      close(pipes[0]);
      close(pipes[1]);
    
      wait(NULL);
      wait(NULL);
    
      return 0;
    }
    

    Fehlerbehandlung sei als Übungsaufgabe dem Leser überlassen 😉

    Das Prinzip ist eigentlich ziemlich simpel - der Vaterprozess öffnet eine Pipe, startet zwei Kindprozesse, die jeweils stdout bzw. stdin durch die Enden der Pipe ersetzen und das gewünschte Programm starten. Der Vaterprozess wartet danach nur noch auf seine Kindprozesse und sammelt sie ein.

    Womöglich könnte man sich auch einen der beiden Kindprozesse sparen, den Vaterprozess eines der beiden Programme ausführen lassen und sich nachher darauf verlassen, dass init die Leichen einsammelt, aber so etwas ist immer eine etwas haarige Angelegenheit; wenn man dabei Mist baut, kann man sich Zombies einhandeln.



  • hmm ... ok so in die Richtung hab ich eh gearbeitet.

    Nur wieso hat dann execlp den stdout vom anderen sohn?

    LG



  • Die beiden Kindprozesse ersetzen vor dem Aufruf von execlp stdin bzw. stdout durch die Enden der vom Vaterprozess geöffneten Pipe.

    Der eine Kindprozess ersetzt stdout durch das eine Ende der Pipe, der andere stdin durch das andere. Wenn der erste jetzt in sein stdout schreibt, geht das in die Pipe, und der andere kann es aus dem anderen Ende der Pipe, welches an seinem stdin hängt, lesen.

    Ich weiß wirklich nicht, wie ich es einfacher ausdrücken könnte.


Anmelden zum Antworten