打开读取和写入的文件可以取消链接

在我的程序(在Mac OS X上)中,我使用以下代码打开了该文件。

int fd; fd = open(filename, O_RDWR); 

程序删除文件如下:

 unlink(filename); 

在我的情况下,我有打开和删除相同的文件。 我观察到以下情况:

  1. 打开文件后,我可以用这个程序删除它,甚至用rm命令。
  2. 删除文件后,读取和写入操作正在文件上没有任何问题。

我想知道这背后的原因。 如何防止rm命令或unlink(2)系统调用删除正在打开的文件?

您不能停止unlink(2)取消链接它有权取消链接的文件(即它具有对目录的写入访问权限)。

因为没有人会想到一个更好的名字,所以unlink不会被unlink 。 这就是所谓的,因为这是它所做的; 它将该文件从目录中解除链接。 (一个目录只是一个链接的集合,即它将名称与相应数据的位置关联起来)。它不会删除文件。 当文件系统不再有任何链接时,该文件被文件系统垃圾收集。

打开文件描述符不是保持文件链接的唯一方法。 另一种非常常见的方式是使用link(1)命令,而不使用-s选项。 这会创建“硬”链接。 如果一个文件有多个硬链接,那么删除其中一个链接(使用unlink(2) )就是这样做的 – 删除其中一个链接。

rm命令有一个可能更令人困惑的名字,但它也只是删除名称 ,而不是文件。 只要有人有链接,文件就存在,包括正在运行的进程。

首先, rm命令正在调用unlink(2)

然后,断开打开的文件是在Linux或其他Unix(例如MacOSX)上正常执行的事情。 这是获取临时文件的规范方法(如tmpfile(3)可能)。

您应该了解inode是什么,并意识到文件不是它的名称或文件路径,而是本质上的inode。 一个文件可以有零个,一个或多个文件路径或名称(如果所有的名字都在同一个文件系统中,可以用链接(2) syscall添加更多的文件)。 目录条目将名称与inode关联。

所以没有(POSIX -ly便携式)禁止没有任何名字的开放文件的I / O。 对于某些打开的文件,内核具有引用计数器到它的inode,并保持该inode,直到所有进程已经打开(2) -它关闭(2)它或终止。

这在UNIX系统中是正常的。 当你rm或取消链接一个打开的文件。 UNIX系统只是标记一个标志,并不会真正删除该文件的欺骗。 直到文件关闭。 并且在文件系统中将被真正删除。

这是帮助守护进程正常工作的保护。

链接是与某个文件关联的名字(一个文件基本上被取消了)。 请注意,一个文件可能有不同的名称(尝试ln )。

unlink()将这个关联之一移除到一个文件。 如果您删除文件的最后一个链接,这只会使您无法通过名称访问该文件。 但是 ,这并不意味着这个文件是不可用的,因为一个文件可能已经被打开了,而他正在被某个应用程序读取/写入。

文件被删除当且仅当: – 没有链接 – 当前没有被任何应用程序打开