c - 在实际打开文件之前验证文件路径

标签 c linux file validation posix

假设 Linux,或者更普遍地说是一个充分兼容 POSIX 的系统,是否有现成的方法来检查打开具有给定名称的文件是否会成功?最乐观的是,我正在寻找与 open(2)

具有相同原型(prototype)的函数的实现
int test_open(const char *pathname, int flags);

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

open(2) manual page列出了 open(2) 失败的许多原因。一个errno值可以解码多个原因,errno在Linux和POSIX中是不同的。但粗略地说:

  1. 我认为一般来说,errno 列出的以下情况最相关:EACCESSEEXISTENOENTEISDIRENOTDIR(POSIX 和 Linux)。
  2. 不太重要:ELOOPEMFILEENFILEENAMETOOLONGENODEV , ENXIO, EOVERFLOW, EPERM, EROFS, ETXTBSY, EWOULDBLOCK (POSIX 添加 EAGAIN)。
  3. 不相关(更多 transient 条件):ENOMEMEINTRENOSPC(POSIX 添加了 EIOENOSR).

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

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

我宁愿不通过创建文件来为验证引入副作用(open() 的标志包括 O_CREAT)。 很明显,在大多数情况下,我寻求的检查无法 100% 可靠地执行,这是我将可能的错误情况分为三类的根本原因。我们可以通过分析目录权限、目录的存在以及是否已经有同名的东西阻碍打开文件,以及文件名是否有意义(我的小组1 个条件)。 (第 2 组检查符号链接(symbolic link)的数量、文件描述符限制、名称长度限制、O_NOATIME 权限、文件系统的可写性,可能还有 EWOULDBLOCK 和 POSIX EAGAIN 案例可以完成,但它们更麻烦并且可能更难移植,并且除非恶意输入,否则预计不太可能发生,这是将它们归类为不那么重要的原因)。

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

最佳答案

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

好的做法是检查open 的结果,并在失败时使用errno

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

您可以使用 realpath(3) 验证文件路径的目录部分功能....但即使那是无用的,一些其他进程可能已经创建或删除了您的 test_open 和真正的 open

之间的目录

关于c - 在实际打开文件之前验证文件路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14954982/

相关文章:

java - 如何从文件夹中获取随机文件?

python - 文件,剥离每一行并添加到字典中的键

java - 如果你只有一个 java 应用程序的 shell 安装程序,你如何构建一个 docker 镜像?

linux - 如果文件不存在则退出脚本

c - 从被调用函数访问 malloc'ed struct array 给出 Segmentation Fault

char* 与 const char* 作为参数

linux - 创建一个名为 hello.txt 的文件,其中包含单词 "hello world"?

java - 创建相关 java.io.File 的安全方法

c - 我已经包含了一个头文件,但在尝试运行 make 时仍然未定义

c++ - 目标文件中 undefined reference - 如何找到哪个库包含它?