CSAPP e10.9

仔细考虑这条命令:linux> fstatcheck 3 < foo.txt

如果经过一点思考,可能会产生这样错误的结论:shell 打开 foo.txt 并分配了文件描述符 3。使用 fork 和 execve 创建了子进程 fstatcheck,它具有与 shell 相同的文件描述符表,即 3 同样引用 foo.txt。因此 fstatcheck 使用 Fstat 获取 foo.txt 的元数据。

但事与愿违,具体的伪代码如下:

1
2
3
4
5
6
7
if (fork() == 0) {
int fd = open(filename, O_RDONLY); // Open the file
close(0); // Close old stdin
dup2(fd, 0); // Copy fd as new stdin
close(fd); // Close the original fd
execve("fstatcheck", argv, envp); // Execute
}

foo.txt 确实被打开且分配了文件描述符 fd,但是在将 stdin 重定向到 foo.txt 后,fd 就被关闭了。也就是说,不存在文件描述符 3,而原先的引用 STDIN 的文件描述符 0 引用了 foo.txt。

图1

这张图很好地佐证了这一点:如果 0 引用的是 STDIN,那么类型应该为 other。

参考资料:https://stackoverflow.com/questions/44357566/what-does-shell-do-when-we-redirect-using


CSAPP e10.9
https://je3ter.github.io/2024/02/17/CSAPP/CSAPP e10.9/
作者
Je3ter
发布于
2024年2月17日
许可协议