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 #4
 
/********************************
Name:     Thomas Heffron (tehqnf@umkc.edu)
Section:  CS431 NET
Program:  Program #4
Due Date: Oct. 31, 2002
Desc:     Write a program that spawns multiple
          processes and terminates after a period
          of time using the alarm signal handler.
Inputs:   Cmd arguments given for number of
          threads to create and duration of
          main process.
Outputs:  Timestamp showing beginning of main proc.
          Indication of creation of additional procs.
          Work function will show each major work loop.
          Timestamp showing termination of main proc.
********************************/

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>

extern char **environ;
extern int errno;

/* Type Definitions used by all functions */
typedef struct pid_mem {
    pid_t this_pid;
    struct pid_mem *next;
} PID_LIST;
PID_LIST *temp_ptr;
PID_LIST *ptr_to_list = NULL;

/* Function declarations */
static void sig_alarm(int signo);

int main(int argc, char *argv[])
{
/* Variable declarations */
    int num_procs, proc_duration, proc_no;
    char procname[128];
    time_t now;
    pid_t pid;

    if (argc == 4) { /* Check for correct number of args */
        num_procs = atoi(argv[1]); /* translate cmd args */
        proc_duration = atoi(argv[2]);
        strcpy(procname, argv[3]);
        time(&now);
        printf("Signal handler started at %s", ctime(&now));
        if (signal(SIGALRM, sig_alarm) == SIG_ERR) { /* define signal catch */
            printf("The signal function returned an error\n");
            exit(1);
        }
        printf("Setting alarm to end process in %d seconds.\n",
              proc_duration);
        alarm(proc_duration); /* set alarm */
        proc_no = 1; /* initialize proc count to one and */
        while (proc_no <= num_procs) { /* create requested procs */
            pid = fork(); /* fork() for each requested process */
            if (pid == 0) { /* If child proc run execve() */
                if (execve(procname, NULL, environ ) == -1) {
                    printf("ERROR IN EXECVE ");
                    perror("execve");
                }
            } else { /* we are in main proc and must keep track of the processes*/
                printf("\nCREATED PROCESS %d\n", pid);
                /* For every new process we must allocate
                /* memory to hold its information and keep
                /* it in a linked list of all processes. */
                temp_ptr = (PID_LIST *) malloc (sizeof (PID_LIST));
                temp_ptr -> this_pid = pid;
                temp_ptr -> next = ptr_to_list;
                ptr_to_list = temp_ptr; /* Update list pointer to new member */
                proc_no++;
            }
        }
        while (1); /* main process must cycle - sig_alarm will call exit() */
    } else {
        printf("Usage: %s num_procs proc_duration exter_proc\n", argv[0]);
        exit(1);
    }
}

static void sig_alarm(int signo)
{
    alarm(0); /* Reset alarm */
    printf("\n*** Alarm to end process ***\n");
    printf("TERMINATING THE PROCESSES...\n\n");
    /* Now we must run the linked list
    /* and issue the kill() signal to
    /* each process that we created. */
    while (ptr_to_list != NULL) {
        printf("Killing process with pid = %d\n", ptr_to_list -> this_pid);
        kill(ptr_to_list -> this_pid, 9);
        temp_ptr = ptr_to_list;
        ptr_to_list = ptr_to_list -> next; /* Make sure to update list pointer */
        free(temp_ptr); /* and free memory */
    }
    printf("\nTerminating main process\n");
    exit(0);
}