Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

An adult (the gameOfficial ) lets some number of children take turns hitting a p

ID: 3591360 • Letter: A

Question

An adult (the gameOfficial) lets some number of children take turns hitting a pinata. With probability 1/20 (as computed by a pinata process) the pinata will bust, and the winning child get all the candy.

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:

Upon receipt of SIGINT the program should do:

and end.

Your pinata program must:

In main(), do:

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:

Explanation / Answer

#include <stdio.h>
#include <stdlib.h> //for rand() and srand()
#include <signal.h> // sigaction(), sigqueue()
#include <sys/types.h> //for pid_t data type
#include <unistd.h> //for getpid()
#include <sys/wait.h> //for waitpid()

/*********Handler for Pinata, call using kill or sigqueue from child process***********/

void sighandler(int sig, siginfo_t *info, void *extra)
{
if (sig == SIGUSR1)
{
int isBroken = (rand() % 20) == 19;
int signalToSend = (isBroken ? SIGUSR2 : SIGUSR1);
sigval pinataval;
pinataval.sival_int = 1; /* assign any extra data that you want to send. This value of 1 is just for example, it has no use in our case. */

/*send response back to child process using info->si_pid to get the pid of the process. This is possible if the child process had used kill or sigqueue to send the signal in the first place.*/

sigqueue(info->si_pid, signalToSend, pinataval); /* in the child method below use "info->si_value" to get the "pinataval" if needed.*/
}
else if (sig == SIGINT)
{
printf("Pinata stopping ");
fflush(stdout);
exit(0); //exit the program
}
}

/********** main function of pinata program**********/
int main(void)
{
srand(getpid()); // This seeds the random number generator

struct sigaction action;

// setting up the signal handler
action.sa_sigaction = &sighandler;

// trying to restart the system call and get extra info.
action.sa_flags = SA_RESTART | SA_SIGINFO;

/* while the handler is busy, it will block all subsequent signal calls. This is required because same handler is being used
for two signals here and we don't want to miss any. */
sigfillset(&action.sa_mask);

if (sigaction(SIGUSR1, &action, NULL) == -1) //returns -1 on error and 0 on success
{
printf("Error: SIGUSR1 cannot be handled.");
}

if (sigaction(SIGINT, &action, NULL) == -1) //returns -1 on error and 0 on success
{
printf("Error: SIGINT cannot be handled");
}

while(1)
{
sleep(1); // to let others have time slice of the CPU.
}

return 0;
}

/* PURPOSE: To reap all child processes that have already finished. Ignores
* parameters. No return value.
*/
void child (int sig,
siginfo_t* info,
void* data
)
{
int status;
pid_t finishedId;

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote