确定文件系统对象是否是 procfs/sysfs/etc。 “虚拟文件”未正确报告其长度

确定文件系统对象是否是 procfs/sysfs/etc。 “虚拟文件”未正确报告其长度

某些类型的伪文件(例如 procfs 和 sysfs 虚拟文件系统中的许多伪文件)没有文件大小(stat返回st_size== 0)并且不SEEK_END支持fseek.这些文件系统对象(例如 )的/proc/cpuinfo行为更像 FIFO,而不是常规的随机访问文件。不幸的是,他们也对文件类型撒了谎:他们的st_mode字段包括S_IFREG位,这意味着常规文件,而不是S_IFIFO位。

这会导致试图“更智能”地管理数据的输入代码出现问题,并且有许多关于工具在查看/proc/*文件时挂起的报告。

我正在开发其中一个工具,它有一个通用的流输入系统,可以从用户指定的各种来源获取流。我还可以处理非随机访问流,例如纯粹“顺序”的管道和套接字,并且用于它们的相同技术也适用于 procfs/sysfs/其他虚拟文件系统对象 - 但我必须能够明确地告诉当我看着一个的时候。

给定 FILE 指针、文件描述符或文件路径名,我如何在 C 中确定我是否正在查看这些麻烦的伪文件对象之一? (注意:仅检查以 /proc 开头的路径是不够的,因为可以任意安装文件系统。我需要操作系统告诉我是否可以信任文件的st_sizeSEEK_END。)是否有一个合理的可移植解决方案现代*尼克斯?

(这是一个编程问题;如果需要,请随意将其迁移到 SO。)

答案1

如果您stat使用文件描述符,结果报告的大小为 0,则要么该文件为空,要么大小未知。如果文件是空的,那么玩游戏就没有多大意义来更有效地读取它。

因此,如果大小未知,则必须使用备用代码路径,如果文件为空,则使用备用代码路径应该不成问题。

我警告不要尝试仅根据文件名诊断文件类型,因为这将使您面临诱饵和切换攻击(或错误)。在成功打开文件之前,不应尝试找出任何内容,然后应确保直接或间接使用文件描述符,而不是名称,因为名称可能不再与文件关联。相同的文件。

希望有帮助。

答案2

检查路径只是第二个好主意。您可以改为检查文件系统(设备):st_dev=makedev(0, 14)。如果主编号为 0,则为procsys等。

即使内核也无法确定文件的性质。想象一个 FUSE 安装座,其中包含/proc.内核会假设一个普通的文件系统,而它是一个伪文件系统,存在您想要避免的问题。

但如果您知道这SEEK_END不起作用,为什么不使用它进行测试呢?

相关内容