Fork-exec 管道重定向问题
谁能告诉我这段代码有什么问题吗?
总之,它创建输入和输出管道以及 fork-exec 的 sort
程序。父级读取字典 /usr/share/dict/words
并将其写入通过 dup2()
'd to sort
' 的管道s 标准输入,同样,读取它的输出,将其打印到终端(父级的标准输出)。或者,至少,这就是应该发生的事情。
回溯表明父进程挂在第 130 行的 read()
处(用注释“XXX”标记)。几乎就像 sort
不知道文件结尾,但关闭 pipeIn
的写入端应该“发出信号”,对吧?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char** argv)
{
int pipeIn[2];
int pipeOut[2];
if ((pipe(pipeIn)) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
if ((pipe(pipeOut)) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
pid_t child = fork();
if (child == 0)
{
// This is child!
if ((dup2(pipeIn[0], STDIN_FILENO)) == -1)
{
perror("dup2");
exit(EXIT_FAILURE);
}
if ((dup2(pipeOut[1], STDOUT_FILENO)) == -1)
{
perror("dup2");
exit(EXIT_FAILURE);
}
if ((dup2(pipeOut[1], STDERR_FILENO)) == -1)
{
perror("dup2");
exit(EXIT_FAILURE);
}
if ((close(pipeIn[0])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
if ((close(pipeOut[1])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
if ((execlp("sort", "-r", NULL)) == -1)
{
perror("execlp");
exit(EXIT_FAILURE);
}
}
else if (child == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
else
{
// This is parent!
if ((close(pipeIn[0])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
if ((close(pipeOut[1])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
int dict = open("/usr/share/dict/words", O_RDONLY);
if (dict == -1)
{
perror("open");
exit(EXIT_FAILURE);
}
char buf[1024];
int count;
while ((count = read(dict, buf, sizeof(char) * 1024)) > 0)
{
putchar('.');
if ((write(pipeIn[1], buf, count)) == -1)
{
perror("write 1");
exit(EXIT_FAILURE);
}
}
if (count == -1)
{
perror("read");
exit(EXIT_FAILURE);
}
if ((close(dict)) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
if ((close(pipeIn[1])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
while ((count = read(pipeOut[0], buf, sizeof(char) * 1024)) > 0) // XXX
{
putchar('!');
if ((write(STDOUT_FILENO, buf, count)) == -1)
{
perror("write 2");
exit(EXIT_FAILURE);
}
}
if (count == -1)
{
perror("read");
exit(EXIT_FAILURE);
}
if ((close(pipeOut[0])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
}
return EXIT_SUCCESS;
}
感谢您的任何意见(请原谅双关语)。
Could anyone tell me what's wrong with this code?
In summary, it creates input and output pipes and fork-exec's the sort
program. The parent reads the dictionary /usr/share/dict/words
and writes it to the pipe that is dup2()
'd to sort
's standard in and, likewise, reads the output from it, printing it to the terminal (the standard output of the parent). Or, at least, that's what's supposed to be happening.
A backtrace says that the parent hangs at the read()
on line 130 (marked with the comment 'XXX'). It's almost as though sort
isn't aware of the end-of-file, but closing the write end of pipeIn
should 'signal' this, right?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char** argv)
{
int pipeIn[2];
int pipeOut[2];
if ((pipe(pipeIn)) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
if ((pipe(pipeOut)) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
pid_t child = fork();
if (child == 0)
{
// This is child!
if ((dup2(pipeIn[0], STDIN_FILENO)) == -1)
{
perror("dup2");
exit(EXIT_FAILURE);
}
if ((dup2(pipeOut[1], STDOUT_FILENO)) == -1)
{
perror("dup2");
exit(EXIT_FAILURE);
}
if ((dup2(pipeOut[1], STDERR_FILENO)) == -1)
{
perror("dup2");
exit(EXIT_FAILURE);
}
if ((close(pipeIn[0])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
if ((close(pipeOut[1])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
if ((execlp("sort", "-r", NULL)) == -1)
{
perror("execlp");
exit(EXIT_FAILURE);
}
}
else if (child == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
else
{
// This is parent!
if ((close(pipeIn[0])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
if ((close(pipeOut[1])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
int dict = open("/usr/share/dict/words", O_RDONLY);
if (dict == -1)
{
perror("open");
exit(EXIT_FAILURE);
}
char buf[1024];
int count;
while ((count = read(dict, buf, sizeof(char) * 1024)) > 0)
{
putchar('.');
if ((write(pipeIn[1], buf, count)) == -1)
{
perror("write 1");
exit(EXIT_FAILURE);
}
}
if (count == -1)
{
perror("read");
exit(EXIT_FAILURE);
}
if ((close(dict)) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
if ((close(pipeIn[1])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
while ((count = read(pipeOut[0], buf, sizeof(char) * 1024)) > 0) // XXX
{
putchar('!');
if ((write(STDOUT_FILENO, buf, count)) == -1)
{
perror("write 2");
exit(EXIT_FAILURE);
}
}
if (count == -1)
{
perror("read");
exit(EXIT_FAILURE);
}
if ((close(pipeOut[0])) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
}
return EXIT_SUCCESS;
}
Thank you for any input (pardon the pun).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题是您没有在智利过程中关闭管道未使用的末端。因此,您需要在
exec
之前的某个位置添加以下代码Your problem is that you are not closing the unused ends of your pipe in the chile process. So you need to add the following code somewhere before the
exec