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.
#include <vector> #include <iostream> #include <signal.h> #include <unistd.h> #include <string> #include <sstream> /// Entry point of process B int procB(void) { // Process B writing to C 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 << std::endl; return 0; } int main(int argc, char** argv) { std::vector<pid_t> kids; // create a pipe int ABtoC[2]; pipe(ABtoC); int A1toA2[2]; pipe(A1toA2); 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(A1toA2[0]); close(A1toA2[1]); // Close this too! execv("./rgen", argv); } else if (child_pid < 0) { std::cerr << "Error: could not forkn"; 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]); close(A1toA2[0]); close(A1toA2[1]); argv[0] = (char *)"python3"; argv[1] = (char *)"a1ece650.py"; argv[2] = nullptr; dup2(A1toA2[1], STDOUT_FILENO); close(A1toA2[1]); close(A1toA2[0]); close(ABtoC[0]); close(ABtoC[1]); execvp("python3", argv); } else if (child_pid < 0) { std::cerr << "Error: could not forkn"; return 1; } kids.push_back(child_pid); child_pid = fork(); if (child_pid == 0) { // redirect stdin from the pipe dup2(A1toA2[0], STDIN_FILENO); close(A1toA2[1]); close(A1toA2[0]); close(ABtoC[0]); close(ABtoC[1]); execv("./ece650-a2", argv); } else if (child_pid < 0) { std::cerr << "Error: could not forkn"; return 1; } kids.push_back(child_pid); child_pid = 0; // redirect stdout to the pipe dup2(A1toA2[1], STDOUT_FILENO); close(A1toA2[0]); close(A1toA2[1]); 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); } return res; }
Insert ASCII graphics below:
+--------------+ +-----+ +-----+ +-----+ |Fork and Pipe| -- A.cpp stdout--stdin A1.py --stdout--stdin A2.cpp +--------------+. +-----+ +-----+ +-----+ ``` | | V V stdout stdout
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.