是否有任何POSIX方式通过fstat()来检查文件是否是符号链接?

时间:2012-01-16 04:05:57

标签: linux posix symlink

是否有任何POSIX方式通过fstat(2)检查文件是否为符号链接?

O_NOFOLLOW中有一个标记open(2)可以检查它,但是,它不是POSIX。

S_ISLNK中有fstat(2)man fstat中有 The S_ISLNK() and S_ISSOCK() macros are not in POSIX.1-1996, but both are present in POSIX.1-2001; the former is from SVID 4, the latter from SUSv2.

S_IFLNK

并且我的机器上的编译将失败。

此外,lstat(2)中还有另一个fstat(2),但它不适用于{{1}}(它将跟随指向的文件的链接)。

1 个答案:

答案 0 :(得分:3)

没有

fstat遵循符号链接是不正确的。相反,open遵循符号链接。一旦你到达fstat,就太晚了,信息就消失了。

告诉我们您需要了解的原因,我们可以帮助解决这个问题。 (打开另一个问题。)

文件的工作原理:

这是一些伪C / shell代码:

system("echo 'Hello, World!' >A.txt");
system("ln A.txt B.txt");
system("ln -s A.txt C.txt");

fdes = open("C.txt");
unlink("A.txt");
unlink("C.txt");
data = read(fdes);
write(stdout, data);

结果:您的程序打印"Hello, world!"。世界状况如下:

+--Application--+    +--Kernel--+    +-------Disk-------+
|               |    |          |    |                  |
|  fdes --------------> file ---------> inode #973 <-------+
|               |    |          |    |  "Hello World!"  |  |
+---------------+    +----------+    |                  |  |
                                     |  directory ---------+
                                     |  "B.txt"         |
                                     |                  |
                                     +------------------+

就内核而言,打开的文件是“inode#973”。内核内存中的数据结构有一些附加信息,例如当前位置,但它不知道路径。预计内核不会知道该信息。

如果您询问内核的路径是什么,可以说“你有B.txt”打开。但是你从未打开过“B.txt”,你打开了“C.txt”,它是“A.txt”的符号链接,“A.txt”和“C.txt”都被删除了(它们只是名字来源)从...开始。

简单类比:

你接到一位老朋友的电话。他问:“我是否在电话簿中查找了你的号码,我是否记住它,或者我是否必须向某人询问你的号码?”

你无法知道答案。所有你知道的是谁在另一端。就像打开的文件不存储有关它的名称(硬链接或符号链接)的信息一样,它只包含有关权限和数据的信息。

解决方案:只需使用lstat(是的,有竞争条件)。如果你没有自己打开文件(例如,你从父进程获得它或者通过套接字获得它),那么或多或少不可能知道它是否是通过符号链接打开的。