【发布时间】:2012-12-10 12:05:36
【问题描述】:
当我们使用 dup 将 STDOUT 重定向到管道时:
close(1); dup(fd[1]);
close(fd[0]);
close(fd[1]);
execlp("ls","-al",(char *) NULL);
但我们正在关闭管道的两端。那么如何将 STDOUT 写入管道?
【问题讨论】:
当我们使用 dup 将 STDOUT 重定向到管道时:
close(1); dup(fd[1]);
close(fd[0]);
close(fd[1]);
execlp("ls","-al",(char *) NULL);
但我们正在关闭管道的两端。那么如何将 STDOUT 写入管道?
【问题讨论】:
在示例代码中,您没有关闭管道的两端。您正在关闭 fd[0] 和 fd[1]。最初,关闭这些就足以关闭管道的两端,但这不是在您复制 fd[0] 之后。您还必须关闭重复的 fd 才能关闭对管道的所有引用。不过那会很愚蠢:您要精确地保持一个末端打开,以便 ls 可以写入。
也许你的困惑是关于close() 正在关闭?它关闭 fd,即对管道末端之一的引用。它不会关闭管道本身:这就是shutdown() 会做的事情。 (如果你不调用shutdown,当引用它的每个fd都关闭时,管道会自动关闭。)所以,因为复制的fd仍然打开,进程可以写入管道(它没有关闭,因为三个对它的引用中只有两个被关闭)。
【讨论】:
因为一旦文件描述符编号 1(例如标准输出)关闭,该编号可用于进一步的 dup 或 open 调用。
您应该检查close 和dup 系统调用的结果。
当然,关闭管道的两端是没有意义的,除非你之前做过一些有用的事情(即在适当的末端读取或写入)。
请参阅 open(2)、dup(2)、pipe(2)、close(2) 手册页。阅读Advanced Linux Programming 书。
【讨论】: