2013-01-03 96 views
1

我在C中写了一个小程序,我成功地打开了一个文件,然后调用了睡眠20秒。在那20秒中,我从shell中使用rm删除了打开的文件。睡眠后,程序成功读取数据并将其打印在屏幕上。从已删除的文件中读取

int bytes_read; 
FILE *fp = fopen("/tmp/file", "r"); 
sleep(20); 
bytes_read = fread(buf, 1, 5, fp); 
buf[bytes_read] = '\0'; 
printf("%s", buf); 

我希望它读取0字节,但它会在文件中打印实际数据。这种行为背后的解释是什么。

+7

磁盘上的数据没有根除,只有inode被删除。并且只有在文件上的所有打开的句柄都关闭之后。 –

+0

如果文件被重命名,这也是真的吗? – 0xhacker

+0

原理相同。你已经打开了一个文件,操作系统不会将它从你的脚下拉开。 –

回答

11

在Linux和其他POSIX系统中,您不会删除文件。您只需从目录中删除一个inode。只要在文件上打开文件描述符,它就不会被删除。只有到inode和最后打开的文件描述符的最后一个链接消失时。

+0

有趣的是,您可能处于文件仍然存在的状态(程序正在运行时),但是一旦删除了目录条目,您完全没有办法挽救它们。有人告诉我,内核不提供通过开放描述符来查找文件的接口存在安全原因,并且可以通过创建合适的内核模块来获得该行为。 –

+0

在Linux上,您可以通过跟踪/ proc/$$/fd(其中$$是您的pid)中的符号链接来查找fd中的文件名 - 使用ls -l来尝试。在我刚刚检查的版本(CentOS 6.3)中,它也表示该文件已被删除,但fd仍处于打开状态。 – cdarke

+2

句子“从目录中删除一个inode”是无稽之谈。 inode不存在于目录中。不同目录中的两个路径可以链接到相同的inode。从inode中断开一条路径(这是'rm'的作用)将从该目录中删除该链接,但是直到最后一次引用它为止,inode不会从文件系统中删除。 –

相关问题