Frage zu pipes umlenken



  • Hallo,

    ich bin anfänger was pipes betrifft und habe eine Frage zum untenstehenden bsp: unten ist ein kleines bsp, wo der kindprzess die daten vom elternprozess liest, aber ich versteh nicht ganz wie die umleitung von pipes auf stdin bzw. stdout funktioniert bzw. wie das visuell dargestellt wird. im child prozess wird das "Lesen der Pipe" umgelenkt auf stdin und ich kann dann mittels "read" und "printf" die daten in der file ausgeben, aber wieso funktioniert das nicht wenn ich das ganze auf stdout umlenke? also anstatt STDIN_FILENO einfach STDOUT_FILENO (siehe markierter code).

    meine 2. frage betrifft execlp: wenn ich im kindprozess zB execlp(less,less,NULL) aufrufe (nach dup2 bzw. umlenken), von wo holt sich dann dieses programm "less" die daten?

    bin da ein wenig auf der leitung und wäre froh, wenn mir das jmd erklären könnte!

    lg + danke

    [cpp]#include <unistd.h>
    #include <sys/wait.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <limits.h>
    #define EXIT(s) {fprintf(stderr, "%s",s); exit(EXIT_FAILURE);}

    // Wenn nicht ausreichend dimensioniert =>
    // vergrößern oder ggf. dynamisch machen
    #define BUF PIPE_BUF * 8

    enum{ ERROR = -1, SUCCESS };

    int main (int argc, char **argv) {
    int fd[2];
    pid_t pid;
    FILE *pipe_writer, *file;
    char puffer[PIPE_BUF];

    if (argc != 2) {
    fprintf(stderr, "Usage: %s DateiZumLesen\n",*argv);
    exit(EXIT_FAILURE);
    }
    if ((file = fopen (argv[1], "r")) == NULL)
    EXIT ("Fehler bei fopen ...\n");
    if (pipe (fd) == ERROR)
    EXIT ("Fehler bei pipe ...\n");
    if ((pid = fork ()) == ERROR)
    EXIT ("Fehler bei fork ...\n");
    if (pid > 0) { /*Elternprozess */
    close (fd[0]); /*Wir schließen die Leseseite */
    if ((pipe_writer = fdopen (fd[1], "w")) == NULL)
    EXIT ("Fehler bei fdopen ...\n");
    fread (&puffer, PIPE_BUF, 1, file);
    fputs (puffer, pipe_writer); /*Wir schreiben in die Pipe */
    fclose (pipe_writer);
    /*Mit dem schließen der Schreibseite */
    /*teilen wir dem Kindprozess das Ende */
    /*des Schreiben in die Pipe mit */
    if (waitpid (pid, NULL, 0) == ERROR)
    EXIT ("Fehler bei waitpid ... \n");
    exit (EXIT_SUCCESS);
    }
    else { /*Kindprozess ließt aus der pipe mit less */
    char buf[128];

    close (fd[1]);

    /*duplizieren Standardeingabe */
    if (dup2 (fd[0], [c]STDIN_FILENO) != STDIN_FILENO[/c])
    EXIT ("Fehler bei dup2 ...\n");
    close (fd[0]); /*Wird nicht mehr benötigt */

    read (0, buf , 15);
    fprintf(stdout,"%s",buf);

    }
    return EXIT_SUCCESS;
    }[/cpp]



  • file descriptoren referenzieren eine datenquelle oder -ziel. es ist möglich, dass zwei file descriptoren auf die gleiche datenquelle zeigen. dub2 macht zwei sachen: zuerst schließt es die datenquelle, auf die der file descriptor im zweiten parameter zeigt. dann wird der zweite file descriptor so umgebogen, dass er jetzt auf die gleiche datenquelle zeigt, wie der file descriptor im ersten parameter von dup2.

    eine pipe hat zwei file descriptoren: einen zum lesen, einen zum schreiben. man kann in den lesbaren aber nicht schreiben und vom schreibbaren nichts lesen. was in den schreibbaren geschrieben wird, kann vom lesbaren gelesen werden. du wirst also nicht nur stdin durch stdout ersetzen müssen, sondern auch die beiden file descriptoren der pipe tauschen.

    less holt sich die daten immer von stdin oder einer datei, wenn eine angegeben wurde. da du bei deinem aufruf aber keine datei angegeben hast, wird less auf stdin warten und die dort hereinkommenden daten darstellen.


Anmelden zum Antworten