Repository navigation
Expand file tree
/
Copy pathdriver.cpp
More file actions
145 lines (116 loc) · 2.77 KB
/
Copy pathdriver.cpp
File metadata and controls
145 lines (116 loc) · 2.77 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
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
142
143
144
145
/*
* driver.cpp
*
* Created on: Jul 21, 2018
* Author: Ehsan Bateni
*/
#include<vector>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include<iostream>
/// Entry point of process A
int procA(void) {
// Process A writing to C
// std::cerr << "A is running"<<std::endl;
char* argv[2];
argv[0] = (char*) "ece650-a1.py";
argv[1] = NULL;
execv("a1.py", argv);
return 0;
}
/// Entry point of process B
int procB(void) {
// Process B writing to C
// std::cerr << "B is running"<<std::endl;
while (!std::cin.eof()) {
// read a line of input until EOL and store in a string
std::string line;
std::getline(std::cin, line);
if (line.size() > 0)
std::cout << line << std::endl;
}
// std::cout << "[B] saw EOF" << std::endl;
return 0;
}
/// Entry point of process C
int procC(void) {
// Process C reading from both A and B
// std::cerr << "C is running"<<std::endl;
char* argv[2];
argv[0] = (char*) "a2";
argv[1] = NULL;
execv("a2", argv);
return 0;
}
int procD(char** arg) {
// writing to A
// std::cout<<"starting procD(rgen)"<<std::endl;
// std::cerr << "D is running "<<std::endl;
execv("rgen", arg);
return 0;
}
int main(int argc, char **argv) {
// create a pipe
std::vector<pid_t> kids;
// create a pipe
int ABtoC[2], DtoA[2];
pipe(ABtoC);
pipe(DtoA);
pid_t child_pid;
child_pid = fork();
if (child_pid == 0) {
// redirect stdout to the pipe
dup2(ABtoC[1], STDOUT_FILENO);
close(ABtoC[0]);
close(ABtoC[1]); // Close this too!
// redirect stdin from another pipe
dup2(DtoA[0], STDIN_FILENO);
close(DtoA[1]);
// start process A
return procA();
} else if (child_pid < 0) {
std::cerr << "Error: could not fork" << std::endl;
return 1;
}
kids.push_back(child_pid);
child_pid = fork();
if (child_pid == 0) {
// redirect stdin from the pipe
dup2(ABtoC[0], STDIN_FILENO);
close(ABtoC[1]);
close(ABtoC[0]);
// start process C
return procC();
} else if (child_pid < 0) {
std::cerr << "Error: could not fork" << std::endl;
return 1;
}
kids.push_back(child_pid);
// redirect stdout to the pipe
child_pid = fork();
if (child_pid == 0) {
dup2(DtoA[1], STDOUT_FILENO);
close(DtoA[0]);
close(DtoA[1]);
return procD(argv);
} else if (child_pid < 0) {
std::cerr << "Error: could not fork" << std::endl;
return 1;
}
kids.push_back(child_pid);
child_pid = 0;
dup2(ABtoC[1], STDOUT_FILENO);
close(ABtoC[0]);
close(ABtoC[1]);
// start process B
int res = procB();
// send kill signal to all children
for (pid_t k : kids) {
int status;
kill(k, SIGTERM);
waitpid(k, &status, 0);
}
// exit with return code of process B
return res;
}