fileno表示已关闭的文件

时间:2017-12-30 18:17:39

标签: c file file-io fopen

我有一个这样的函数,旨在读取文件:

int foo(FILE* f)

我想使用flock来阻止TOCTTOU。 flock需要文件描述符作为整数。我可以使用fileno(file)来获取此信息。因此foo的实现可能如下所示:

int foo(FILE* f) {
  if(!f) return -1;
  int fd = fileno(f);
  if(fd < 0) return -1;
  flock(fd, LOCK_EX);
  //do all the reading stuff and so on.
} 

然而,邪恶的用户可能会这样做:

FILE* test;
test = fopen("someexistingfile.txt", "r");
fclose(test);
foo(test);

然后我遇到了问题,因为fileno会根据valgrind执行无效读取,因为它假定文件是打开的。

有关如何检查文件是否已关闭的任何想法?

1 个答案:

答案 0 :(得分:3)

C11 n1570 7.21.3p4

  
      
  1. 通过关闭文件可以将文件与控制流解除关联。在将流与文件解除关联之前,刷新输出流(任何未写入的缓冲区内容都将传输到主机环境)。 关联文件关闭后不确定指向/usr/lib/jvm/default-runtime对象的指针 (包括标准文本流)。实际存在的零长度文件(输出流没有写入字符)是否为实现定义。
  2.   

FILE之后,在库函数中使用fclose的值会导致未定义的行为。在重新分配之前,指针的值不能安全地用于任何事情。

换句话说,你不能真正任何事情来辨别你所提供的FILE *值是否指的是有效的打开文件......除了测试之外反对FILE * - 如果指针的值为NULL,它肯定不能指向开放流。