#include "headers.h"
int main(int argc, char *argv[]){
extern int errno;
int sem_id;
/* Struct for waiting on the semaphore */
static struct sembuf sem_wait[] = { 0, -1, 0 };
/* Struct for signalling on the semaphore */
static struct sembuf sem_signal[] = { 0, +1, 0 };
/* We want our fifo mode to be readable and writable only to us */
mode_t fifo_mode = 0x00000180;
const char *fifopath = "/tmp/alarm_fifo";
int fd;
pid_t child_alive = 0;
pid_t child_pid = 1; /* Just for initialization purposes */
int foo; /* Dumb value for the signal handler */
/* Install a new signal handler */
signal(SIGUSR1, new_handler);
/* We need to create a semaphore set */
/* First check if it is already there */
if((sem_id = semget(0x1014fbad, 0, 0)) == -1){
/* Need to create the set */
if((sem_id = semget(0x1014fbad, 1, IPC_CREAT | IPC_EXCL | SEM_PERM)) != -1){
/* We need to initialize the new semaphore set */
union semun arg;
ushort init_v[] = { 1 };
arg.array = init_v;
if(semctl(sem_id, 1, SETALL, arg) == -1){
fprintf(stderr, "%s: semctl in parent\n", strerror(errno));
abort();
}
}
}
child_alive = find_child();
/* If the child is dead, we need to see if the semaphore is set properly.
* It may not be if the child died abnormally.
*/
if(!child_alive){
/* Reset the semaphore set, just in case... */
union semun arg;
ushort init_v[] = { 1 };
arg.array = init_v;
if(semctl(sem_id, 1, SETALL, arg) == -1){
fprintf(stderr, "%s: semctl() in parent\n", strerror(errno));
abort();
}
}
/* Now we wait */
if(semop(sem_id, sem_wait, 1) < 0){
fprintf(stderr, "%s: semop() in parent\n", strerror(errno));
abort();
}
if(child_alive){
/* Signal our child to wake up */
if(kill(child_alive, SIGUSR1) < 0){
fprintf(stderr, "%s: sending signal to child\n", strerror(errno));
abort();
}
}
/* First try to open our FIFO; if it doesn't open, create it, then open */
if((fd = open(fifopath, O_RDWR)) == -1){
/* We don't have a FIFO, make one */
if(mkfifo(fifopath, fifo_mode)){ /* Create a FIFO */
fprintf(stderr, "%s: mkfifo() in parent\n", strerror(errno));
abort();
}
else{
if((fd = open(fifopath, O_RDWR)) == -1){
fprintf(stderr, "%s: open() of FIFO in parent\n", strerror(errno));
abort();
}
}
}
/* Fork an itty bitty child... */
if(!child_alive){
if((child_pid = fork()) == -1){
fprintf(stderr, "%s: fork()\n", strerror(errno));
abort();
}
}
if(child_pid == 0)
new_handler(foo);
else
client(fd, sem_id);
return 0;
}