Pipe



  • Hallo zusammen,

    ich versuche unter Linux ein C Programm zu schreiben, das ein externes Programm startet und alles, was es über die Standardeingabe bekommt an dieses externe Programm weiterzuleiten. Das Programm soll später noch mehr können (daher kommt es z.B. auch nicht in Frage popen zu benutzen). Soweit mein (vereinfachter) Code:

    /********************
           pipe.cpp
    ********************/
    #include <unistd.h>
    #include <string.h>
    #include <signal.h>
    
    #include <stdio.h>
    
    int main() {
    	int pfd[2]; // lesen aus pfd[0], schreiben in pfd[1]
    	pipe(pfd);
    	int pid = fork();
    
    	if ( pid == -1) { 
    		printf("ERROR: Couldn't fork\n");
    		return -1;
    	}
    	if (pid == 0) { /* KINDPROZESS */
    		close(pfd[1]); // Schreibende der Pipe schliessen
    		if (pfd[0] != STDIN_FILENO) { // Leseende auf Standardeingabe umbiegen
    			if (dup2(pfd[0], STDIN_FILENO) != STDIN_FILENO)
    				printf("dup2 error to stdin");
    			close(pfd[0]);
    		}
     		execl("./stdinToFile", "./stdinToFile", 0); // Prozess stdinToFile ausführen
     		printf("Oops\n"); // hier sollten wir nicht hinkommen
    	} else { /* ELTERNPROZESS */
    		close(pfd[0]); // Leseende schließen
    	}
    
    	return 0;
    }
    

    stdinToFile ist ein Programm, dass alles von der Standardeingabe in eine Datei schreibt, bis "quit" eingegeben wird. Ich hab's mit

    echo "1 2 3 quit" | ./stdinToFile
    

    getestet und im Logfile steht dann "1 2 3".

    Wenn ich aber

    echo "1 2 3 quit" | ./pipe
    

    aufrufe, bekomme ich nur "bash: echo: write error: Datenübergabe unterbrochen (broken pipe)".

    Wißt ihr, was ich da mit den pipe/dup Befehlen vergeigt habe? Wär echt toll, ich mach schon ne ganze Weile an dem Mist rum 😞

    * JanaS *



  • Wenn ich vor das close in Zeile 29 noch ein wait(&status) reinmache, bekomme ich zwar nicht mehr den Fehler, aber die Logdatei bleibt leer (und der Aufruf terminiert auch nicht). Buh!



  • Ich glaube, Du hast den Sinn von pipe() nicht ganz verstanden.
    Du erzeugst in Zeile 12 eine Pipe und benutzt diese als Standardeingabe in dem Kind-Prozess. Jedoch schreibst Du ja nichts in das andere "Ende" der Pipe (pfd[1]) hinein. Was soll Deiner Meinung nach dann aus pfd[0] herauskommen???
    (Im Übrigen sagt Dir das ja auch die Fehlermeldung "broken pipe".)

    Wenn Dein Programm das externe Programm "stdinToFile" aufrufen soll und die Standardeingabe an dieses weiterleiten soll, benötigst Du keine Pipe! Der execl()-Aufruf allein würde es auch tun, da mit diesem Aufruf automatisch die Standardeingabe an das aufgerufene Programm geht!


Anmelden zum Antworten