有人可以在检查fd [0]!= STDIN_FILENO之后解释使用dup2的原因,因为根据我的理解fd [0]!= STDIN_FILENO会失败而且dup2仍然会返回STDIN_FILENO以外的东西,只是试图了解一些示例代码谢谢,如果有人可以解释我对excelp的使用那将是非常棒的。
int fd[2];
pid_t pid;
if(argc != 2) {
fprintf(stderr, "Must be specify exactly 1 file\n");
exit(0);
}
if(pipe(fd) < 0)
exit(1);./
pid = fork();
switch (pid) {
case -1:
exit(1);
case 0:
close(fd[1]);
//here
if(fd[0] != STDIN_FILENO) {
if(dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)
exit(3);
close(fd[0]);
}
if(execlp("tr", "tr", "[a-z]", "[A-Z]", (char *) 0) < 0)
exit(4);
break;
default:
close(fd[0]);
// and here
if(fd[1] != STDIN_FILENO) {
if(dup2(fd[1], STDIN_FILENO) != STDIN_FILENO)
exit(5);
close(fd[1]);
}
if(execlp("cat", "cat", argv[1], (char *) 0) < 0)
exit(4);
break;
}
return 0;
答案 0 :(得分:2)
目的是使stdin(STDIN_FILENO,为0)指向fd [0]指向的文件(管道的读取侧)。首先检查它们是否已经相同...如果是,代码将重复0到0然后关闭0 - 不好。如果它们不相同,请使用dup2使STDIN_FILENO指向fd [0]指向的位置。如果dup2成功,它将返回其第二个参数,因此如果dup2失败,则通过调用退出该检查。
你写
根据我的理解fd [0]!= STDIN_FILENO会失败
为什么你“理解”这一点并不清楚。它仅在fd [0]包含STDIN_FILENO(即0)时失败,但由于它包含pipe
调用分配的文件描述符,因此不太可能。
dup2仍将返回STDIN_FILENO以外的其他内容
如果成功,dup2将返回其第二个参数。它除了失败之外不会返回STDIN_FILENO以外的东西 - 为什么会这样? - 在这种情况下,它返回-1。
答案 1 :(得分:1)
答案 2 :(得分:1)
对fd[0] != STDIN_FILENO
的检查是一种防御性编程实践,因为通常标准输入和标准输出先前已打开,但如果它们在您pipe()
调用之前已关闭,{{ 1}}会将两个描述符分配给管道(注意,当创建管道时,用于管道两端的文件描述符是下一个编号最小的描述符),因此检查将有意义。< / p>
答案 3 :(得分:0)
这个程序将在父进程中运行cat,并在子进程中运行tr,并且它希望通过tr读取cat的输出。
一开始,它打开一个管道,父级将写入fd [1],子级将从fd [0]读取,以便父级可以将数据写入子级。
在父母中,它将fd [1]复制到stdin;在孩子身上,它将fd [0]复制到stdin。
在child中,execlp运行tr,tr将从stdin读取,并且因为stdin已经被复制为fd [0],所以它实际上读取了cat从管道输出的内容。
execlp()
在当前进程中运行新的可执行文件。您可以man execlp
查询其详细信息。