stdin und stdout über Pipe mit zwei Kindprozessen

bastler

Grünschnabel
Hallo,

ich programmiere gerede ein etwas größeres C-Programm.
Nun habe ich den Code für dieses Forum minimiert, um das Problem schnell klar zu machen.
Ziel ist es, dass ein Kindprozess einem anderen Kindprozess eine einfache Ausgabe seines Standart-Outputs über eine Pipe zum anderen Kindprozess schickt und dieser dann das Geschickte als seinen Standart-Input nimmt.

Es geht auch fast alles. Nur wartet z.B. der Befehl "sort" scheinbar auf den Stream. Aber der ist dort!
Zum Beweis, habe ich dann ein kleines Stück des Stream ausgeben lassen (was man unten sieht).

Mein Programm:
Code:
#include <stdio.h>		/* I/O                                   */
#include <stdlib.h>		/* standard c functions                  */
#include <string.h>		/* string manipulations                  */
#include <unistd.h>		/* for the Stream-Management             */
#include <sys/types.h>

void main(void){
	FILE *umleit;
	int myeins[2];
	char string[256];
	pid_t prozessid=1;
	
	pipe(myeins);
	prozessid=fork();
	if(prozessid==0){
		dup2(myeins[1],STDOUT_FILENO);
		system("ls");
		exit(0);
	}
	prozessid=fork();
	if(prozessid==0){
		dup2(myeins[0],STDIN_FILENO);
		umleit=fdopen(myeins[0],"r");
		printf("\n");
		fscanf(umleit,"%s",&string);
		printf("Empfangen: %s\n",string);
		fscanf(umleit,"%s",&string);
		printf("Empfangen: %s\n",string);
		printf("\n\n");
		system("sort");
		exit(0);
	}
}

Die Ausgabe dazu:
Code:
Empfangen: alt
Empfangen: datei.txt

Da auf dem Stream noch mehr liegt, müsste "sort" etwas bekommen, aber der wartet!
Bitte schaue sich einer mal mein Problem an.
 
Hi

Zuerst einmal muß ich dir sagen: deine Problembeschreibung ist wunderbar! So wünscht man sich das. Danke!

Das Problem dürfte sein, daß du die Pipe (-Eingabe) nicht schließt. sort kann schließlich erst mit dem Sortieren anfangen wenn die Eingabe vollständig ist.

Gruß
 
Danke für die Antwort!
Obwohl mein zuvor beschriebenes Problem beseitigt ist, tritt nun leider ein weiteres auf:
Der erzeugende Prozess (Elternprozess) soll immer auf seine Kindprozesse warten.

Eigendlich kein Problem, aber hier schon. Das selbe Programm wie oben habe ich nun auf das Problem angepasst.
Das Problem erkläre ich unter dem Code:

Code:
#include <stdio.h>		/* I/O                                   */
#include <stdlib.h>		/* standard c functions                  */
#include <string.h>		/* string manipulations                  */
#include <unistd.h>		/* for the Stream-Management             */
#include <sys/types.h>
#include <sys/wait.h>

void main(void){
	FILE *umleit;
	int myeins[2];
	int status;
	char string[256];
	pid_t prozessid=1;
	
	pipe(myeins);
	prozessid=fork();
	if(prozessid==0){
		close(myeins[0]);
		dup2(myeins[1],STDOUT_FILENO);
		system("ls");
		close(myeins[1]);
		
		exit(0);
	}
	if (prozessid!=0) {
		printf("Nach erstem Prozess\n");
		while(waitpid(prozessid,&status,WNOHANG)==0){};
	}
	prozessid=fork();
	if(prozessid==0){
		close(myeins[1]);
		dup2(myeins[0],STDIN_FILENO);
		system("sort");
		close(myeins[0]);
		exit(0);
	}
	if (prozessid!=0) {
		printf("Nach zweitem Prozess\n");
		while(waitpid(prozessid,&status,WNOHANG)==0){}; // um diese Zeile geht es
	}
}

Wenn ich nun die makierte Zeile (die mit dem Kommentar) komplett auskommentiere, dann kommt folgende Ausgabe:

Code:
benutzer@linux-2mj4:~/prog/proj2> ./test2
Nach erstem Prozess
Nach zweitem Prozess
benutzer@linux-2mj4:~/prog/proj2> alt
Fehlercode.txt
inputfile
output
shell
shell.c
shell.c~
sicherung
temp
test
^C

Wie man sieht, hat sich der Elternprozess schon beendet, als der Kindprozess "sort" ausführt. Nach dem ausführen bleibt der Prozess stehen und man muss ihn abbrechen.
Wenn ich die makierte Zeile mit kompiliere gibt er folgendes aus (was man auch irgendwann abbrechen muss):

Code:
benutzer@linux-2mj4:~/prog/proj2> ./test2
Nach erstem Prozess
Nach zweitem Prozess
^C

Ich möchte aber, dass der Elternprozess solange wartet, bis sich der gegenwärtige Kindprozess beendet hat.
 
Zurück