Prozess starten und Ausgabe umleiten



  • Hallo,

    unter Linux sind einige Programme mit grafischer Oberfläche ja so implementiert, dass sie Befehle nicht direkt abarbeiten sondern an Kommandozeilenprogramme weiterleiten (zB Mail, Drucken).
    Ich suche nach einer Möglichkeit ein schon vorhandenes (Kommandozeilen-)Programm innerhalb meines Programms mit bestimmten Parametern zu starten. Insbesondere die Standardausgabe ist für mich von Interesse.
    Wie macht man so etwas unter Linux (richtig)? Sind Pipes/Named Pipes der richtige Ansatz? Da große Textmengen anfallen sollte es effizient sein (keine mehrmaliges kopieren zwischen Puffern).

    Viele Grüße,
    Günther



  • starten: fork + exec
    pipe ist ein guter weg
    manche Programme haben auch einen slave mode für solche Anwendungen



  • Hier ein Beispiel mit ls:
    ich hab das Errorhandlig teilweise weggelassen oder nur unvollständig Implementiert (siehe dazu Manpages)

    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    
    int main(void)
    {
    	int pipefd[2];
    	char buffer[512];
    	ssize_t length;
    
    	//pipefd[0]:lesen  [1]:schreiben
    	if(pipe(pipefd) == -1) {
    		perror("pipe()");
    		exit(EXIT_FAILURE);
    	}
    
    	switch(fork())  {
    		case -1:	perror("fork()"); exit(EXIT_FAILURE);
    		case  0:	//Kind
    					close(pipefd[0]);
    					// leite stdout nach pipefd[1] um
    					if(dup2(pipefd[1], STDOUT_FILENO) == -1) {
    						perror("dup2()");
    						exit(EXIT_FAILURE);
    					}
    					// -b ausgabe mit C-escape Sequenzen
    					if(execlp("ls", "ls", "-b", NULL) == -1) {
    						perror("exec");
    						exit(EXIT_FAILURE);
    					}
    		default:	//Elternprozess
    					close(pipefd[1]);
    					length = read(pipefd[0], buffer, sizeof(buffer));
    					// length==0:EOF  length==-1:Error
    					while(length > 0) {
    						write(STDOUT_FILENO, buffer, length);
    						length = read(pipefd[0], buffer, sizeof(buffer));
    					}
    					if(length == -1) {
    						perror("read()");
    						exit(EXIT_FAILURE);
    					}
    					close(pipefd[0]);
    	}
    	return EXIT_SUCCESS;
    }
    

Anmelden zum Antworten