Search code examples
c++pipefork

How to pass file back and foward between parent and children using pipe


I'm trying to open a file with the parent then, send it to the child. I want the child to look for specific word and send the line from the text file back to the parent.

With my Code right now, I can send the text file to the children but I cant check the file and send it back to the parent.

int fd[2];
pid_t cpid;

pipe(fd);
if ((cpid = fork()) == -1)
{
    cout << "ERROR" << endl;
    exit(1);
}

// child process
if (cpid == 0)
{
    // don't need the write-side of this
    close(fd[WRITE_FD]);

    std::string s;
    char ch;
    while (read(fd[READ_FD], &ch, 1) > 0)
    {
        if (ch != 0)
            s.push_back(ch);
        else
          {
            //std::cout << s << " "; //'\n'; //print the txt
            while(getline(s, ch, '.'))
            {
              printf("%s\n", toSend.c_str());
            }
            s.clear();
          }
    }

    // finished with read-side
    close(fd[READ_FD]);
}

// parent process
else
{
    // don't need the read-side of this
    close(fd[READ_FD]);

    fstream fileWords ("words.txt");
    string toSend;
    while (fileWords >> toSend)
    {
        // send word including terminator
        write(fd[WRITE_FD], toSend.c_str(), toSend.length()+1);
    }

    // finished with write-side
    close(fd[WRITE_FD]);
    wait(NULL);
}
return EXIT_SUCCESS;

Solution

  • Pipes are intended for unidirectional communication. If you try to use a pipe for bidirectional communication, it's almost certain that programs will end up reading their own output back into themselves (or similar undesired behavior), rather than successfully communicating with each other. There's two similar approaches that would work for bidirectional communication:

    1. Create two pipes, and give each process the read end of one and the write end of the other. Then there's no ambiguity about where data will end up.
    2. Use a socket instead of a pipe. The socketpair function makes this easy: just do socketpair(AF_UNIX, SOCK_STREAM, 0, fd) in place of pipe(fd). Sockets work just like pipes, but are bidirectional (writes to either of the FD's always get read by the other FD).