Getting Filename from file descriptor in C

2018-12-31 22:02发布

Is it possible to get the filename of a file descriptor (Linux) in C?

标签: c linux
7条回答
残风、尘缘若梦
2楼-- · 2018-12-31 22:20

In Windows, with GetFileInformationByHandleEx, passing FileNameInfo, you can retrieve the file name.

查看更多
与风俱净
3楼-- · 2018-12-31 22:22

Impossible. A file descriptor may have multiple names in the filesystem, or it may have no name at all.

Edit: Assuming you are talking about a plain old POSIX system, without any OS-specific APIs, since you didn't specify an OS.

查看更多
刘海飞了
4楼-- · 2018-12-31 22:25

As Tyler points out, there's no way to do what you require "directly and reliably", since a given FD may correspond to 0 filenames (in various cases) or > 1 (multiple "hard links" is how the latter situation is generally described). If you do still need the functionality with all the limitations (on speed AND on the possibility of getting 0, 2, ... results rather than 1), here's how you can do it: first, fstat the FD -- this tells you, in the resulting struct stat, what device the file lives on, how many hard links it has, whether it's a special file, etc. This may already answer your question -- e.g. if 0 hard links you will KNOW there is in fact no corresponding filename on disk.

If the stats give you hope, then you have to "walk the tree" of directories on the relevant device until you find all the hard links (or just the first one, if you don't need more than one and any one will do). For that purpose, you use readdir (and opendir &c of course) recursively opening subdirectories until you find in a struct dirent thus received the same inode number you had in the original struct stat (at which time if you want the whole path, rather than just the name, you'll need to walk the chain of directories backwards to reconstruct it).

If this general approach is acceptable, but you need more detailed C code, let us know, it won't be hard to write (though I'd rather not write it if it's useless, i.e. you cannot withstand the inevitably slow performance or the possibility of getting != 1 result for the purposes of your application;-).

查看更多
刘海飞了
5楼-- · 2018-12-31 22:26

Before writing this off as impossible I suggest you look at the source code of the lsof command.

There may be restrictions but lsof seems capable of determining the file descriptor and file name. This information exists in the /proc filesystem so it should be possible to get at from your program.

查看更多
琉璃瓶的回忆
6楼-- · 2018-12-31 22:27

I had this problem on Mac OS X. We don't have a /proc virtual file system, so the accepted solution cannot work.

We do, instead, have a F_GETPATH command for fcntl:

 F_GETPATH          Get the path of the file descriptor Fildes.  The argu-
                    ment must be a buffer of size MAXPATHLEN or greater.

So to get the file associated to a file descriptor, you can use this snippet:

#include <sys/syslimits.h>
#include <fcntl.h>

char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
    // do something with the file path
}

Since I never remember where MAXPATHLEN is defined, I thought PATH_MAX from syslimits would be fine.

查看更多
浅入江南
7楼-- · 2018-12-31 22:28

You can use fstat() to get the file's inode by struct stat. Then, using readdir() you can compare the inode you found with those that exist (struct dirent) in a directory (assuming that you know the directory, otherwise you'll have to search the whole filesystem) and find the corresponding file name. Nasty?

查看更多
登录 后发表回答