我分叉并设置如下命令:
pid_t pid;
pid = fork();
if (pid == 0)
{ // I am the child
freopen("/input_pipe","r",stdin);
freopen("/output_pip","w",stdout);
execl("/bin/sh", "sh", "-c", command, (char *)NULL); // using execv is probably faster
// Should never get here
perror("execl");
exit(1);
}
在分叉进程之前,已经创建了/ input_pipe并填充了数据。
这在几乎所有情况下都适用。该命令从其stdin读取(带有read()
)并获取由另一个进程写入管道的数据。
但有时命令无法从其stdin流中读取并在尝试时出现“Bad file descriptor”错误。
什么可能导致此错误?
编辑:我已将freopen部分更改为:
pipe_in = open(pipename_in, O_RDONLY);
pipe_out = open(pipename_out, O_WRONLY);
dup2(pipe_in, 0);
dup2(pipe_out, 1);
我会测试这几天,因为错误只是很少出现。
答案 0 :(得分:4)
问题的一个可能来源是" stdin" " stdout"不必分别对应文件描述符0和1。在运行时库的许多实现中,freopen可以更改属于FILE *的文件描述符。文件描述符属于内核,而FILE属于运行时库,它们不一定是对齐的。
请看这里:
http://man7.org/linux/man-pages/man3/stdout.3.html
"将freopen(3)应用于其中一个流可以更改与流关联的文件描述符编号"
在execl之后,子进程只期望文件描述符0和1是标准输入和输出,但是可能发生freopen关闭fd 0并且连接另一个fd到(FILE *)stdin。 我建议你使用"打开","关闭"," dup" etc ...系统调用并直接处理文件描述符0和1(或者更好的是,标准宏STDIN_FILENO和STDOUT_FILENO)。