我有以下程序(我的原始代码的修剪版本)以突出显示我正在观察的内容:
#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])。如果是这样,怎么样?
谢谢你, 艾哈迈德。