SICE Curriculum Portal for Thomas Heffron
Contents

Home
UMKC Curriculum
   FS '96
      CS 101
   SS '01
      CS 201
   FS '01
      CS 191
      CS 281
   WS '02
      CS 291
      EN 304wi
   SS '02
      CS 352
      CS 481
   FS '02
      CS 431
      CS 441
   WS '03
      CS 423
      CS 451
SICE Survival Guide
Personal Experience

contact me @umkc:
tehqnf@umkc.edu

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;
}