C语言open函数疑问:为何需重新打开文件才能配合execve工作
为什么关闭并重开文件后execve才能读取到内容?
我尝试用C语言实现类似<<(heredoc)的功能,练习open函数的使用,编写了如下代码:
#include <stdio.h> #include <fcntl.h> #include <unistd.h> int main() { int in_fd = open("here_doc.tmp", O_CREAT | O_RDWR | O_TRUNC, 0644); int out_fd = open("outfile", O_CREAT | O_RDWR | O_APPEND, 0644); write(in_fd, "hello 1\n", 8); write(in_fd, "Pello 1\n", 8); write(in_fd, "Yello 1\n", 8); /* ********* 我想知道下面两行为何是必需的 ******* */ close(in_fd); in_fd = open("here_doc.tmp", O_RDWR, 0644); dup2(in_fd, 0); dup2(out_fd, 1); close (in_fd); close (out_fd); char *argv[]= {"cat", NULL}; execve("/bin/cat", argv, NULL); }
原本我以为只需要调用一次open就能完成,但发现直接使用第一次open的文件描述符时,execve调用的cat读不到文件内容,必须加上注释里的关闭并重开操作才能正常工作,请问这是为什么?
核心原因:文件偏移量的位置问题
当你第一次打开文件并执行三次write操作后,文件的当前偏移量已经移动到了文件末尾。此时如果直接把这个文件描述符通过dup2设置为标准输入(fd=0),cat程序从这个偏移位置开始读取,自然读不到任何内容——因为已经到文件结尾了。
而关闭文件再重新打开的操作,会把文件的偏移量重置到文件开头,这时候cat从开头读取,就能获取到之前写入的所有内容了。
替代方案:无需关闭重开的方法
其实不用关闭重开,直接调用lseek函数把偏移量移回文件开头即可,效果完全一样:
// 替换close和重新open的两行,改成下面这行 lseek(in_fd, 0, SEEK_SET);
内容的提问来源于stack exchange,提问作者water
相关产品推荐
相关产品推荐

