不会关闭管道的读取端导致"断管"在写结束

时间:2015-03-30 23:21:34

标签: linux pipe

我有以下程序(我的原始代码的修剪版本)以突出显示我正在观察的内容:

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <cassert>
#include <cstring>
using namespace std;

int main()
{
    for (uint32_t i = 0; i < 5; ++i) {
        int pipefd[2];
        char buff[64];
        FILE *cmd_output_fd;
        int rval;
        int pid, child_status;

        rval = pipe(pipefd);
        assert(rval == 0);
        cout << "Pipe : " << pipefd[0] << ", " << pipefd[1] << endl;

        pid = fork();
        assert(pid >= 0);

        if (pid == 0) {
            // Child process - exec cksum

            dup2(pipefd[1], STDOUT_FILENO);
            close(pipefd[0]);
            close(pipefd[1]);

            execlp("cksum", "cksum", "testout", nullptr);

            // If we are here, execlp() failed.
            assert(0);
            return 1;
        }

        close(pipefd[1]);

        // wait for child to finish up.
        wait(&child_status);
        if ((WIFEXITED(child_status)) && (WEXITSTATUS(child_status) != 0)) {
            std::cout << "cksum utility finished with error, exit status "
                      << WEXITSTATUS(child_status) << endl;
        }

        // If all is well, cksum has checksum of testout in it's stdout (pipefd[1])

        cmd_output_fd = fdopen(pipefd[0], "r");
        assert(cmd_output_fd != NULL);  // Error   (NOTE 1)

        if (fgets(buff, sizeof(buff), cmd_output_fd) == NULL) {
            assert(0);      // Error
        }
        fclose(cmd_output_fd);
    }

    return 0;
}

偶尔会遇到以下错误:

Pipe : 22, 24
cksum: write error: Broken pipe
cksum utility finished with error, exit status 1

当cksum实用程序遇到“Broken pipe”错误(1)时,cmd_output_fd为NULL(2)(在标记为注1的行中触发assert())。我的猜测是在遇到错误的循环期间,在fksum启动之前,pipefd [0](读取器端)以某种方式关闭。这可以解释两个观察结果 - cksum无法写入pipefd [0],而fdopen()失败。

如果我的假设是正确的,可能导致pipefd [0]关闭的原因是什么?

只是一个疯狂的猜测,这个问题可能是因为我没有在for循环结束时关闭(pipefd [0])。如果是这样,怎么样?

谢谢你, 艾哈迈德。

0 个答案:

没有答案