Suche pendant zu FILE *popen( *command, *type); *geloest*

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
weedy
Beiträge: 585
Registriert: 02.11.2002 21:47:49
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Suche pendant zu FILE *popen( *command, *type); *geloest*

Beitrag von weedy » 14.10.2004 02:15:25

Hallo,

Mit die Funktion popen kann ich eine Pipe an ein Kommenao hängen (z.B. popen("/bin/ls", "r"); Nun steht aber in der manpage, daß ich als mode ausschliesslich "r" für read und "w" für write eingeben kann und somit entweder nur in die Pipe reinschreiben oder rauslesen kann. Ich hätte aber gerne beides, ich möchte nämlich über die pipe ein Kommando (a) mit Daten füttern und (b) gleichzeitig Daten auslesen. Gibt es da eine einfache Möglichkeit? Ich sehe da bis jetzt nur die Möglichkeit, nach einem fork() im Childprozeß ein execve in diesem durchzuführen; aber wie komme ich da an die Input- und Output-Streams?

Nachtrag: möglicherweise könnte es so gehen, daß ich auf die Filedeskriptoren zugreife in /proc/pid/fd, mit der pid, die ich im Vaterprozeß von fork bekommen habe. aber so richtig gefällt mir das nicht. Na, mal sehen.

weedy.
Zuletzt geändert von weedy am 14.10.2004 21:58:29, insgesamt 1-mal geändert.

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 14.10.2004 15:41:08

Du kannst mittels pipe zwei Pipes erzeugen und im Kindprozess das jeweilige Ende mit Hilfe von dup2 bzw. stdin und stdout legen.

Beispiel ohne Fehlerabfrage etc.:

Code: Alles auswählen

// für dup2,read,write
#include <unistd.h>

// für fwrite
#include <stdio.h>

// für memset
#include <string.h>

// für exit
#include <stdlib.h>

int main(int argc, char** argv)
{

    // Die beiden Pipes. Sie sind danach benannt, wie der Kindprozess
    // sie sieht!
    int input[2], output[2];

    // Der Lesepuffer    
    char buf[2048];

    // Die Kommandozeilenparameter des Kindprozesses. Der erste
    // Parameter muss immer der Name, mit dem das Programm aufgerufen
    // wurde, sein.
    char* child_argv[] = {"sh",NULL};

    // Die beiden Pipes erzeugen.
    pipe(input);
    pipe(output);

    if (!fork()) {
        // der Kindprozess
        // Eingabepart der 1. Pipe mit stdin verbinden
        dup2(input[0], 0);  // stdin ist immer 0

        // Ausgabepart der 2. Pipe mit stdout verbinden
        dup2(output[1], 1); // stdout ist immer 1

        // Und ausführen
        execv("/bin/sh",child_argv);

        // Dies wird normalerweise nicht erreicht, aber sicher ist sicher
        exit(0);
    }

    memset(buf, 0, 2048);
    write(input[1], "ls\n", 3);
    read(output[0], &buf, 2048); printf("%s", buf);

    memset(buf, 0, 2048);
    write(input[1], "echo Hallo\n", 11);
    read(output[0], &buf, 2048); printf("%s", buf);

    close(input[1]);
    close(output[0]);
}
Mehr Hilfe mit "man 2 dup2", "man 2 pipe" etc.

HTH

Benutzeravatar
weedy
Beiträge: 585
Registriert: 02.11.2002 21:47:49
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Beitrag von weedy » 20.10.2004 03:48:49

Danke übrigens.

weedy.

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 20.10.2004 15:26:51

:D
Keine Ursache. Wollte auch mal wissen, wie das geht. 8)

Antworten