Skip to content
Advertisement

Forks and Pipes in c++

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.

  1. 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
  2. 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.
  3. 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 dups first, and then close what you don’t need.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement