C++同时将输入和输出管道连接到外部程序

3
我正在尝试在程序中调用外部程序并检索其输出。它看起来像这样:(输入) | (外部程序) | (检索输出)。我最初考虑使用popen(),但似乎不可能,因为管道不是双向的。有没有在Linux中处理这种情况的简单方法?我可以尝试创建一个临时文件,但如果可以不访问磁盘就能清晰地处理它将会很好。有什么解决方案吗?谢谢。
1个回答

4
在Linux上,您可以使用pipe函数:打开两个新管道,一个用于每个方向,然后使用fork创建一个子进程,之后通常关闭未使用的文件描述符(父进程的读端,父进程发送到子进程的管道的写端,反之亦然),然后使用execve或其前端之一启动应用程序。
如果您将管道的文件描述符链接到标准控制台文件句柄(每个进程单独),则甚至可以使用std::cin/std::cout与其他进程通信(您可能只想为子进程这样做,因为您可能想保留父进程中的控制台)。不过我没有测试过,所以需要您自己尝试。

完成后,您需要使用waitwaitpid等待子进程终止。代码可能类似于以下示例:

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
    }
}

简而言之,将两个管道与分叉的子进程绑定,并使用execve函数将该子进程执行到目标外部程序? - Jaebum
这两个管道名称非常令人困惑。 - Pavan Manjunath
@PavanManjunath,它们应该是“Parent writing to(2) Child”和反之亦然的缩写... - Aconcagua

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接