假设 Linux,或者更普遍地说是一个充分兼容 POSIX 的系统,是否有现成的方法来检查打开具有给定名称的文件是否会成功?最乐观的是,我正在寻找与 open(2)
int test_open(const char *pathname, int flags);
这将根据具有相同参数的 open(2)
系统调用的预期成功或失败返回结果,但实际上没有创建或打开任何文件。它应该获得适当的许可(可在专有软件项目中重复使用)开源。
open(2)
manual page列出了 open(2)
失败的许多原因。一个errno
值可以解码多个原因,errno
在Linux和POSIX中是不同的。但粗略地说:
- 我认为一般来说,
errno
列出的以下情况最相关:EACCESS
、EEXIST
、ENOENT
、EISDIR
、ENOTDIR
(POSIX 和 Linux)。 - 不太重要:
ELOOP
、EMFILE
、ENFILE
、ENAMETOOLONG
、ENODEV
,ENXIO
,EOVERFLOW
,EPERM
,EROFS
,ETXTBSY
,EWOULDBLOCK
(POSIX 添加EAGAIN
)。 - 不相关(更多 transient 条件):
ENOMEM
、EINTR
、ENOSPC
(POSIX 添加了EIO
、ENOSR
).
(我现在无法快速找到 open()
的在线 POSIX 手册页,我个人指的是安装在我的 Linux 机器上的 POSIX 手册页 - 我会在网上找到时编辑问题链接。)
背景和期望:我的应用程序/系统配置架构要求在永久存储输入值之前需要对其进行验证。只有在执行验证和存储步骤后,文件才会用于写入。接受错误的值会带来巨大的不便(同时尝试实际更改为使用错误的文件路径会干扰操作)。对于这种特殊情况,我不能也不想异常(exception)(它只是一百多个配置值中的一个)。
我宁愿不通过创建文件来为验证引入副作用(open()
的标志包括 O_CREAT
)。 很明显,在大多数情况下,我寻求的检查无法 100% 可靠地执行,这是我将可能的错误情况分为三类的根本原因。我们可以通过分析目录权限、目录的存在以及是否已经有同名的东西阻碍打开文件,以及文件名是否有意义(我的小组1 个条件)。 (第 2 组检查符号链接(symbolic link)的数量、文件描述符限制、名称长度限制、O_NOATIME
权限、文件系统的可写性,可能还有 EWOULDBLOCK
和 POSIX EAGAIN
案例可以完成,但它们更麻烦并且可能更难移植,并且除非恶意输入,否则预计不太可能发生,这是将它们归类为不那么重要的原因)。
附言我添加了 c
标签,这是我现在的编程语言,但该语言不是很相关。
最佳答案
没有万无一失的方法来做到这一点,因为(正如 Jite 评论的那样)一些其他进程可能已经改变了环境(例如删除父目录,或填满文件系统,超过磁盘配额,...... ) 在您的 test_open
和进一步的 open
或 creat
系统调用之间。或者磁盘(或包含文件系统的媒体,例如一些 U 盘)可能已被烧毁或已被拔掉。
好的做法是检查open
的结果,并在失败时使用errno
。
您可以使用 access
来检查之前的一些事情。但既然没有万无一失的方法,何必呢?
您可以使用 realpath(3) 验证文件路径的目录部分功能....但即使那是无用的,一些其他进程可能已经创建或删除了您的 test_open
和真正的 open
关于c - 在实际打开文件之前验证文件路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14954982/