简体   繁体   中英

C++ both input and output pipe to the external program

I am trying to invoke external program with some input and retrieve the output from it within a program.

It will be look like;

(some input) | (external program) | (retrieve output)

I first thought about using a popen() but it seems like, it is not possible because the pipe is not bidirectional .

Is there any easy way to handle this kind of stuff in linux ?

I can try making a temp file but it will be great if it can be handled clearly without accessing the disk.

Any Solution? Thanks.

On linux you can use pipe function: Open two new pipes, one for each direction, then create a child process using fork , afterwards, you typically close the file descriptors not in use (read end on parent, write end on child of the pipe for parent sending to child and vice versa for the other pipe) and then start your application using execve or one of its front ends.

If you dup2 the pipes' file descriptors to the standard console file handles ( STDIN_FILENO / STDOUT_FILENO ; each process separately), you should even be able to use std::cin / std::cout for communicating with the other process (you might want to do so only for the child, as you might want to keep your console in parent). I have no tested this, though, so that's left to you.

When done, you'd yet wait or waitpid for your child process to terminate. Might look like similar to the following piece of code:

int pipeP2C[2], pipeC2P[2];
// (names: short for pipe for X (writing) to Y with P == parent, C == child)

if(pipe(pipeP2C) != 0 || pipe(pipeC2P) != 0)
{
    // error
    // TODO: appropriate handling
}
else
{
    int pid = fork();
    if(pid < 0)
    {
        // error
        // TODO: appropriate handling
    }
    else if(pid > 0)
    {
        // parent
        // close unused ends:
        close(pipeP2C[0]); // read end
        close(pipeC2P[1]); // write end

        // use pipes to communicate with child...

        int status;
        waitpid(pid, &status, 0);

        // cleanup or do whatever you want to do afterwards...
    }
    else
    {
        // child
        close(pipeP2C[1]); // write end
        close(pipeC2P[0]); // read end
        dup2(pipeP2C[0], STDIN_FILENO);
        dup2(pipeC2P[1], STDOUT_FILENO);
        // you should be able now to close the two remaining
        // pipe file desciptors as well as you dup'ed them already
        // (confirmed that it is working)
        close(pipeP2C[0]);
        close(pipeC2P[1]);

        execve(/*...*/); // won't return - but you should now be able to
                         // use stdin/stdout to communicate with parent
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM