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