#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmid, shmptr;
int msgid;

int *SHMEM;  /* start address of shared memory segment */

typedef struct {
    long mtype;         /* message type */
    int  data;          /* just some data */
    } semmsg;

typedef struct {
    long mtype;
    int data[100];
    }  messagetype;

void del_and_exit (i)
int i;
{ /* delete shared memory and quit */
  shmctl(shmid, IPC_RMID, 0);  
  msgctl(msgid, IPC_RMID);  
  exit();
}


bcopy (from, to, bytes)
char *from, *to;
int bytes;
{  int i;

   for (i=0; i<=bytes; i++) to[i] = from [i];
 }

unsigned short _rnd_init_v[3] = {0, 0, 0};

rndom(i)  /* random number between 0 and i-1 */
int i;
{
  if (_rnd_init_v[0] == 0) 
              { _rnd_init_v[0] = _rnd_init_v[1] = _rnd_init_v[2] = getpid();
		seed48(_rnd_init_v);
	      }
  return ( lrand48() % i);
}

InitSem(sem, num)
int num, sem;
{  int i;
   for (i=1; i<=num; i++) V(sem);
 }

P(sem)
int sem;
{ semmsg M;
  int i;
  i = msgrcv(msgid, &M, sizeof(M), sem + 2, 0);
  if (i==-1) { printf("Error in P operation on Sem: %d \n", sem); exit();}
  if (M.mtype != (sem+2)) { printf("Gross Error %d:%d\n", M.mtype, sem+2);} 
}

V(sem)
int sem;
{ semmsg M;
  int i;
     M.mtype   = sem + 2;
     M.data    = sem;
     i = msgsnd(msgid, &M, sizeof(M), 0); 
     if (i==-1) { printf("Error in V operation on Sem: %d \n", sem); exit();}
}


sendport(port, mesg, size)
int port, size;
char *mesg;
{  messagetype M;
   int i;

   if (size > 400) {printf("message too long\n"); exit(); };
   M.mtype   = port + 100;
   bcopy(mesg, M.data, size); 
   i = msgsnd(msgid, &M, size+4, 0); 
   if (i==-1) { printf("Error in SEND operation on Port: %d \n", port); 
                exit();
   }   
}

receiveport(port, mesg, maxsize)
int port, *mesg, maxsize;
{  messagetype M;
   int i;

   M.mtype   = port + 100;
   i = msgrcv(msgid, &M, sizeof(M), port + 100, 0);
   if (i==-1) { printf("Error in RECEIVE operation on Port: %d \n", port); 
                exit();
   }   
   bcopy(M.data, mesg, maxsize); /* bcopy not supported on SysV!! */
}

Initialize()
{  
   key_t key;

   key = 225000000 + getuid();  /* unique number */
   /* now get a shared memory segment and a attach it */
   shmid =  shmget( key , 1024, 0777|IPC_CREAT);
   if (shmid==-1) { printf("Could not get a Semaphore\n"); exit(0); };
   shmptr = (int) shmat(shmid, 0, 0);
   if (shmptr==-1) { 
       perror("Could not attach shared memory\n"); exit(0);};

   /* get a message queue ... hack */
   msgid = msgget( key, 0777 | IPC_CREAT);   
   if (msgid==-1) { perror ("Could not get message queue\n"); exit(0);};


   SHMEM = (int *) shmptr;
   signal(SIGINT,  del_and_exit); /* cleanup on most signals */
   signal(SIGHUP,  del_and_exit); 
   signal(SIGTERM, del_and_exit);
   signal(SIGBUS,  del_and_exit); 
   signal(SIGSEGV,  del_and_exit); 
   printf ("Initialized %d %d\n", shmptr, msgid);
 }



StartProcess(proc)
void (*proc)();
{
  if (fork()==0){
     proc();
     exit();
   }
}


