#define _HPUX_SOURCE
/******************************************/
/*                                        */
/*  Prof. Dr. Carsten Vogt                */
/*  Fachhochschule Koeln                  */
/*  Fakultaet 07, Nachrichtentechnik      */
/*  http://www.nt.fh-koeln.de/vogt        */
/*                                        */
/*  UNIX-C-Schnittstelle:                 */
/*  Synchronisation mit Semaphoren        */
/*  Hier: Reihenfolgebeziehung            */
/*                                        */
/******************************************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>

main() {

 /* Vater bereitet vor */

 int status; /* Hilfsvariable */

 int semid; /* Identifikator der Semaphorgruppe */

 unsigned short init_array[1]; /* zur Initialisierung */

 struct sembuf sem_p, sem_v; /* Beschreibung von P- und V-Operationen */

 /* Erzeugung einer Semaphorgruppe mit einem Semaphor */

 semid = semget(IPC_PRIVATE,1,IPC_CREAT|0777);

 /* Initialisierung des Semaphors mit dem Wert 0 */

 init_array[0] = 0;
 semctl(semid,0,SETALL,init_array);

 /* Vorbereitung der P- und der V-Operation */

 sem_p.sem_num = 0;   sem_v.sem_num = 0;
 sem_p.sem_op  = -1;  sem_v.sem_op  = 1;
 sem_p.sem_flg = 0;   sem_v.sem_flg = 0;

 if (fork()==0) {

  /* Vorgaengerprozess */

  /* Schlaeft drei Sekunden */

  printf("\nVorgaenger schlaeft\n");
  sleep(3);

  printf("\nVorgaenger wird fertig\n");

  /* Entblockiert den Nachfolger durch eine V-Operation */

  semop(semid,&sem_v,1);

  /* Terminiert */

  exit(0);

 }

 if (fork()==0) {

  /* Nachfolgerprozess */

  /* Blockiert in einer P-Operation und wartet damit auf den Vorgaenger */

  printf("\nNachfolger wartet auf Vorgaenger\n");
  semop(semid,&sem_p,1);

  printf("\nNachfolger laeuft weiter\n");

  /* Schlaeft zwei Sekunden */

  sleep(2);

  /* Terminiert */

  printf("\nNachfolger wird fertig\n\n");
  exit(0);

 }

 /* Vater wartet auf Ende der beiden Soehne */

 wait(&status);
 wait(&status);

 /* Vater loescht den Semaphor */

 semctl(semid,0,IPC_RMID,0);

}

