当 FILE 流文件被覆盖时会发生什么

What happens when the FILE stream file is overwritten

如果文件在 fopen() 和 fgets() 之间被覆盖会怎样?我有一个程序因以下堆栈跟踪而失败:

0x00007f9d63629850 (Linux) 
0x00007f9d6253e8ab (/lib64/libc-2.11.3.so) __memchr 
0x00007f9d62523996 (/lib64/libc-2.11.3.so) _IO_getline_info_internal 
0x00007f9d6252d0cd (/lib64/libc-2.11.3.so) __GI_fgets_unlocked 

我有理由相信正在读取的文件可能在 fopen() 和 fgets() 之间被覆盖。这有多合理?

我们在 SUSE 11.4 上使用 glibc 2.11.3,所有更新和补丁都应用于 glibc。

这取决于文件在磁盘上的覆盖方式。

  1. 如果文件被原地覆盖(相同的 inode),您的程序将读取新数据。 fopen 不会在第一次读取之前自动填充缓冲区,因此 fgets 将填充缓冲区并获取新数据(在并发更新之后)。
    • 这主要适用于本地文件系统。大多数网络文件系统都有优化,在没有文件锁的情况下,可能仍然 return 旧数据。
    • 没有文件锁定,并发修改会导致观察中间状态的读取操作。
  2. 如果文件被替换(删除并重新创建,或重命名操作),将读取旧数据。