/*
 * sysbench.c
 *
 * It initializes a message queue, 2 semaphore sets and a shared memory, 
 * and then waits for a semaphore.
 * After running sysbench, you should run 'sysmark' on a possibly remote 
 * machine to see the results of the benchmark
 *
 * By Kamran Karimi
 */

#include "sysbm.h"

int msgid = -1;
int semid = -1;
int shmid = -1;
int msg_resultid = -1;

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

 if(semid > -1)
  if(semctl(semid, 1, IPC_RMID, 0) < 0)
   fprintf(stderr,"sysbench: failed to remove the semaphore, BECAUSE %s\n", 
                                                           strerror(errno));
 if(msg_resultid > -1)
  if(msgctl(msg_resultid, IPC_RMID, NULL) < 0)
   fprintf(stderr,"sysbench: failed to remove the semaphore, BECAUSE %s\n", 
                                                           strerror(errno)); 
 if(msgid > -1)
  if(msgctl(msgid,IPC_RMID,NULL) < 0)
   fprintf(stderr,"sysbench: failed to remove the message queue, BECAUSE %s\n", 
                                                               strerror(errno));
 if(shmid > -1)
  if(shmctl(shmid,IPC_RMID,NULL) < 0)
   fprintf(stderr,"sysbench: failed to remove the shared memory, BECAUSE %s\n", 
                                                               strerror(errno));
 exit(5);
}


void main()
{
 unsigned short seminit[1]; 
 struct sigaction sact;
 struct msg_result result_mess;

 sigemptyset(&sact.sa_mask);
 sact.sa_flags = 0;
 sact.sa_handler = sig_handler;
 if(sigaction(SIGINT, &sact, NULL) < 0)
  fprintf(stderr,"sysbench: Can't Catch Signal, BECAUSE: %s\n",strerror(errno));
 
 msgid = msgget(MSG_KEY, MSG_MODE | IPC_CREAT);
 if(msgid < 0) 
 {
  fprintf(stderr,"sysbench: msgget() failed BECAUSE %s\n", strerror(errno));
  raise(SIGINT);
 }

 shmid = shmget(SHM_KEY, SHM_SIZE, SHM_MODE | IPC_CREAT);
 if(shmid < 0) 
 {
  fprintf(stderr,"sysbench: shmget() failed BECAUSE %s\n", strerror(errno));
  raise(SIGINT);
 }
  
 semid = semget(SEM_KEY, 1, SEM_MODE | IPC_CREAT);
 if(semid < 0)
 {
  fprintf(stderr,"sysbench: semget() failed BECAUSE %s\n", strerror(errno));
  raise(SIGINT);
 }
 seminit[0] = 0;
 if(semctl(semid, 1, SETALL, seminit) < 0)
 {
  fprintf(stderr,"sysbench: Can not initialize the semaphores BECAUSE %s\n", 
                                                              strerror(errno));
  raise(SIGINT);
 }

 msg_resultid = msgget(MSG_RESULT_KEY, MSG_MODE | IPC_CREAT);
 if(msg_resultid < 0) 
 {
  fprintf(stderr,"sysbench: msgget() failed BECAUSE %s\n", strerror(errno));
  raise(SIGINT);
 }

 if(fork() == 0)
 { /* child */
  if(execlp("sh","sh","sys_s", NULL) < 0)
   fprintf(stderr,"sysbench: execlp failed!\n");
  exit(0);
 }

 do
 {
  if(msgrcv(msg_resultid, (struct msgbuf *)&result_mess, MSG_RESULT_SIZE, 0, 0) < 0)
  {
   fprintf(stderr,"sysbench: msgrcv() failed BECAUSE %s\n", strerror(errno));
   raise(SIGINT);
  }
  if(!strcasecmp(result_mess.mtext,"done"))
   break;
  fprintf(stderr,"%s\n", result_mess.mtext);
 }while(1);
  
 raise(SIGINT);
}
