#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/signal.h>
#include <strings.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>

char *tempfile="tempfile.dat";

volatile int gen=0;

char* file_read();
int file_store(int);
int generate();
int notify_number(int);
int consume_number(char *);
int generate_sleep();
void parent_sigset_catcher(int);
void child_sigset_catcher(int);


int consume_number(char *the_num)
{
	char temp[50];
	sprintf(temp, "child %d consumes number %s\n", getpid(), the_num);
	write(1, temp, strlen(temp));
	return(0);
}					
	
int notify_number(int the_num)
{
	char temp[50];
	sprintf(temp, "parent %d generates number %d\n", getpid(), the_num);
	write(1, temp, strlen(temp));
	return(the_num);
}

int generate()
{
	return((rand()%33)+1);
}

int file_store(int num)
{
	char temp_var[10];
	int filedes;
	filedes=creat(tempfile, 0644);
	filedes=open(tempfile, O_WRONLY, 0644);
	sprintf(temp_var, "%d", num);
	write(filedes, temp_var, sizeof(temp_var));
	close(filedes);
	
	return(filedes);
}

char* file_read()
{
	char temp_char[10];
	int filedes;
	filedes=open(tempfile, O_RDONLY);
	read(filedes, temp_char, sizeof(temp_char));
	close(filedes);
	unlink(tempfile);
	return(temp_char);
}	

int generate_sleep()
{
	return((rand()%5)+1);
}

int main()
{
	int pid;
	int c_pid, p_pid;
	int ident_p=0, ident_c=0;
	
	
	if ((pid=(unsigned) fork())!=0)
	{
		srand((unsigned) getpid());
		sigset(SIGUSR1, parent_sigset_catcher);	
		c_pid=pid;
		ident_p=1;
	}
	else
	{
		srand((unsigned) getpid());
		sigset(SIGUSR2, child_sigset_catcher);
		p_pid=getppid();
		ident_c=1;
	}

	if (ident_p == 1)
	{
		file_store(notify_number((gen=generate())));
		for(; ;)
		{
			sleep(generate_sleep());
			kill(c_pid, SIGUSR2);
			sigpause(SIGUSR1);
		}
	}	

	if (ident_c == 1)
	{
		sleep(1);
		for(; ;)
		{
			sleep(generate_sleep());
			kill(p_pid, SIGUSR1);
			sigpause(SIGUSR2);
		}
	}
	return(0);
}

void parent_sigset_catcher(int the_sig)
{
	//printf("parent signal received %d \n", the_sig);
	sleep(1);//generate_sleep());
	file_store(notify_number((gen=generate())));
}

void child_sigset_catcher(int the_sig)
{
	//printf("child signal received %d \n", the_sig);
	sleep(1);//generate_sleep());
	consume_number(file_read());
}

