pipe() und Umleitung auf stdio
-
Hallo!
Ich arbeite gerade an einem Programm, aus dem heraus eine andere Anwendung gestartet werden soll. Wichtig ist dabei, dass ich im ausführenden Prozess den Konsolenoutput des ausgeführten Programms benötigt. Ich habe das derzeit so implementiert:
#include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int pid, pipes[2]; if (pipe(pipes) != 0) { perror("pipe"); exit(EXIT_FAILURE); } pid = fork(); if (pid < 0) { perror("fork"); exit(EXIT_FAILURE); } if (pid == 0) { close(pipes[0]); if (dup2(pipes[1], 1) == -1) { perror("dup2"); exit(EXIT_FAILURE); } char *argument[3] = { "/usr/bin/pdflatex", "fa.tex", NULL }; char *command = argument[0]; if (execv(command, argument) == -1) { perror("execv"); exit(EXIT_FAILURE); } } else { close(pipes[1]); int readsize = 1; char *buffer = new char[readsize]; while (0 < read(pipes[0], buffer, readsize)) { printf(buffer); } } return 0; }
Das funktioniert soweit perfekt. Problem ist nur: Wenn ich den Wert von readsize erhöhe, etwa 1024 oder sowas, es reicht auch schon aus, ihn auf 20 zu setzen, dann wird die Ausgabe komplett anders formatiert ausgegeben und teilweise schleichen sich einfach Fehler ein. Warum ist das so? Ich meine, 1 byte auszulesen ist irgendwie nicht besonders schön, ich hätte gerne eine Erklärung für dieses Phänomen!
Danke schonmal,
Metalchuck
-
Was erwartet denn ein printf?
Einen mit \0 terminierten String.
Deshalb mein Vorschlag:
int readsize = 20; char *buffer = new char[readsize+1]; while (true) { int ret = read(pipes[0], buffer, readsize); if (ret < 0) { if (errno == EINTR) continue; perror("read"); exit(EXIT_FAILURE); } if (ret == 0) break; buffer[ret] = 0; printf(buffer); }
-
Da fällt mir ein, dass man auf keinen Fall Programmoutput direkt an printf weiterleiten möchte. Man könnte dich dann ja mit einem .tex File hacken.
-
Danke! Das war der entscheidende Trick. Ich arbeite normalerweise selten direkt in C, daher ist mir das natürlich nicht eingefallen...
Zu deiner Anmerkung: Der Output soll in ein GUI-Textfeld geschrieben werden, obiger Code war nur zu Demonstrationszwecken. Aber ich habe da noch ne Frage zu. Wie soll man mich auf diese Weise hacken können? Bräuchte man dazu nicht nen Buffer overflow? Der kann doch hier nicht entstehen, weil ich ja blockweise auslese, oder?
-
metalchuck schrieb:
Danke! Das war der entscheidende Trick. Ich arbeite normalerweise selten direkt in C, daher ist mir das natürlich nicht eingefallen...
Zu deiner Anmerkung: Der Output soll in ein GUI-Textfeld geschrieben werden, obiger Code war nur zu Demonstrationszwecken. Aber ich habe da noch ne Frage zu. Wie soll man mich auf diese Weise hacken können? Bräuchte man dazu nicht nen Buffer overflow? Der kann doch hier nicht entstehen, weil ich ja blockweise auslese, oder?
Ob es praktisch wirklich möglich ist, weiss ich nicht. Aber überleg mal, was passiert wenn ein %d oder %s im output des Programms auftauchen.
Falls du Qt für deine Gui verwendest dann geht alles viel einfacher mit QProcess. Damit kannst du sicher unt einfach einen Subprozess ausführen.