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