在C中从文件描述符检索文件名
可以用C语言获取文件描述符(Linux)的文件名吗?不可能。文件描述符在文件系统中可能有多个名称,或者根本没有名称 编辑:假设您谈论的是一个普通的旧POSIX系统,没有任何特定于操作系统的API,因为您没有指定操作系统。在Windows中,通过,您可以检索文件名。您可以使用fstat()通过struct stat获取文件的inode。然后,使用readdir()可以将找到的inode与存在的inode进行比较(struct dirent)并找到相应的文件名。在C中从文件描述符检索文件名,c,linux,file,file-descriptor,C,Linux,File,File Descriptor,可以用C语言获取文件描述符(Linux)的文件名吗?不可能。文件描述符在文件系统中可能有多个名称,或者根本没有名称 编辑:假设您谈论的是一个普通的旧POSIX系统,没有任何特定于操作系统的API,因为您没有指定操作系统。在Windows中,通过,您可以检索文件名。您可以使用fstat()通过struct stat获取文件的inode。然后,使用readdir()可以将找到的inode与存在的inode进行比较(struct dirent)并找到相应的文件名。 讨厌?正如泰勒所指出的,没有办法“直
讨厌?正如泰勒所指出的,没有办法“直接可靠地”完成您需要的工作,因为给定的FD可能对应于0个文件名(在各种情况下)或>1(后一种情况通常描述为多个“硬链接”)。如果您确实需要具有所有限制的功能(关于速度和获得0,2,…结果而不是1的可能性)首先,FD——它告诉你,在生成的
struct stat
中,文件所在的设备,它有多少个硬链接,它是否是一个特殊的文件,等等。这可能已经回答了你的问题——例如,如果有0个硬链接,你就会知道磁盘上实际上没有相应的文件名
如果统计数据给了你希望,那么你必须在相关设备上“遍历目录树”,直到找到所有的硬链接(或者只有第一个,如果你不需要多个,任何一个都可以)。为此,你使用(当然还有opendir&c)递归地打开子目录,直到在struct dirent
中找到,从而收到与原始struct stat
中相同的inode编号(此时,如果需要整个路径,而不仅仅是名称,则需要向后遍历目录链以重建它)
如果这种通用方法是可以接受的,但您需要更详细的C代码,请让我们知道,编写它并不困难(尽管如果它没有用,我宁愿不编写它,也就是说,您无法承受不可避免的缓慢性能,或者在应用程序中获得!=1结果的可能性;-).在将此视为不可能之前,我建议您查看该命令的源代码 可能有限制,但lsof似乎能够确定文件描述符和文件名。此信息存在于/proc文件系统中,因此可以从您的程序中获取。您可以在
/proc/self/fd/NNN
上使用,其中NNN是文件描述符。这将为您提供文件创建时的名称已打开-但是,如果文件从那时起被移动或删除,它可能不再准确(尽管Linux在某些情况下可以跟踪重命名)。要验证,stat
给定的文件名和fstat
您拥有的fd,并确保st_dev
和st_ino
是相同的
当然,并非所有的文件描述符都引用文件,对于这些描述符,您将看到一些奇怪的文本字符串,例如
pipe:[1538488]
。由于所有实际文件名都是绝对路径,因此您可以很容易地确定哪些路径是绝对路径。此外,正如其他人所指出的,文件可以有多个指向它们的硬链接-这将只报告打开文件时使用的硬链接。如果您想找到给定文件的所有名称,只需遍历整个文件系统即可 我在Mac OS X上遇到了这个问题。我们没有/proc
虚拟文件系统,因此公认的解决方案无法工作
相反,我们有一个用于fcntl
的F_GETPATH
命令:
F_GETPATH Get the path of the file descriptor Fildes. The argu-
ment must be a buffer of size MAXPATHLEN or greater.
因此,要获取与文件描述符关联的文件,可以使用以下代码段:
#include <sys/syslimits.h>
#include <fcntl.h>
char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
// do something with the file path
}
#包括
#包括
char filePath[PATH_MAX];
如果(fcntl(fd,F_GETPATH,filePath)!=-1)
{
//对文件路径执行一些操作
}
因为我从来都不记得
MAXPATHLEN
是在哪里定义的,所以我认为来自syslimits的PATH\u MAX
就可以了。然后我的答案就适用了。Linux没有这样做的工具。Linux(POSIX)文件描述符不一定指文件,即使它们指的是索引节点,也不是文件名。描述符可以指向已删除的文件(因此没有名称,这是生成临时文件的常见方法),也可以指向具有多个名称的索引节点(硬链接)。请尝试查看lsof源代码:)不久前我自己也遇到同样的问题时,我就是这么做的。lsof在黑魔法和牺牲山羊身上工作——你不能希望复制它的行为。更具体地说,lsof与linux内核紧密耦合,不通过用户代码可用的任何API来做它所做的事情。linux有一个不可移植的过程API对于这一点,确实存在一些限制,但说这是不可能的完全是错误的。@Tyler-lsof在用户空间中运行。因此,无论它做什么,都有一个API可用于userland代码:)@Duck,那里的可移植性可能就是lsof的源代码有这么多黑魔法的原因;每个UNIX变体都有不同的功能。linux proc接口还不错,事实上,alebit的文档很少。虽然我讨厌windows,但只要原始文件仍然有引用(openfd
就是这样的引用),就可以使用windows等效接口,inode编号不能重复使用。任何在关闭文件后或打开文件前使用inode编号的软件都会受到竞争条件的影响。危险,威尔·罗宾逊!这并不总是有效的——如果您使用setuid()
技巧,您的进程可能无法访问/proc/self/fd
。请参阅:@bdonlan:如果没有挂载/proc?@user2284570,这个答案是特定于Linux的。我不知道NetBSD是否支持procfs—如果