0

假设 Linux,或者更一般地说是一个足够兼容 POSIX 的系统,是否有现成的方法来检查打开具有给定名称的文件是否会成功?最乐观的是,我正在寻找一个具有相同原型的函数的实现open(2)

int test_open(const char *pathname, int flags);

它将根据open(2)具有相同参数的系统调用的预期成功或失败返回结果,但不会实际创建或打开任何文件。它应该被适当地许可(可在专有软件项目中重复使用)开源。

open(2)手册页open(2)列出了许多失败的原因。一个errno值可以解码多种原因,errnoLinux 和 POSIX 不同。但粗略地说:

  1. 我认为总的来说,以下情况errno最相关:EACCESS, EEXIST, ENOENT, EISDIR, ENOTDIR(POSIX 和 Linux)。
  2. 不太重要:ELOOP, EMFILE, ENFILE, ENAMETOOLONG, ENODEV, ENXIO, EOVERFLOW, EPERM, EROFS, ETXTBSY, EWOULDBLOCK(POSIX 添加EAGAIN)。
  3. 不相关(更多瞬态条件):ENOMEM, EINTR, ENOSPC(POSIX 添加EIO, ENOSR)。

(我现在无法快速找到在线 POSIX 手册页open(),我个人指的是安装在我的 Linux 机器上的 POSIX 手册页 - 我会在找到在线链接时编辑问题。)

背景和期望:我的应用程序/系统配置架构要求在永久存储输入值之前需要对其进行验证。只有在执行了验证和存储步骤之后,文件才会用于写入。接受错误的值会带来巨大的不便(尝试实际更改以使用错误的文件路径会干扰操作)。我不能或不想为这种特殊情况例外(它只是一百多个配置值之一)。

open()我宁愿不通过创建文件(包含的标志)来引入验证的副作用O_CREAT很明显,在最一般的情况下,我正在寻找的检查不能 100% 可靠地实现,这就是我将可能的错误情况分为三组的根本原因。通过分析目录权限、目录的存在以及是否已经存在阻碍打开文件的同名内容以及文件名是否有意义(我的第 1 组条件),我们可以做出非常有根据的猜测。(第 2 组检查符号链接的数量、文件描述符限制、名称长度限制、O_NOATIME权限、文件系统的可写性,可能EWOULDBLOCK还有 POSIXEAGAIN案例可以完成,但它们更麻烦并且可能不太便携,并且预计不太可能发生,除非恶意输入,这是将它们分类不太重要的原因)。

PS我添加了标签c,这是我现在的编程语言,但语言不是很相关。

4

1 回答 1

3

没有万无一失的方法可以做到这一点,因为(正如 Jite 评论的那样)其他一些进程可能已经改变了环境(例如,删除了父目录,或者填满了文件系统,超过了磁盘配额,......)test_open以及进一步的opencreat系统调用。或者磁盘(或包含文件系统的媒体,例如一些 USB 记忆棒)可能已烧毁或已拔出。

好的做法是检查结果openerrno在失败时使用。

您可以使用access之前检查一些事情。但是既然没有万无一失的方法,那何必呢?

您可以使用realpath(3)函数验证文件路径的目录部分...。但即使这样也没用,其他一些进程可能已经创建或删除了您test_open和真实之间的目录open

于 2013-02-19T11:43:43.080 回答