5

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

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

删除文件的程序如下:

unlink(filename);

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

  1. 打开文件后,我可以使用此程序甚至使用rm命令将其删除。
  2. 删除文件后,对文件进行读写操作没有任何问题。

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

4

4 回答 4

8

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

unlink不被称为unlink是因为没有人能想到更好的名字。之所以这么叫,是因为它就是这样做的;它从目录中取消链接文件。(目录只是链接的集合;即,它将名称与相应数据的位置相关联。)它不会删除文件;它不会删除文件。当不再有指向该文件的任何链接时,该文件将由文件系统进行垃圾收集。

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

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

于 2013-10-18T05:19:45.133 回答
4

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

然后,在 Linux 或其他 Unix(例如 MacOSX)上取消链接打开的文件是很正常的事情。这是获取临时文件的规范方法(可能像tmpfile(3)那样)。

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

因此,没有(POSIX-ly 可移植)方法来禁止在没有任何名称的已打开文件上进行 I/O。对于某些打开的文件,内核具有对其 inode 的引用计数器,并保留该 inode 直到所有具有open(2)的进程都关闭它(2)或终止。

另请参见inode(7)credentials(7)

于 2013-10-18T05:19:46.853 回答
1

链接是与某个文件关联的名称(文件基本上是未命名的)。请注意,文件可能有不同的名称(尝试ln)。

unlink()删除其中一个与文件的关联。如果您删除文件的最后一个链接,这只会使您无法通过名称访问该文件。但是,这并不意味着该文件不可用,因为一个文件可能已经打开并且他当前被某个应用程序读/写。

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

于 2013-10-18T15:40:57.723 回答
1

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

帮助守护进程正常工作是一种保护。

于 2013-10-18T05:01:26.883 回答