从C中的文件描述符获取文件名

是否有可能得到在C文件描述符(Linux)的文件名?

Solutions Collecting From Web of "从C中的文件描述符获取文件名"

您可以在/proc/self/fd/NNN上使用readlink ,其中NNN是文件描述符。 这会给你打开文件的名字 – 不过,如果文件被移动或删除了,它可能不再准确(尽管在某些情况下,Linux可以跟踪重命名)。 要验证, stat给定的文件名和fstat你有,并确保st_devst_ino是相同的。

当然,并不是所有的文件描述符都指向文件,对于那些你会看到一些奇怪的文本字符串,比如pipe:[1538488] 。 由于所有的真实文件名都是绝对路径,因此可以确定哪些文件很容易。 此外,正如其他人所指出的,文件可以有多个指向他们的硬链接 – 这只会报告它被打开的链接。 如果你想找到给定文件的所有名字,你只需要遍历整个文件系统。

我在Mac OS X上遇到了这个问题。我们没有/proc虚拟文件系统,所以接受的解决方案无法工作。

相反,我们有一个fcntlF_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 } 

由于我从来不记得MAXPATHLEN在哪里定义,所以我认为从syslimits中PATH_MAX会好的。

在Windows中,通过GetFileInformationByHandleEx传递FileNameInfo ,可以检索文件名。

正如Tyler所指出的那样,由于给定的FD可能对应于0个文件名(在各种情况下)或> 1(多个“硬链接”是通常描述后一种情况的方式),所以没有办法做到“直接可靠” )。 如果你仍然需要所有的限制功能(速度和获得0,2,…结果的可能性,而不是1),这里是你如何做到这一点:首先,FD的fstat – 这告诉你,在生成的struct stat ,文件生活在什么设备,有多少硬链接,它是否是一个特殊的文件等。这可能已经回答你的问题 – 例如,如果0硬链接,你会知道事实上没有磁盘上对应的文件名。

如果统计信息给你带来希望,那么你必须在相关设备上“目录树”,直到找到所有的硬链接(或者只是第一个,如果你不需要超过一个,任何一个都可以) )。 为此目的,你使用readdir (和opendir&c当然)递归地打开子目录,直到你在一个struct dirent找到,因此得到了与原始struct stat相同的inode号(如果你想要整个路径,而不是只是名字,你需要走回目录链来重建它)。

如果这个通用的方法是可以接受的,但是你需要更详细的C代码,让我们知道,这不是很难写(尽管我宁愿不写它,如果它是无用的,即你无法承受不可避免的慢性能或获取!= 1结果的可能性为您的应用程序的目的;-)。

在写这个关闭之前,我建议你看一下lsof命令的源代码。

可能有限制,但lsof似乎能够确定文件描述符和文件名。 这个信息存在于/ proc文件系统中,所以应该可以从你的程序中获取。

您可以使用fstat()通过struct stat来获取文件的inode。 然后,使用readdir(),你可以比较你发现的inode和目录中存在的inode(struct dirent)(假设你知道该目录,否则你将不得不搜索整个文件系统)并找到相应的文件名。 讨厌?

不可能。 文件描述符可能在文件系统中有多个名字,或者根本没有名字。

编辑:假设你正在谈论一个普通的旧POSIX系统,没有任何操作系统特定的API,因为你没有指定一个操作系统。