cis-452-lab-3/programming-assignment.c

152 lines
3.5 KiB
C
Raw Normal View History

2021-02-22 02:21:39 +00:00
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
/**************************************************************************
* Authors: Gary Fleming, Amber McCloughan
* Class: CIS452 - Operating Systems Concepts
* Professor: Dr. Greg Wolffe
* Date: 2/07/2019
*
* Program that forks off a child process and waits for it to send
* signals back. If the parent process receives a signal from the
* child, the signal handler tells the parent what to do.
*
* To end the program, do a Ctrl + C.
***************************************************************************/
// See comment above function definition.
void sigHandler(int);
/**
* Main function of program.
*/
int main()
{
// Seeding rand().
srand(time(NULL));
/*
* PID from fork, user signal number,
* and time to wait respectively.
*/
int pid, sig, waitTime;
// Forking off child process.
pid = fork();
// Error handling.
if (pid < 0)
{
fprintf(stderr, "ERROR with fork.\n");
exit(1);
// Child process code.
}
else if (!pid)
{
while (1)
{
/*
* Wait for random amount of time
* between 1 and 5 seconds.
*/
waitTime = (rand() % 5) + 1;
// Sleep for random time.
sleep(waitTime);
/*
* Randomly choose between SIGUSR1
* and SIGUS2.
*/
sig = (rand() % 2) + 1;
// SIGUSR1
if (sig == 1)
{
// Send the signal!
kill(getppid(), SIGUSR1);
}
// SIGUSR2
else
{
// Send the signal!
kill(getppid(), SIGUSR2);
}
}
}
// Saying which process was forked off.
printf("Spawned child PID %d.\n", pid);
// Binding signal handlers.
signal(SIGUSR1, sigHandler);
signal(SIGUSR2, sigHandler);
signal(SIGINT, sigHandler);
// Loop for waiting on signals.
while (1)
{
printf("Waiting...\n");
pause();
}
return 0;
}
/**
* Handler for signals. Binded for all three signals
* concerned in this application: SIGUSR1 (user-defined
* signal 1), SIGUSR2 (user-defined signal 2), and
* SIGINT (keyboard interrupt signal ^C). Depending
* on which signal is being handled (specified by
* sigNum), the handler will do different things.
* This is driven by the if-else statement.
*
* @param sigNum, the identifying number of the signal
* sent and now being handled. According to the
* man page for signal:
* SIGINT = 2
* SIGUSR1 = 30, 10, 16
* SIGUS2 = 31, 12, 17
*/
void sigHandler(int sigNum)
{
// If we're dealing with SIGUSR1.
if (sigNum == SIGUSR1)
{
// Saying it's SIGUSR1.
printf("Received a SIGUSR1 signal.\n");
// Binding signal handler again.
signal(SIGUSR1, sigHandler);
// Done handling.
return;
// If we're dealing with SIGUS2.
}
else if (sigNum == SIGUSR2)
{
// Saying it's SIGUSR2.
printf("Received a SIGUSR2 signal.\n");
// Binding signal handler again.
signal(SIGUSR2, sigHandler);
// Done handling.
return;
// If we're dealing with SIGINT (^C).
}
else if (sigNum == SIGINT)
{
// Exit message.
printf(" received. That's it, I'm shutting you down...\n");
// Exiting.
exit(0);
}
return;
}