QuestionQuestion

In this assignment we'll make 3 programs:

A pinata program that waits until it receives SIGUSR1. It will then
send SIGUSR1 with probability 19/20, or
send SIGUSR2 with probability 1/20
to the process that signalled it.
A child program who hits the pinata.
It waits for its parent process (the gameOfficial) to send it SIGUSR1 and tell the child that it is that child's turn.
It then sends SIGUSR1 to the pinata-processes.
If it gets back SIGUSR1 it knows it failed to break the pinata, and it sends SIGUSR1 back to the gameOfficial.
However, if it gets back SIGUSR2 is knows it did break the pinata, and it sends SIGUSR2 back to the gameOfficial.
A gameOfficial program.
It asks the user for:
the number of pinata-whacking children to make
It makes all the processes
It regulates the game, and
It tells the processes to end after the game is finished.
Assignment:
pinata.c
The pinata's job is to wait for a child to whack it and/or to wait to be told to stop:

Children whack the pinata by sending it SIGUSR1.
The gameOfficial tells the pinata to stop by sending SIGINT.
Upon receipt of SIGUSR1 the pinata sees if it broke:

There is a 19/20 chance that the pinata survives, this causes SIGUSR1 to be sent back to the sender.
There is a 1/20 chance that the pinata breaks, this causes SIGUSR2 to be sent back to the sender.
Hint: This code might be useful:
int isBroken = (rand() % 20) == 19;
int signalToSend = (isBroken ? SIGUSR2 : SIGUSR1);
Upon receipt of SIGINT the program should do:

printf("Pinata stopping\n");
fflush(stdout);
and end.
Your pinata program must:

In main(), do:
srand(getpid()); // This seeds the random number generator
      
Install a signal handler for SIGINT that causes the program to end. This signal handler should printf() a message that the pinata process is ending.
Install a signal handler for SIGUSR1. The signal handler should see if the pinata broke by computing (rand() % 20) == 19.
If it is true then the pinata did break and SIGUSR2 should be sent back to the sender.
If it is false then the pinata survived and SIGUSR1 should be sent back to the sender.
While the pinata is waiting to be signal()-ed it should not be doing much of anything. It should run code like:
while (shouldRun)
sleep(1);
child.c
The child's job is to wait for signal numbered SIGUSR1 from its parent (the gameOfficial) This means it is its turn.

Then the child sends the signal SIGUSR1 to the pinata process.

If the child receives SIGUSR1 (from the pinata) that means it did not bust the pinata. It printf()-s a message of disappointment, and sends SIGUSR1 to its parent say that it has not yet won.

If the child receives SIGUSR2 (from the pinata) that means it did bust the pinata. It printf()-s a boastful message, and sends SIGUSR2 to its parent say that it has won.

Your child program must:

In main(), do:
srand(getpid()); // This seeds the random number generator
      
Check that there are 3 arguments total on the command line (the program's name and 2 others). If there are not then do:
fprintf(stderr,"Usage: %s <pinataPid> <childNum>\n",
argv[0]
       );
exit(EXIT_FAILURE);
Install a signal handler for signal SIGINT to be told when to quit. This signal handler should printf() a message that the child process is ending and actually stop the program.
Install a signal handler for signal SIGUSR1.
If this signal comes from its parent then it should printf() a message that acknowledges that it is its turn and it should send SIGUSR1 to the pinata.
If this signal comes from the pinata process then it should printf() a message of disappointment and send signal SIGUSR1 to its parent (the gameOfficial).
Install signal handlers for signal SIGUSR2. This handler should printf() a boastful message and send signal SIGUSR2 to its parent (the gameOfficial).
While the child is waiting to be signal()-ed it should not be doing much of anything. It should run code like:
while (shouldRun)
sleep(1);
gameOfficial.c
The gameOfficial's job is to ask for the number of children, launch the pinata process, launch the desired number of children, and then regulate the game.

After one of the children has reported that it has won then it should send SIGINT to the pinata and all children processes. It should also reap them with waitpid().

Your gameOfficial program must:

In a loop get a valid number for numChildren (greater than 0).
Install a SIGCHLD signal handler. This handler should have a while loop that does a non-hanging waitpid() that detects whether or not a child process (including pinata process) has ended. If it has it should print that process's PID and whether or not it ended successfully or crashed.
Install SIGUSR1 signal handler turnOver(). This function tells the gameOfficial that the current child has finished its turn, but that the game has not yet finished.
Install SIGUSR2 signal handler turnOverStopGame(). This function tells the gameOfficial both that the current child has finished its turn and that the game has finished.
Have a loop that regulates which child's turn it is. The loop sends SIGUSR1 to the current child.
After the above loop, have code that sends SIGINT to all child processes (including the pinata process)

Solution PreviewSolution Preview

These solutions may offer step-by-step problem-solving explanations or good writing examples that include modern styles of formatting and construction of bibliographies out of text citations and references. Students may use these solutions for personal skill-building and practice. Unethical use is strictly forbidden.

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

int shouldRun = 1;
int isWaitingForPinata;
pid_t parentPid;
pid_t pinataPid;
int childNum;

void sigint_handler(int sig);
void sigusr1_handler(int signum, siginfo_t *info, void *context);
void sigusr2_handler(int signum);

int main(int argc, char **argv){

if(argc != 3){
fprintf(stderr,"Usage: %s <pinataPid> <childNum>\n", argv[0]);
exit(EXIT_FAILURE);
}
else{
pinataPid = atoi(argv[1]);
childNum = atoi(argv[2]);
parentPid = getppid();
}

// Setting the SIGINT signal handler
struct sigaction sa;
sa.sa_handler = sigint_handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
if(sigaction(SIGINT, &sa, NULL) == -1) {
    perror("sigaction");
    exit(1);
}

// Setting the SIGUSR1 signal handler.
struct sigaction su1;
su1.sa_flags...

By purchasing this solution you'll be able to access the following files:
Solution.zip.

$60.00
for this solution

PayPal, G Pay, ApplePay, Amazon Pay, and all major credit cards accepted.

Find A Tutor

View available C-Family Programming Tutors

Get College Homework Help.

Are you sure you don't want to upload any files?

Fast tutor response requires as much info as possible.

Decision:
Upload a file
Continue without uploading

SUBMIT YOUR HOMEWORK
We couldn't find that subject.
Please select the best match from the list below.

We'll send you an email right away. If it's not in your inbox, check your spam folder.

  • 1
  • 2
  • 3
Live Chats