commando-zeilen-programmen einen grafische oberfläche verpassen?

guten tag,
i hab versucht einem einfachen programm der commandozeile eine grafische
oberfläche zu verpassen (gtk+ oder qt). das problem dabei ist, dass das
programm die stdout des aufgerufenen prozesses auslesen soll und umleitet auf
die gui.
zunächst habe ich das problem mit popen zu lösen versucht. aber popen kehrt
erst dann zurück, wenn der aufgerufene befehl fertig ist. z.b.

FILE *out = popen("ls", "r");

dann kann ich den stream auf "out", welcher sich auf das stdout von ls bezieht
verwenden. ich möchte jetzt aber dass immer 100 byte ausgelesen werden. z.b.
bei cdda2wav könnte man dann eine prozentanzeige implementieren die den
fortschritt der arbeit anzeigt.

meine idee wäre einen kindprozess zu erzeugen und dort mit execv den
unterprozess zu starten. das problem dabei ist, dass die stdout des
kindprozesses und die stdout des aufgerufenen prozesses nicht identisch sind.
also funktioniert der folgende code nicht:

FILE *out;
int pid = fork();

if(pid == 0) {
  stdout = out;
  char *argv = {"cdda2wav", "cdda2wav", 0x0};
  execv(argv[0], argv);
  perror("execv");
} else {
  [...hier sollte dann über out auf den stream lesend zugegriffen werden.
   vielleicht auch mit select ein multiplexing machen, damit nichts blockiert
   wird...]
}

weiters hab ich auch versucht eine unbenannte pipe zu erstellen über die dann
der stdout-stream des kindprozesses geschrieben wird und im elternprozess
gelesen wird. funktioniert auch nicht, weil (so wie ich glaube) execv den
stdout wieder zurücksetzt auf den ursprung also die ausgabe auf die console.

kann mir jemand dabei helfen? c oder c++ wenn möglich in anderen
programmiersprachen kenne ich mich leider noch nicht aus......

danke im voraus

cya,
pitiz <csad3124(a)uibk.ac.at>

weiters hab ich auch versucht eine unbenannte pipe zu erstellen über die dann
der stdout-stream des kindprozesses geschrieben wird und im elternprozess
gelesen wird. funktioniert auch nicht, weil (so wie ich glaube) execv den
stdout wieder zurücksetzt auf den ursprung also die ausgabe auf die console.

Es gaebe immer noch den Umweg ueber ein temporaeres File in das der
aufgerufene Prozess hineinschreibt und das Dein Prozess ausliest.

Bye, Chris.

* Peter Moser (csad3124(a)uibk.ac.at) wrote:

weiters hab ich auch versucht eine unbenannte pipe zu erstellen über die dann
der stdout-stream des kindprozesses geschrieben wird und im elternprozess
gelesen wird. funktioniert auch nicht, weil (so wie ich glaube) execv den
stdout wieder zurücksetzt auf den ursprung also die ausgabe auf die console.

Bin nicht 100% sicher dass ich alles mitbekommen habe (..bin totmuede :wink:
..so was in dieser Richtung :

..usual includes..

int main (int argc, char **argv)
{
    pid_t pid;
    int filedes[2];
    if (-1 == pipe (filedes)) {
        exit (errno);
    }
    fflush (stdout);
    pid = fork ();
    if (pid > 0) {
        close (filedes[1]);
        printf ("Vater..\n");
        for (;:wink: {
            char buffer[100];
            int count = read (filedes[0], buffer, sizeof (buffer));
            if (count <= 0)
                exit (0);
            write (STDOUT_FILENO, buffer, count);
        }
    } else if (pid == 0) {
        printf ("Kind..\n");
        close (1);
        dup (filedes[1]);
        close (filedes[0]);
        close (filedes[1]);
        execlp ("ls", "ls", "-l", "/home", (char *) 0);
        exit (EXIT_FAILURE);
    } else
        exit (errno);
    return 0;
}

read ist hier natuerlicherweise blockierend, kannst select oder andere
benutzen. Ist wahrscheinlich aber sinnvoller wenn du dir "echte" Beispiele
anschaust [xcdroast zum beispiel in io.c usw.]

Ciao,
Michele (hoffentlich hab ich das richtig mitbekommen..)