I am using 4 processes in which A’s output will goto A1 and A1’s output will go to A2 and A2 output will come out in the console. Even A1 output also will comeout in console.
- 1st program – A C++ program which is a random generator that will generate the output as per the requirements of A1’s input and also act as a collector for
stdout
from the sub processes - 2nd program – Python script which will take the input of A’s output and will generate the output as per the requirements of A2 and the output of A1 should print in the console.
- 3rd program – cpp file which will take the input of A1’s output and will give the output and print in the control.
I am using 2 pipes – ABtoC for A to A1, A1toA2 for A1toA2.
Here A to A1 is working and A1’s output is printing in the console. But the issue is A1’s output is not going to A2’s input. Here is the below code I am using for this operation.
JavaScript
x
120
120
1
#include <vector>
2
3
#include <iostream>
4
#include <signal.h>
5
#include <unistd.h>
6
#include <string>
7
#include <sstream>
8
9
/// Entry point of process B
10
int procB(void) {
11
// Process B writing to C
12
while (!std::cin.eof()) {
13
// read a line of input until EOL and store in a string
14
std::string line;
15
std::getline(std::cin, line);
16
if (line.size() > 0)
17
std::cout << line << std::endl;
18
}
19
std::cout << std::endl;
20
return 0;
21
}
22
23
int main(int argc, char** argv) {
24
std::vector<pid_t> kids;
25
// create a pipe
26
int ABtoC[2];
27
pipe(ABtoC);
28
29
int A1toA2[2];
30
pipe(A1toA2);
31
32
33
34
pid_t child_pid;
35
child_pid = fork();
36
if (child_pid == 0) {
37
// redirect stdout to the pipe
38
dup2(ABtoC[1], STDOUT_FILENO);
39
close(ABtoC[0]);
40
close(ABtoC[1]);
41
close(A1toA2[0]);
42
close(A1toA2[1]); // Close this too!
43
44
execv("./rgen", argv);
45
} else if (child_pid < 0) {
46
std::cerr << "Error: could not forkn";
47
return 1;
48
}
49
50
51
kids.push_back(child_pid);
52
53
child_pid = fork();
54
if (child_pid == 0) {
55
// redirect stdin from the pipe
56
dup2(ABtoC[0], STDIN_FILENO);
57
close(ABtoC[1]);
58
close(ABtoC[0]);
59
close(A1toA2[0]);
60
close(A1toA2[1]);
61
62
argv[0] = (char *)"python3";
63
argv[1] = (char *)"a1ece650.py";
64
argv[2] = nullptr;
65
66
67
dup2(A1toA2[1], STDOUT_FILENO);
68
close(A1toA2[1]);
69
close(A1toA2[0]);
70
close(ABtoC[0]);
71
close(ABtoC[1]);
72
execvp("python3", argv);
73
74
} else if (child_pid < 0) {
75
std::cerr << "Error: could not forkn";
76
return 1;
77
}
78
79
kids.push_back(child_pid);
80
81
child_pid = fork();
82
if (child_pid == 0) {
83
// redirect stdin from the pipe
84
dup2(A1toA2[0], STDIN_FILENO);
85
close(A1toA2[1]);
86
close(A1toA2[0]);
87
close(ABtoC[0]);
88
close(ABtoC[1]);
89
90
execv("./ece650-a2", argv);
91
92
} else if (child_pid < 0) {
93
std::cerr << "Error: could not forkn";
94
return 1;
95
}
96
97
98
kids.push_back(child_pid);
99
child_pid = 0;
100
101
// redirect stdout to the pipe
102
dup2(A1toA2[1], STDOUT_FILENO);
103
close(A1toA2[0]);
104
close(A1toA2[1]);
105
close(ABtoC[0]);
106
close(ABtoC[1]);
107
108
// start process B
109
int res = procB();
110
111
// send kill signal to all children
112
for (pid_t k : kids) {
113
int status;
114
kill(k, SIGTERM);
115
waitpid(k, &status, 0);
116
}
117
118
return res;
119
}
120
Insert ASCII graphics below:
JavaScript
1
7
1
+--------------+ +-----+ +-----+ +-----+
2
|Fork and Pipe| -- A.cpp stdout--stdin A1.py --stdout--stdin A2.cpp
3
+--------------+. +-----+ +-----+ +-----+
4
``` | |
5
V V
6
stdout stdout
7
Advertisement
Answer
When you launch A1, you are closing A1toA2[1]
and then after that trying to dup
it into stdout. Do all of the dup
s first, and then close what you don’t need.