Removed submodules
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "signals.h"
|
||||
|
||||
static void catch_loop (int);
|
||||
|
||||
/* Convert the short signal name (NNN part of SIGNNN) to its number.
|
||||
Consult /usr/include/asm/signal.h for the number mappings. For
|
||||
this lab, hard-code the numbers; do not use the numeric constants.
|
||||
Return -1 if the name isn't one you need to look up. */
|
||||
int
|
||||
signal_lookup (char *name)
|
||||
{
|
||||
// TODO: Look up the numbers for INT, SEGV, KILL, and TSTP
|
||||
if (strcmp (name, "INT") == 0)
|
||||
return 2;
|
||||
if (strcmp (name, "SEGV") == 0)
|
||||
return 11;
|
||||
if (strcmp (name, "KILL") == 0)
|
||||
return 9;
|
||||
if (strcmp (name, "TSTP") == 0)
|
||||
return 20;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Entry point for overriding a signal handler in this lab.
|
||||
void
|
||||
override (char *signal)
|
||||
{
|
||||
int sig = signal_lookup (signal);
|
||||
if (sig == SIGKILL)
|
||||
printf ("Received bad signal name: %s\n", signal);
|
||||
else
|
||||
catch_loop (sig);
|
||||
}
|
||||
|
||||
// Generic signal handler. This function doesn't use the signal number
|
||||
// in the provided distribution.
|
||||
void
|
||||
sig_handler (int signum __attribute__ ((unused)))
|
||||
{
|
||||
// TODO: Complete this signal handler so that it writes the message
|
||||
// "Breaking out with signal %d\n" with the signal number that was
|
||||
// passed. Note that you cannot use printf() in a signal handler.
|
||||
// You must use write(). After writing the message, exit with return
|
||||
// code 37.
|
||||
//
|
||||
// HINT: If you fail integration tests and get a message that the
|
||||
// binary files are different, you may be writing an extra byte (the
|
||||
// null byte). You can make sure you avoid this by using strlen()
|
||||
// instead of trying to hard-code a length.
|
||||
char buf[128];
|
||||
snprintf (buf, 128, "Breaking out with signal %d\n", signum);
|
||||
write (STDOUT_FILENO, buf, strlen (buf));
|
||||
exit (37);
|
||||
}
|
||||
|
||||
void
|
||||
catch_loop (int signum)
|
||||
{
|
||||
// sigaction(signum)
|
||||
// TODO: Override the signal handler for the signal number passed.
|
||||
// Then create a child that runs the following code:
|
||||
// prctl (PR_SET_PDEATHSIG, SIGKILL);
|
||||
// printf ("Child has started\n");
|
||||
// fflush (stdout);
|
||||
// while (1) ;
|
||||
|
||||
struct sigaction sa = { 0 };
|
||||
sa.sa_handler = sig_handler;
|
||||
|
||||
sigaction (signum, &sa, NULL);
|
||||
|
||||
pid_t pid = fork ();
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
prctl (PR_SET_PDEATHSIG, SIGKILL);
|
||||
printf ("Child has started\n");
|
||||
fflush (stdout);
|
||||
while (1)
|
||||
pause ();
|
||||
}
|
||||
|
||||
// HINT: You will NOT call sig_handler() directly here. Instead,
|
||||
// you must use sigaction() to modify the signal's interrupt handler
|
||||
// so that sig_handler() will be called later when the signal occurs.
|
||||
|
||||
// After starting the child, the parent will call sleep (1) to wait
|
||||
// for 1 second before sending the signal to the child. The parent
|
||||
// must wait for the child to run (and exit), then print
|
||||
// "Child was stopped with status %d\n" with the child process's exit
|
||||
// status code, retrieved with waitpid(). Note that you will need to
|
||||
// call WEXITSTATUS() on the retrieved status code.
|
||||
|
||||
sleep (1);
|
||||
|
||||
int status = 0;
|
||||
kill (pid, signum);
|
||||
waitpid (pid, &status, 0);
|
||||
printf ("Child was stopped with status %d\n", WEXITSTATUS (status));
|
||||
}
|
||||
Reference in New Issue
Block a user