posix_spawnp und piping child output zu einer Zeichenkette

8

Ich habe Probleme mit der Erstellung des Prozesses und der Weiterleitung der Ausgabe des untergeordneten Prozesses in eine Zeichenfolge des übergeordneten Prozesses. Ich habe es funktioniert unter Windows (mit CreatePipe und CreateProcess und ReadFile), aber kann nicht scheinen, das genaue Analog auf Unix zu arbeiten. Das ist mein Code:

%Vor%

Die Ausgabe ist:

  

Exit-Code: 0

Ich nehme also an, dass alles außer der eigentlichen Rohrleitung funktioniert. Was ist hier falsch? Ich frage mich auch, ob es eine Möglichkeit gibt, die piped Bytes in einer Waitpid Schleife zu lesen, aber wenn ich das versuche, hängt der Elternprozess unendlich.

    
rubenvb 15.12.2012, 14:32
quelle

1 Antwort

13

posix_spawn ist interessant und nützlich, was diese Frage wert ist - selbst wenn sie für das OP nicht mehr relevant ist.

Es gibt einige signifikante Fehler im Code, wie gepostet. Ich vermute, dass einige davon das Ergebnis von Hacking in Verzweiflung waren, aber ich weiß nicht, welcher der ursprüngliche Bug war:

  1. Das Array args enthält nicht das argv[0] , das den Namen der ausführbaren Datei darstellen würde. Dies führt dazu, dass das echo -Programm niemals die beabsichtigte argv[1] ("bla").
  2. sieht
  3. Die Funktion read() wird von verschiedenen Stellen aus aufgerufen, und zwar auf eine Weise, die einfach keinen Sinn ergibt. Eine korrekte Vorgehensweise wäre, nur read als Teil des Steuerausdrucks für die while -Schleifen aufzurufen.
  4. waitpid() wird vor dem Lesen der Pipes aufgerufen. Dies verhindert, dass die E / A abgeschlossen wird (zumindest in nicht-trivialen Fällen).
  5. Ein subtileres Problem mit diesem Code besteht darin, dass versucht wird, alle stdout des Kindes vor dem Lesen von stderr zu lesen. Im Prinzip könnte dies dazu führen, dass der untergeordnete Block blockiert wird, während versucht wird, in stderr zu schreiben, wodurch verhindert wird, dass das Programm beendet wird. Eine effiziente Lösung hierfür zu erstellen, ist komplizierter, da es erforderlich ist, dass Sie aus jeder verfügbaren Datenquelle lesen können. Ich habe dafür poll() verwendet. Ein anderer Ansatz wäre die Verwendung mehrerer Threads.

Außerdem habe ich sh (die Befehlsshell, d. h. bash ) als Kindprozess verwendet. Dies bietet eine große zusätzliche Flexibilität, z. B. das Ausführen einer Pipeline anstelle einer einzelnen ausführbaren Datei. Insbesondere bietet die Verwendung von sh den einfachen Vorteil, dass das Parsen der Befehlszeile nicht verwaltet werden muss.

%Vor%     
nobar 06.12.2014, 05:27
quelle

Tags und Links