/******************************************/
/*                                        */
/*  Prof. Dr. Carsten Vogt                */
/*  Fachhochschule Koeln                  */
/*  Fakultaet 07, Nachrichtentechnik      */
/*  http://www.nt.fh-koeln.de/vogt        */
/*                                        */
/*  UNIX-C-Schnittstelle:                 */
/*  Prozesskommunikation ueber            */
/*  Mesage Queues.                        */
/*                                        */
/******************************************/

#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/signal.h>

main() {

 /* Vaterprozess bereitet die Kommunikation vor */

 int msgid; /* Identifikator der Message Queue */

 int empf_id; /* PID des Empfaenger-Prozesses */

 int i, status; /* Hilfsvariable */

 /* Structs, in der der Sender vor dem Abschicken
    die Nachricht aufbaut bzw. der Empfaenger die
    empfangene Nachricht ablegt. */

 struct {
  long mtype;
  int wert1, wert2, wert3;
 } message_snd, message_rcv;

 /* Erzeugung der Message Queue */

 msgid = msgget(IPC_PRIVATE,IPC_CREAT|0777);

 if (fork()==0) {

  for (i=1;i<=5;i++) {

   /* Sender-Prozess sendet in Sekundenabständen
      fünf Dreiergruppen von int-Werten */

   sleep(1);
   message_snd.mtype = 1;
   message_snd.wert1 = 10*i;
   message_snd.wert2 = 10*i+1;
   message_snd.wert3 = 10*i+2;
   printf("\nSender schreibt Typ = %d, Wert1 = %d, Wert2 = %d, Wert3 = %d\n", message_snd.mtype, message_snd.wert1, message_snd.wert2, message_snd.wert3); 
   msgsnd(msgid,&message_snd,sizeof(message_snd)-sizeof(long),0);  }

   /* Sender-Prozess terminiert */

   exit(0);  }
 
 if ((empf_id=fork())==0) {

  /* Empfaenger-Prozess empfaengt beliebig viele
     Dreiergruppen von int-Werten */

  while(1) {

   msgrcv(msgid,&message_rcv,sizeof(message_rcv)-sizeof(long),0,0);
   printf("\nEmpfaenger liest Typ = %d, Wert1 = %d, Wert2 = %d, Wert3 = %d\n", message_rcv.mtype, message_rcv.wert1, message_rcv.wert2, message_rcv.wert3); 

  }

 }

 /* Vater wartet auf Ende des Sender-Prozesses */

 wait(&status);

 /* Vater terminiert den Empfaenger-Prozess */

 kill(empf_id,SIGKILL);

 /* Vater loescht die Message Queue */

 msgctl(msgid,IPC_RMID,0);

}
