【问题标题】:fileno for closed file关闭文件的文件号
【发布时间】:2017-12-30 18:17:38
【问题描述】:

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

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 进行无效读取,因为它假定文件是打开的。

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

【问题讨论】:

  • 邪恶用户”?好吧,我会说“愚蠢”的用户。
  • 查看flock()的返回值。如果fd 不是有效的描述符,我强烈认为它会失败。
  • @MartinR 问题是,如果文件关闭,fileno 已经给出无效读取
  • 相关的stackoverflow.com/q/21450109/694576 如果不重复(请参阅此答案stackoverflow.com/a/21450247/694576)。
  • 特别是文件描述符是不透明的数字,它只对内核意味着任何东西,如果它们是无效的(例如,你只是随机选择一个数字并尝试对其进行操作)它不会做任何事情.

标签: c file file-io fopen


【解决方案1】:

C11 n1570 7.21.3p4

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

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

换句话说,你无法真正做任何事情来辨别你给出的FILE * 值是否指的是一个有效的打开文件......好吧,除了针对@ 进行测试987654326@ - 如果指针的值为NULL 它肯定不能指向一个打开的流。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 2016-10-29
    • 2018-05-14
    • 1970-01-01
    • 2016-08-23
    相关资源
    最近更新 更多