是否有通过fstat()的POSIX方法来检查文件是否为符号链接? [英] is there any POSIX way through fstat() to check whether a file is a symbolic link or not?

查看:99
本文介绍了是否有通过fstat()的POSIX方法来检查文件是否为符号链接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有通过fstat(2)的POSIX方法来检查文件是否为符号链接?

Is there any POSIX way through fstat(2) to check whether a file is a symbolic link or not?

open(2)中有一个标志O_NOFOLLOW可以对其进行检查,但是它不是POSIX.

There is flag O_NOFOLLOW in open(2) which can check it, however, it's not 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.

,编译将在我的计算机上失败.

and the compile will fail on my machine.

此外,lstat(2)中还有另一个S_IFLNK,但是,它不能与fstat(2)一起使用(它将跟随指向所引用文件的链接).

Also, there is another S_IFLNK in lstat(2), however, it won't work with fstat(2) (which will follow the link to the file referred to).

推荐答案

否.

fstat遵循符号链接不是真的.而是open跟随符号链接.进入fstat时,已经太迟了,信息也消失了.

It's not true that fstat follows symlinks. Instead, open follows symlinks. Once you get to fstat, it is too late and the information is gone.

告诉我们您为什么需要知道,我们可以为您解决该问题. (打开另一个问题.)

Tell us why you need to know, and we can help with that problem. (Open another question.)

文件的工作方式:

这是一些伪C/shell代码:

Here is some pseudo-C / shell code:

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!".世界状况如下:

The result: your program prints "Hello, world!". The state of the world looks like this:


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

就内核而言,打开的文件为"inode#973".内核内存中的数据结构具有一些其他信息,例如当前位置,但它不知道路径.内核不应该知道该信息.

As far as the kernel is concerned, the file open is "inode #973". The data structure in kernel memory has some additional information such as the current position, but it does NOT know the path. The kernel is not expected to know that information.

如果您询问内核路径是什么,它可能会说您拥有B.txt".但是您从未打开过"B.txt",而是打开了"C.txt",这是指向"A.txt"的符号链接,并且"A.txt"和"C.txt"均已删除(它们只是开头).

If you asked the kernel what the path is, it could say "you have B.txt" open. But you never opened "B.txt", you opened "C.txt" which was a symlink to "A.txt", and both "A.txt" and "C.txt" have been deleted (they were just names to begin with).

简单的比喻:

您收到一个老朋友的电话.他问:我是在电话号码簿中查找您的电话号码吗,我是否记住了电话号码,还是必须向某人询问您的电话号码?"

You get a phone call from an old friend. He asks, "Did I look up your number in the phone directory, did I memorize it, or did I have to ask someone for your number?"

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

You have no way of knowing the answer. All you know is who is on the other end of the line. Just like an open file doesn't store information about what it was named (hard link or symbolic link), it just has information about permissions and data.

解决方案:只需使用lstat(是的,有竞争条件).如果您不是自己打开文件的(例如,您是从父进程中获取文件的,或者是通过套接字获取的),则几乎无法知道是否通过符号链接打开了文件.

The solution: Just use lstat (yes, there is a race condition). If you didn't open the file yourself (e.g., you get it from a parent process or you get it over a socket), then it's more or less impossible to know if it was opened through a symbolic link.

这篇关于是否有通过fstat()的POSIX方法来检查文件是否为符号链接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆