2009-07-23 12 views
5

我知道有可能通过realpath()函数获取文件的绝对路径。但是,根据bugs部分的manpage,它的实现有一些问题。详细情况如下:如何在linux下使用realpath()以编程方式获取文件的绝对路径?


BUGS使用此功能

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

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


所以,问题是什么是获得文件的绝对路径的最佳做法?

+0

复制“[编程式检索OS X命令行应用程序的绝对路径](http://stackoverflow.com/questions/799679/programatically-retrieving-the-absolute-path-of-an-os-的x命令行应用内)“? – bortzmeyer 2009-07-23 19:45:38

+0

不,他们不是一回事。我想知道如何获得普通文件的绝对路径,而不是可执行文件的路径。 – jcadam 2009-07-24 15:12:26

回答

2

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

# man 2 readlink 
+0

我已阅读coreutils包中的readlink命令的源代码。有一个简单的解决方案 - 只需将PATH_MAX定义为1024! -__-! – jcadam 2009-07-23 14:42:16

3

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

5

我知道这个问题已经过时了,但我没有看到任何解决核心问题的答案:至少有两个原因引用的手册页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,该怎么办。

相关问题