-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsigHandler.c
More file actions
116 lines (70 loc) · 3.43 KB
/
sigHandler.c
File metadata and controls
116 lines (70 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "eggshell.h"
pid_t suspendedPids[MAX_SUSPENDED]; //initializes stack-like array for suspended processes
int topOfTheStack = -1;
//resumes the last suspended process
void resumeSuspended(int resumeTo){
if(topOfTheStack == -1){
printf("Currently no suspended processes found! Can't resume what isn't paused\n");
addVar("EXITCODE","-1"); //exit code to -1, as error occurred
return;
}else{
//fprintf(stdout, "Process Group: : %d\n", getpgid(current_pid));
current_pid = suspendedPids[topOfTheStack]; //pulls pid at the top of the suspended pids Stack
kill(current_pid, SIGCONT); //sends SIGCONT to resume last suspended pid
//fprintf(stdout, "Pulled Stack ID: : %d\n", topOfTheStack);
//fprintf(stdout, "PID on resume: : %d\n", current_pid);
suspendedPids[topOfTheStack] = 0; //set previous top to nothing
topOfTheStack--; //decrements stack top
//if resumed to foreground
if(resumeTo == 1) {
int status;
if(waitpid(current_pid, &status, WUNTRACED) < 0){ //waits for the child process to terminate
perror("Error: An error occurred whilst waiting for the child process.\n");
addVar("EXITCODE","-1"); //exit code to -1, as error occurred
return;
};
//if exited normally
if (WIFEXITED(status)) {
addVar("EXITCODE","0"); //reaches here when program executes command successfully, therefore stores 0 as EXITCODE
return;
}
else if(status == -1){ //if exited with failure case
printf("Error: A problem went wrong in the child process during parsing external command.\n");
addVar("EXITCODE","-1"); //exit code to -1, as error occurred
return;
}
else if(WEXITSTATUS(status)){ //if exited abnormally
printf("Exited with status %d.\n",WEXITSTATUS(status));
return;
}
}
//if resumed to background
else if(resumeTo == 0) {//doesn't wait therefore resumes in background
}
}
}
//on signal recognition, sends the signal to the current process id
void signalHandler(int signo){
fprintf(stdout,"\n"); //prints new line safely to the terminal
//if SIGINT is received
if(signo == SIGINT){
kill(current_pid, SIGINT); //sends SIGINT to interrupt current pid
}
//if SIGTSTP is received
else if(signo == SIGTSTP){
topOfTheStack++; //increments stack top
suspendedPids[topOfTheStack] = current_pid; //pushes the current process id
kill(current_pid, SIGTSTP); //sends SIGTSTP to interrupt current pid
//fprintf(stdout, "Pushed Stack ID: : %d\n", topOfTheStack);
//fprintf(stdout, "PID on pause: : %d\n", current_pid);
}
}
void checkForSignals(void){
struct sigaction sa; //initialize sigaction struct
sa.sa_handler = signalHandler; //sets handler to the above signalHandler method
sigemptyset(&sa.sa_mask); //initializes additional set of signals to be blocked during signalHandler()
sa.sa_flags = SA_RESTART; //restarts function if interrupted by handler
//creates signal handlers for CTRL+C and CTRL+Z
if(sigaction(SIGINT, &sa, NULL) == -1) printf("Error: Couldn't trap CTRL+C\n");
if(sigaction(SIGTSTP, &sa, NULL) == -1) printf("Error: Couldn't trap CTRL+Z\n");
}