【问题标题】:How to get the absolute path of a file programmatically with out realpath() under linux?如何在linux下不使用realpath()以编程方式获取文件的绝对路径?
【发布时间】:2009-07-23 13:43:58
【问题描述】:

我知道可以使用 realpath() 函数获取文件的绝对路径。但是,根据手册页的 BUGS 部分,它的实现存在一些问题。详情如下:


错误

避免使用此功能。它被设计破坏了,因为(除非使用非标准的resolved_pa​​th == NULL 功能)无法确定输出缓冲区resolved_pa​​th 的合适大小。根据 POSIX,大小 PATH_MAX 的缓冲区就足够了,但 PATH_MAX 不必是已定义的常量,可能必须使用 pathconf(3) 获得。并且询问 pathconf(3) 并没有真正帮助,因为一方面 POSIX 警告 pathconf(3) 的结果可能很大并且不适合分配内存。另一方面,pathconf(3) 可能返回 -1 表示 PATH_MAX 不受限制。

libc4 和 libc5 实现包含缓冲区溢出(在 libc-5.4.13 中修复)。因此,像 mount(8) 这样的 set-user-ID 程序需要一个私有版本。


那么,问题是获取文件的绝对路径的最佳做法是什么?

【问题讨论】:

标签: c linux


【解决方案1】:

我知道这个问题很老,但我没有看到任何解决核心问题的答案:至少有两个原因,参考的手册页 OP 是错误的和过时的。

一个是 POSIX 2008 添加/强制支持 NULL 参数选项,realpath 为您分配字符串。使用此功能的程序将可移植到所有相关版本的 GNU/Linux,可能是大多数其他现代系统,以及任何符合 POSIX 2008 的系统。

手册页错误的第二个原因是对PATH_MAX 的警告。这纯粹是反对“任意限制”的 GNU 宗教意识形态。在现实世界中,没有路径名长度限制会增加各种滥用/DoS 的途径,会给原本不会失败的任务添加大量失败案例,并且会破坏更多的接口,而不仅仅是realpath

如果您关心最大的可移植性,最好同时使用这两种方法。有关详细信息,请参阅 POSIX 文档:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html

如果定义了PATH_MAX,我将使用固定大小、调用者提供的缓冲区,否则传递NULL。这似乎涵盖了所有情况,但您可能还想检查旧版本的 POSIX,看看他们是否有任何指导方针,如果没有定义 PATH_MAX

【讨论】:

    【解决方案2】:

    使用 getcwd() 和 readlink() 允许给出缓冲区大小来重新实现 realpath()。请注意,您必须解析符号链接“。”和“..”从左到右正确地做到这一点。

    【讨论】:

      【解决方案3】:

      在 shell 中,我可以使用 readlink -f $FILE 获得完整路径。 glibc 中有一个readlink() 函数,也许对你有帮助。

      # man 2 readlink
      

      【讨论】:

      • 我已经阅读了coreutils包中readlink命令的源代码。有一个简单的解决方案——只需将PATH_MAX 定义为1024!!!! -__-!!!
      猜你喜欢
      • 2011-01-21
      • 2015-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      • 2013-06-03
      • 1970-01-01
      • 2019-01-17
      相关资源
      最近更新 更多