-
Notifications
You must be signed in to change notification settings - Fork 0
/
executor.cpp
141 lines (132 loc) · 4.18 KB
/
executor.cpp
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
* Created by Misra Yavuz.
* Do not edit this program.
* Compile: g++ executor.cpp -o executor
* ./executor processNum instructionsPath
*/
#include <iostream>
#include <string>
#include <unistd.h>
#include <csignal>
#include <sstream>
#include <fstream>
#include <sys/stat.h>
#include <fcntl.h>
#include <map>
using namespace std;
map<string,int> sigMap;
bool finished=false;
int processNum;
string inputPath;
struct timespec delta = {0 /*secs*/, 300000000 /*nanosecs*/}; //0.3 sec
int main(int argc, char *argv[]) {
/*
* Map string of signal name to signal int.
*/
sigMap["SIGINT"] = SIGINT;
sigMap["SIGHUP"] = SIGHUP;
sigMap["SIGILL"] = SIGILL;
sigMap["SIGTRAP"] = SIGTRAP;
sigMap["SIGBUS"] = SIGBUS;
sigMap["SIGFPE"] = SIGFPE;
sigMap["SIGSEGV"] = SIGSEGV;
sigMap["SIGXCPU"] = SIGXCPU;
sigMap["SIGTERM"] = SIGTERM;
/*
* Get command line arguments. Expects 2 inputs, number of processes and a path to the instructions.txt file.
*/
processNum = stoi(argv[1]) ;
inputPath = argv[2];
pid_t pidList[processNum+1]; // Keep PID of watchdog at 0, PID of P1 at 1, ...
/*
* Create the named file (FIFO) under /tmp/myfifo directory.
* executor only reads the newly written PIDs from the pipe.
* Take a look at the example usage of named pipes for the watchdog part.
* (For ex., https://www.geeksforgeeks.org/named-pipe-fifo-example-c-program/)
*/
int unnamedPipe;
char * myfifo = (char*) "/tmp/myfifo";
mkfifo(myfifo, 0644);
char temp[30];
unnamedPipe = open(myfifo,O_RDONLY);
/*
* Read PIDs that are written by the watchdog.
* Format: "P# <pid>"
* Example: "P1 3564"
* P0 = watchdog, P1, P2, .... PN
*/
string p_index, p_pid;
int pid,id;
for (int i=0; i<=processNum; i++) {
read(unnamedPipe, temp, 30);
stringstream splitmsg(temp);
splitmsg >> p_index >> p_pid;
id = stoi(p_index.substr(1));
pid = stoi(p_pid);
pidList[id] = pid;
}
/*
* Read instructions from the input file.
*/
string inst, token1, token2;
int tempID, tempSig;
ifstream inst_file (inputPath);
if (inst_file.is_open()) {
while ( getline(inst_file, inst)){
stringstream splitline(inst);
splitline >> token1 >> token2 ;
/*
* If the instruction is a signal:
*/
if (token1.substr(0,3) == "SIG" ) {
tempID = stoi(token2.substr(1));
tempSig = sigMap.at(token1);
nanosleep(&delta, &delta); // Deal with writing delays
kill(pidList[tempID] , tempSig);
/*
* If SIGTERM is sent to head process, i.e., P1, read processNum amount of PIDs from pipe and update the list.
*/
if (tempID == 1 && tempSig == 15) {
for (int i= 1; i<=processNum; i++){
read(unnamedPipe, temp, 30);
stringstream splitmsg(temp);
splitmsg >> p_index >> p_pid;
id = stoi(p_index.substr(1));
pid = stoi(p_pid);
pidList[id] = pid;
}
}
/*
* If SIGTERM is sent to processes except P1, read only one PID from the pipe.
*/
else if (tempSig == 15){
read(unnamedPipe, temp, 30);
stringstream splitmsg(temp);
splitmsg >> p_index >> p_pid;
id = stoi(p_index.substr(1));
pid = stoi(p_pid);
pidList[id] = pid;
}
}
/*
* If the instruction is wait:
*/
else sleep(stoi(token2));
}
/*
* Instruction file is read completely.
*/
close(unnamedPipe);
finished = true;
}
/*
* Kill all processes and exit.
*/
if (finished) {
for (int i=0; i<=processNum; i++){
kill(pidList[i] , SIGTERM);
nanosleep(&delta, &delta);
}
return 0;
}
}