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

有没有通过fstat(2) POSIX的方式来检查文件是否是一个符号链接

open(2)有标志O_NOFOLLOW可以检查,但是不是POSIX。

fstat(2)S_ISLNK ,这在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. 

编译将在我的机器上失败。

另外,在lstat(2)还有另外一个S_IFLNK ,但是它不能和fstat(2) (它将跟随所指向的文件的链接)。

Solutions Collecting From Web of "是否有任何通过fstat()检查文件是否是符号链接的POSIX方式?"

没有。

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!" 。 世界的状况如下所示:

 +  - 应用程序 -  + +  - 内核 -  + + -------磁盘------- +
 |  |  |  |  |  |
 |  fdes --------------> file ---------> inode#973 <------- +
 |  |  |  |  |  “你好,世界!”  |  |
 + --------------- + + ---------- + |  |  |
                                      | 目录--------- +
                                      |  “B.txt”|
                                      |  |
                                      + ------------------ +

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

如果你问内核路径是什么,它可以说“你有B.txt”打开。 但是你从来没有打开过“B.txt”,你打开了“C.txt”,这是“A.txt”的符号链接,“A.txt”和“C.txt”都被删除了首先)。

简单的比喻:

你接到一个老朋友的电话。 他问道:“我在电话簿里查了一下电话号码,我是否记住了,还是必须要求某人提供号码?”

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

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