#include #include #include #include #include typedef struct { char name[20]; // Buffer overflow char vorname[20]; // waiting to happen long matrikelnr; int note; } Zulassung; void sekretariat(int pipe_fd) { Zulassung z; // Zeug nullen memset(&z, 0, sizeof(z)); // So lange Daten lesen bis scanf auf ungültige Werte stösst while (scanf("%s %s %ld", z.name, z.vorname, &z.matrikelnr) == 3) // Zulassung in pipe schreiben write(pipe_fd, &z, sizeof(z)); } void pruefer(int pipe_fd_in, int pipe_fd_out) { Zulassung z; // So lange struct Zulassung aus der pipe lesen, // bis nicht mehr genügend Daten vorhanden sind while (read(pipe_fd_in, &z, sizeof(z)) == sizeof(z)) { // Note eintragen // PS: Folgender Algorithmus ist eine akkurate Repräsentation der Notenvergabe an der FH z.note = (z.matrikelnr % 6) + 1; // Zeug weiterleiten write(pipe_fd_out, &z, sizeof(z)); } } void pruefungsamt(int pipe_fd) { Zulassung z; // So lange struct Zulassung aus der pipe lesen, // bis nicht mehr genügend Daten vorhanden sind while (read(pipe_fd, &z, sizeof(z)) == sizeof(z)) { // Zeug ausgeben printf("[Matrikelnr: %6ld] Name: %s %s - Note: %d\n", z.matrikelnr, z.vorname, z.name, z.note); } } /************************************************************/ /* */ /* Erzeugen dreier paralleler Prozesse, die über pipes */ /* kommunizieren: */ /* */ /* SEKRETARIAT ---------> PRÜFER --------->PRÜFUNGSAMT */ /* PIPE_1 PIPE_2 */ /* */ /************************************************************/ int main() { int Pipe_1[2], Pipe_2[2]; /* pipe-Deskriptoren */ int Status_1, Status_2; Status_1 = pipe(Pipe_1); /* Erzeugen der pipes */ Status_2 = pipe(Pipe_2); if ((Status_1 == -1) || (Status_2 == -1)) /* pipe() liefert */ printf("\n!!! kann pipe nicht erzeugen\n"); /* im Fehlerfall-1*/ else if (fork() == 0) /* nicht Vater */ { if (fork() == 0) /* Enkel */ { close (Pipe_1[0]); /* darf in Pipe_1 nicht lesen */ close (Pipe_2[0]); /* darf in Pipe_2 nicht lesen */ close (Pipe_2[1]); /* darf in Pipe_2 nicht schreiben */ sekretariat(Pipe_1[1]); } else /* erstes Kind */ { close(Pipe_1[1]); /* darf in Pipe_1 nicht schreiben */ close(Pipe_2[0]); /* darf in Pipe_2 nicht lesen */ pruefer(Pipe_1[0], Pipe_2[1]); } } else { if (fork() == 0) /* zweites Kind */ { close(Pipe_1[0]); /* darf in Pipe_1 nicht lesen */ close(Pipe_1[1]); /* darf in Pipe_1 nicht schreiben */ close(Pipe_2[1]); /* darf in Pipe_2 nicht schreiben */ pruefungsamt(Pipe_2[0]); } /* der Vaterprozess stirbt nach Erzeugen der Kind- */ /* prozesse, dabei wird implizit für jeden */ /* seiner pipe-Deskriptoren 'close' aufgerufen. */ } }