CS431 - Homework #6
/****************************************
Name: Thomas Heffron
Section: CS431 NET
Program: Program #6 - producer
Due Date: Dec. 5, 2002
Desc: Process that creates a file input
pipe to read from a file and an
IPC output pipe to export what has
been read.
Inputs: Process takes two CMD args as
input/output pipe names.
Outputs: Process will pass error signals
if pipes cannot be opened.
*****************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
/* Data declarations used by all functions */
FILE *ifptr;
int fdpipe;
extern int errno;
/* Function declarations */
static void sig_alarm(int signo);
unsigned long get_time();
int main(int argc, char *argv[]) {
int fifostat, size, wait_val;
char buffer[256];
size_t bsize = 256;
umask(0);
/* Set random seed */
srand(get_time() % 64003);
printf("Producer created...\n");
/* Set alarm signal handlers - one for SIGUSR1 */
if (signal(SIGUSR1, sig_alarm) == SIG_ERR) {
printf("The SIGUSR1 function returned an error.\n");
exit(1);
}
/* and one for SIGUSR2 */
if (signal(SIGUSR2, sig_alarm) == SIG_ERR) {
printf("The SIGUSR2 function returned an error.\n");
exit(1);
}
/* Open file for reading - signal to main if error */
if ( (ifptr = fopen(argv[1], "r")) == NULL) {
printf("!!! Could not open file for input: %s\n", argv[1]);
printf("!!! Sending alarm to main process.\n");
kill(getppid(), SIGALRM);
}
/* Now open pipe for writing - signal main if error */
if ( (fdpipe = open(argv[2], 0666)) == -1) {
printf("!!! Could not open pipe for output: %s\n", argv[2]);
printf("!!! Sending alarm to main process.\n");
kill(getppid(), SIGALRM);
}
/* Now we can begin to handle the file */
/* Read until no data left and pass to output pipe */
/* Then calculate a random time to wait */
while (fgets(buffer, 256, ifptr) != NULL) {
write(fdpipe, buffer, strlen(buffer));
wait_val = ((int) (4.0*rand()/(RAND_MAX + 1.0)));
sleep(wait_val);
}
/* Once file is empty, wait 3 seconds for other */
/* pipes to clear. Then send a single EOF to buffer */
sleep(3);
buffer[0] = EOF;
write(fdpipe, buffer, 1);
/* now wait until this process gets the alarm from main */
/* Main will then send signals to this process for exit */
while(1);
}
/* Single function to handle all signals */
static void sig_alarm(int signo) {
/* if signal is USER1 then simply wait */
/* we do this to stop processing file */
/* but wait for other processes to stop */
if (signo == SIGUSR1) {
printf("* Producer halted.\n");
while(1);
}
/* if signal is USER2 then main has */
/* handled the exit gracefully. We will */
/* close all pipes and exit process. */
if (signo == SIGUSR2) {
fclose(ifptr);
close(fdpipe);
printf("** Producer now exiting.\n");
exit(0);
}
}
/* Function to get a large integer for random seed */
unsigned long get_time()
{
FILE *in_file;
unsigned long retval;
float trash;
in_file = fopen("/proc/uptime", "r");
fscanf(in_file, "%lu%f", &retval, &trash);
fclose(in_file);
return retval;
}