#include "headers.h"

void new_handler(int dummy){
  /* This is the child now */
  /* Daemon code */
  const char *pid_file = "/tmp/alarm.pid";
  int statloc;
  int pid_fd;
  int this_child_pid;
  int child_fd;
  int child_sem_id;
  int pid_length;
  time_t alarm_time;
  char string_pid[MY_MAX];
  char *pid_char_id;
  const char *fifopath = "/tmp/alarm_fifo";
  char inbuf[MY_MAX];
  int in_size;
  union semun child_arg;
  /* Struct for waiting on the semaphore */
  static struct sembuf child_sem_wait[] = { 0, -1, 0 };
  /* Struct for signalling on the semaphore */
  static struct sembuf child_sem_signal[] = { 0, +1, 0 };
  /* Get the semaphore set for this process */
  this_child_pid = getpid();
  pid_char_id = gcvt(this_child_pid, 5, string_pid);
  pid_length = (strlen(string_pid));
  string_pid[pid_length] = '\0';  /* Null terminate the string */
  pid_length++;
  if((pid_fd = open(pid_file, O_RDWR)) < 0){
    if((pid_fd = creat(pid_file, 0600)) < 0){
      fprintf(stderr, "%s: creat() in child\n", strerror(errno));
      abort();
    }
  }
  if(write(pid_fd, string_pid, 0) < 0){  /* Clear the file */
    fprintf(stderr, "%s: write() in child\n", strerror(errno));
    abort();
  }
  if(write(pid_fd, string_pid, pid_length) < 0){
    fprintf(stderr, "%s: write() in child\n", strerror(errno));
    abort();
  }
  close(pid_fd);
  if((child_sem_id = semget(0x1014fbad, 0, 0)) < 0){
    fprintf(stderr, "%s: semget() in child\n", strerror(errno));
    abort();
  }
  /* Now we wait */
  if(semop(child_sem_id, child_sem_wait, 1) < 0){
    fprintf(stderr, "%s: semop() in child\n", strerror(errno));
    abort();
  }
  if((child_fd = open(fifopath, O_RDWR)) == -1){
    fprintf(stderr, "%s: open() in child\n", strerror(errno));
    abort();
  }
  /* Read from the FIFO */
  read(child_fd, &in_size, sizeof(in_size));
  read(child_fd, inbuf, in_size);
  read(child_fd, &alarm_time, sizeof(alarm_time));
  close(child_fd);
  /* Release semaphore here */
  if(semop(child_sem_id, child_sem_signal, 1) < 0){
    fprintf(stderr, "%s: semop() in child\n", strerror(errno));
    abort();
  }
  /* We want the signal to be discarded */
  signal(SIGUSR1, SIG_IGN);
  sleep(alarm_time);
  printf("\a");  /* For a cheesy beep */
  printf("%s\n", inbuf);
  /* Now wait for a signal */
  signal(SIGUSR1, new_handler); /* Re-install the signal handler */
  while(1)
    sigpause(0);
}