CS431 - Homework #6
/**************************************
Name: Thomas Heffron
Section: CS431 NET
Program: Program #6 - consumer
Due Date: Dec. 5, 2002
Desc: Process that opens an IPC input
pipe for reading and creates
a file output pipe for final export.
Inputs: Process takes two CMD args as
input/output pipe names.
Output: 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 declaration used by all functions */
FILE *ofptr;
int inpipe;
extern int errno;
/* Function declarations */
static void sig_alarm(int signo);
unsigned long get_time();
int main(int argc, char *argv[]) {
int size, wait_val, i;
char buffer[256];
size_t bsize = 256;
umask(0);
/* Set random seed */
srand(get_time() % 16007);
printf("Consumer created...\n");
printf("\nEncrypted output:\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 pipe for reading - signal to main if error */
if ( (inpipe = open(argv[1], 0666)) == -1) {
printf("!!! Could not open pipe for input: %s\n", argv[1]);
printf("!!! Sending alarm to main process.\n");
kill(getppid(), SIGALRM);
}
/* Open file for output - signal to main if error */
if ( (ofptr = fopen(argv[2], "w")) == NULL) {
printf("!!! Could not open file for output: %s\n", argv[2]);
printf("!!! Sending alarm to main process.\n");
kill(getppid(), SIGALRM);
}
/* Now we can begin to handle stream */
/* Rread until the signal char EOF is read from input */
/* For each buffer chunk, change each upper case to lower */
/* and each lower case to upper. Then write changed stream to */
/* output file. Calculate a ramdom time to wait. */
size = read(inpipe, buffer, 256);
buffer[size] = '\0';
while (buffer[0] != EOF) {
for (i = 0; i < size; i++) {
if ((buffer[i] >= 'a') && (buffer[i] <= 'z'))
buffer[i] = (buffer[i] - 'a' + 'A');
else if ((buffer[i] >= 'A') && (buffer[i] <='Z'))
buffer[i] = (buffer[i] - 'A' + 'a');
}
fputs(buffer, ofptr);
wait_val = ((int) (4.0*rand()/(RAND_MAX + 1.0)));
sleep(wait_val);
size = read(inpipe, buffer, 256);
buffer[size] = '\0';
}
/* Once pipe is 'empty' and main is still running */
/* display the EOF is found (this is several seconds */
/* after producer has found EOF) Send alarm signal to */
/* main (parent) process to simulate alarm */
printf("\n!!! Found end-of-file. Sending alarm to main process.\n");
kill(getppid(), SIGALRM);
/* now wait until this process gets 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 input */
/* but wait for signal to close and exit */
if (signo == SIGUSR1) {
printf("* Consumer 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) {
close(inpipe);
fclose(ofptr);
printf("** Consumer now exiting.\n");
exit(0);
}
}
/* Function to get 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;
}