从C中的文件描述符获取文件名
是否有可能得到在C文件描述符(Linux)的文件名?
您可以在/proc/self/fd/NNN
上使用readlink
,其中NNN是文件描述符。 这会给你打开文件的名字 – 不过,如果文件被移动或删除了,它可能不再准确(尽pipe在某些情况下,Linux可以跟踪重命名)。 要validation, stat
给定的文件名和fstat
你有,并确保st_dev
和st_ino
是相同的。
当然,并不是所有的文件描述符都指向文件,对于那些你会看到一些奇怪的文本string,比如pipe:[1538488]
。 由于所有的真实文件名都是绝对path,因此可以确定哪些文件很容易。 此外,正如其他人所指出的,文件可以有多个指向他们的硬链接 – 这只会报告它被打开的链接。 如果你想find给定文件的所有名字,你只需要遍历整个文件系统。
我在Mac OS X上遇到了这个问题。我们没有/proc
虚拟文件系统,所以接受的解决scheme无法工作。
相反,我们有一个F_GETPATH
命令fcntl
:
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(多个“硬链接”是通常描述后一种情况的方式),所以没有办法做到“直接可靠”的要求)。 如果你仍然需要所有的限制function(速度和获得0,2,…结果的可能性,而不是1),这里是你如何做到这一点:首先,FD的fstat – 这告诉你,在生成的struct stat
,文件生活在什么设备,有多less硬链接,它是否是一个特殊的文件,等等。这可能已经回答你的问题 – 例如,如果0硬链接,你会知道其实是没有磁盘上对应的文件名。
如果统计信息给了你希望,那么你必须在相关设备上“目录树”,直到find所有的硬链接(或者只是第一个,如果你不需要超过一个,任何一个都可以) )。 为此,你使用readdir (和opendir&c当然)recursion地打开子目录,直到你在一个struct dirent
find,因此得到了你在原始struct stat
的相同的inode号(在这个时候如果你想要整个path,而不是只是名字,你需要走回目录链来重build它)。
如果这个通用的方法是可以接受的,但是你需要更详细的C代码,让我们知道,这不是很难写(尽pipe我宁愿不写它,如果它是无用的,即你无法承受不可避免的慢性能或获取!= 1结果的可能性为您的应用程序的目的;-)。
在写这个closures之前,我build议你看一下lsof命令的源代码。
可能有限制,但lsof似乎能够确定文件描述符和文件名。 这个信息存在于/ proc文件系统中,所以应该可以从你的程序中获取。
您可以使用fstat()通过struct stat来获取文件的inode。 然后,使用readdir(),你可以比较你发现的inode和目录中存在的inode(struct dirent)(假设你知道该目录,否则你将不得不search整个文件系统)并find相应的文件名。 讨厌?
不可能。 文件描述符在文件系统中可能有多个名称,或者根本没有名称。
编辑:假设你正在谈论一个普通的旧POSIX系统,没有任何操作系统特定的API,因为你没有指定一个操作系统。