是否有任何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}}(它将跟随指向的文件的链接)。
答案 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
(是的,有竞争条件)。如果你没有自己打开文件(例如,你从父进程获得它或者通过套接字获得它),那么或多或少不可能知道它是否是通过符号链接打开的。