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