/*
 * pi.c
 *
 * invokes 10 instances of the integrator program and recives the 
 * results of their computaions to produce the value of pi.
 *
 * By Kamran Karimi
 */

#include "pi.h"

int msgid = -1;

static void sig_handler(int signo)
{
 fprintf(stderr,"Pi: Quiting\n");

 if(msgid != -1)
  msgctl(msgid, IPC_RMID, NULL); 
 exit(5);
}


int main()
{
 int count;
 struct sigaction sact;
 double Result = 0;
 struct message mess;
 
 sact.sa_handler = sig_handler;
 sigemptyset(&sact.sa_mask);
 sact.sa_flags = 0;
 if(sigaction(SIGINT, &sact, NULL) < 0)
 {
  fprintf(stderr,"Pi: Can't Catch Signal");
  fprintf(stderr,"  BECAUSE: %s\n",strerror(errno));
 }
  
 msgid = msgget(MSG_KEY, MSG_MODE | IPC_CREAT);
 if(msgid < 0) 
 {
  fprintf(stderr,"Pi: msgget() failed BECAUSE %s\n", strerror(errno));
  exit(20);
 }
 
 fprintf(stderr,"Pi: starting remote tasks\n");
 if(fork() == 0)
 { /* child */
  if(execlp("sh","sh","pi_s", NULL) < 0)
   fprintf(stderr,"Pi: execlp() failed BECAUSE %s\n", strerror(errno));
  raise(SIGINT);
 }
 
 for(count = 0; count < NUM_INTEGRATORS; count++)
 {
  fprintf(stderr,"Pi: waiting for Result #%d...\n", count + 1);
  if(msgrcv(msgid, (struct msgbuf *)&mess, sizeof(struct body), 0, 0) < 0)
  {
   fprintf(stderr,"Pi: msgrcv() failed BECAUSE %s\n", strerror(errno));
   raise(SIGINT);
  }
  if(mess.body.architecture != MY_DIPC_ARCH)
   fprintf(stderr,"Pi: Different Architecture. Needs Conversion\n");
  Result += mess.body.result;   
 }
 fprintf(stderr, "Pi: PI as computed is: %25.20e\n", Result);
 raise(SIGINT);
 exit(0); /* gcc insisted on this */
}
  