我从fanotify中接收文件系统事件。 有时,我想获取正在访问的文件的绝对路径。
通常,这不是问题-
但是,如果路径超过
显然,我可以
我尝试通过使用
到目前为止,我已经成功为打开它们的进程的工作目录内部的文件获得了长路径(fanotify事件包含目标进程的
是否有一种方法可以从文件描述符中获取绝对路径而无需遍历整个文件系统? 最好与kernel 2.6.32/glibc 2.11兼容。 更新: 对于好奇者。 我已经弄清楚为什么使用足够大以存储整个路径的缓冲区调用
看看do_proc_readlink的实现。注意它不直接使用提供的
通常,这不是问题-
fanotify_event_metadata
包含文件描述符fd
,因此我可以在/proc/self/fd/<fd>
上调用readlink
并获得路径。但是,如果路径超过
PATH_MAX
,则无法再使用readlink
,它将失败并出现ENAMETOOLONG
。 我想知道是否有一种方法可以在这种情况下获取文件路径。显然,我可以
fstat
来自fanotify的描述符,并遍历整个文件系统以查找具有相同设备ID和inode编号的文件。 但是,就性能而言,这种方法对我来说不可行(即使我优化它以忽略长度小于PATH_MAX
的路径)。我尝试通过使用
O_PATH
重新打开fd
并调用openat(fd,"..",...)
来获取父目录。 很明显,这失败了,因为fd
不是指向目录的。 我还尝试检查readlink
调用失败后缓冲区的内容(希望它包含部分路径)。 这也行不通。到目前为止,我已经成功为打开它们的进程的工作目录内部的文件获得了长路径(fanotify事件包含目标进程的
pid
,因此我可以读取/proc/<pid>/cwd
并从那里获取到根的路径)。 但这是一个局部解决方案。是否有一种方法可以从文件描述符中获取绝对路径而无需遍历整个文件系统? 最好与kernel 2.6.32/glibc 2.11兼容。 更新: 对于好奇者。 我已经弄清楚为什么使用足够大以存储整个路径的缓冲区调用
readlink("/proc/self/fd/<fd>",...
不起作用。看看do_proc_readlink的实现。注意它不直接使用提供的
buffer
。相反,它分配一个单独的页面,并在调用d_path时将其用作临时缓冲区。换句话说,无论buffer
有多大,d_path
始终会被限制为页面大小。在amd64上是4096字节。与PATH_MAX
相同!当它用完所提到的页面时,prepend本身将返回-ENAMETOOLONG
。
.
/..
元素,长度超过了PATH_MAX
?如果没有,realpath()
可能适合您:http://man7.org/linux/man-pages/man3/realpath.3.html - Andrew HenlePATH_MAX
字符短吗?这听起来很奇怪。 - unwindrealpath
需要首先提供路径。readlink()
也是如此。你是如何让它工作的? - Andrew Henlereadlink
在/proc/self/fd/<fd>
上。 - Nikita Kakuev