2013-01-03 127 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不會從文件系統中刪除。 –

相關問題