// Betriebssysteme1 - Uebung 11, Matthias Jauernig, 2005 #include #include #include #include #include int main(void){ int fd1[2], fd2[2], rc, l; pid_t pid1, pid2; bool ende1, ende2; char ea1[100], ea2[100], *ret1, *ret2; // erste Pipe öffnen if((rc=pipe(fd1)) < 0){ perror("Fehler beim Oeffnen von Pipe1"); return 1; } // ersten Child erzeugen if((pid1=fork()) == -1){ perror("Fehler beim Erzeugen von Child1"); return 2; } switch(pid1){ case 0: // im Child1 if(close(fd1[0]) < 0){ // schließe die eine Pipe-Seite perror("Konnte Pipe1-Seite in Child1 nicht schließen"); return 3; } // lese Daten, bis EOF do{ // empfange "Arbeitserlaubnis" vom Parent if((l=read(fd1[1], ea1, sizeof(ea1))) < 0){ perror("Initialer Read im Child1"); return 13; } // lese Daten von stdin fflush(stdin); printf("Child1: Dateneingabe: "); ret1 = fgets(ea1, sizeof(ea1), stdin); // Daten an Parent senden if(ret1){ if((l=write(fd1[1], ea1, sizeof(ea1))) < 0){ perror("Fehler beim Senden der Daten von Child1 zum Parent"); return 14; } } }while(ret1); // bei Fehler oder EOF Pipe schließen, Child verlassen if(close(fd1[1]) < 0){ // schließe die letzte offene Pipe-Seite perror("Konnte Pipe in Child1 nicht endgueltig schließen"); return 15; } break; default:// im Parent if(close(fd1[1]) < 0){ // schließe die andere Pipe-Seite perror("Konnte Pipe1-Seite in Parent nicht schließen"); return 4; } // zweite Pipe öffnen if((rc=pipe(fd2)) < 0){ perror("Fehler beim Oeffnen von Pipe2"); return 5; } // zweiten Child erzeugen if((pid2=fork()) == -1){ perror("Fehler beim Erzeugen von Child2"); return 6; } switch(pid2){ case 0: // im Child2 if(close(fd2[0]) < 0){ // schließe die eine Pipe-Seite perror("Konnte Pipe2-Seite in Child2 nicht schließen"); return 7; } // lese Daten, bis EOF do{ // empfange "Arbeitserlaubnis" vom Parent if((l=read(fd2[1], ea2, sizeof(ea2))) < 0){ perror("Initialer Read im Child2"); return 16; } // lese Daten von stdin fflush(stdin); printf("Child2: Dateneingabe: "); ret2 = fgets(ea2, sizeof(ea2), stdin); // Daten an Parent senden if(ret2){ if((l=write(fd2[1], ea2, sizeof(ea2))) < 0){ perror("Fehler beim Senden der Daten von Child2 zum Parent"); return 17; } } }while(ret2); // bei Fehler oder EOF Pipe schließen, Child verlassen if(close(fd2[1]) < 0){ // schließe die letzte offene Pipe-Seite perror("Konnte Pipe in Child2 nicht endgueltig schließen"); return 18; } break; default:// im Parent if(close(fd2[1]) < 0){ // schließe die andere Pipe-Seite perror("Konnte Pipe2-Seite in Parent nicht schließen"); return 8; } // Kommunikation mit Childs ende1 = false; ende2 = false; do{ // Kommunikation mit Child1 if(!ende1){ strncpy(ea1,"1", 2); // Child1 soll Daten lesen und senden if((l=write(fd1[0], ea1, sizeof(ea1))) < 0){ perror("Fehler beim initialen Senden zu Child1"); return 9; } // empfange Daten von Child1 if((l=read(fd1[0], ea1, sizeof(ea1))) < 0){ perror("Fehler beim Daten-Empfang von Child1"); return 10; }else{ if(l==0){ printf("Parent: Child1 beendet\n"); ende1 = true; if(close(fd1[0]) < 0){ perror("Konnte Pipe1 in Parent nicht endgueltig schließen"); return 19; } }else printf("Parent: Von Child1 empfangen: %s\n", ea1); } } // Kommunikation mit Child2 if(!ende2){ strncpy(ea2,"2", 2); // Child2 soll Daten lesen und senden if((l=write(fd2[0], ea2, sizeof(ea2))) < 0){ perror("Fehler beim initialen Senden zu Child2"); return 11; } // empfange Daten von Child2 if((l=read(fd2[0], ea2, sizeof(ea2))) < 0){ perror("Fehler beim Daten-Empfang von Child2"); return 12; }else{ if(l==0){ printf("Parent: Child2 beendet\n"); ende2 = true; if(close(fd2[0]) < 0){ perror("Konnte Pipe2 in Parent nicht endgueltig schließen"); return 20; } }else printf("Parent: Von Child2 empfangen: %s\n", ea2); } } }while(!ende1 || !ende2); printf("Parent: Beide Childs beendet...\n"); break; } break; } return 0; }