在Linux中,PATH_MAX的定义在哪里?

149

我应该使用哪个头文件来调用 #include,以便将 PATH_MAX 作为 int 类型来调整字符串大小?

我想声明:

char *current_path[PATH_MAX];

但是当我这样做时,我的编译器(在Linux上使用的Clang/LLVM)会发出以下错误:

recursive_find6.c:29:20: error: use of undeclared identifier 'PATH_MAX'
char *current_path[PATH_MAX];
                   ^

我尝试过谷歌搜索,但仍然没有找到解决办法。

#include <limits.h>并不能解决这个问题或错误。

我是否正确地认为PATH_MAX的值是int类型?


3
请看这个问题:https://dev59.com/wnRA5IYBdhLWcg3wxA5N - Josh Brown
24
你可能希望使用 char current_path[PATH_MAX]; 代替 char *current_path[PATH_MAX];,因为你需要一个字符串而不是一个指针数组。 - John Carter
在Ubuntu 10.04上编译时,出现“path_max未声明”的错误。 - qdii
5个回答

177

这个定义在linux/limits.h中。
#define PATH_MAX 4096 /* # chars in a path name including nul */

#include <linux/limits.h>

char current_path[PATH_MAX];

PATH_MAX存在一些缺陷,如此博客所述(感谢paulsm4)。


33
这是一个关于 PATH_MAX 的好链接,它解释了为什么 PATH_MAX 实际上并不存在:http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html。 - paulsm4
8
你应该使用 <limits.h>;<linux/limits.h> 看起来明显不可移植。 - Edward Falk
5
注意:PATH_MAX和NAME_MAX是不同的(参考文献中似乎在某种程度上混淆了这两个常量)。注意:POSIX <limits.h>中指出:“以下符号常量之一的定义应从<limits.h>头文件中省略[...],其中相应值等于或大于所述最小值,但该值可以因应用于其上的文件而有所变化。特定路径名支持的实际值应由pathconf()函数提供。” - Jonathan Leffler
2
路径名非常不安全,path_max是一个谎言甚至不是一个恒量(在不同的操作系统功能上可能不同)。这是一个可怕的特性,应该尽快替换。 - Lothar
1
@Lothar,你建议我们使用什么代替?路径数字?GPS坐标? - Melab
显示剩余5条评论

19

请注意,目前仍不清楚PATH_MAX是否定义了包括或不包括末尾空字节的最大长度。在不同的操作系统上可能是其中之一。如果您无法或不想在编译期间检查哪种情况,最好强制人为限制为PATH_MAX-1。安全第一。 (显然,您仍需要至少保留PATH_MAX个字节的内存来缓冲字符串。)


5
{PATH_MAX}表示路径名中的最大字节数,包括结束的空字符。这是根据 POSIX '01 标准定义的。 - muh karma
11
请注意,POSIX 2008年解决了混淆问题 - <limits.h> (Rationale): {PATH_MAX}。IEEE PASC Interpretation 1003.1 #15解决了标准中路径名和{PATH_MAX}的定义描述不一致的问题,允许应用程序开发人员分配{PATH_MAX}或{PATH_MAX}+1字节。通过更正{PATH_MAX}的定义以包括空字符,已消除不一致性。随着这个变化,之前分配{PATH_MAX}字节的应用程序将继续成功。 - Jonathan Leffler
3
请注意,你不应该使用 PATH_MAX - 1,而应该使用 PATH_MAX + 1。虽然现在已经不需要了,但是你需要为末尾的 '\0' 再增加一个字节。 - Alexis Wilke
我觉得他们在讨论限制某些使用“-1”创建的路径,因为接着他们说你仍然应该保留“PATH_MAX”字节。或者你为什么要写“-1” @Kumashiro? - undefined

13

1
即使如此还不够。PATH_MAX 不一定被定义:“在特定的实现中,如果相应值等于或大于所述最小值,以下列表中一个符号常量的定义将从 <limits.h> 头文件中省略,但是该值可能因应用于其上的文件而异。对于特定路径名支持的实际值应由 pathconf() 函数提供。”鉴于 Linux 文件系统支持不同的值,Linux 定义 PATH_MAX 可能违反 POSIX 标准。 - Andrew Henle
1
定义 _POSIX_C_SOURCE 是做什么用的?有人告诉我在程序中永远不要定义以 _ 开头的变量。 - vy32
@vy32 _POSIX_C_SOURCE 是一个 特性测试宏 - Flux
1
@flux - 好的...所以我不应该定义它? - vy32
@vy32 这取决于你想要做什么。请阅读有关特性测试宏的资料。 - Flux

5

当我进行简单的C编程时,我遇到了同样的挑战。在您特定的Linux系统上,/usr/include目录包含许多针对Linux操作系统的头文件。

find . -name "*.h" | xargs grep PATH_MAX 

您应该能看到几个定义了PATH_MAX的头文件;不幸的是,这个值在不同的头文件中被定义得不一样。以下是我Ubuntu系统中的列表(我手动从grep程序中删除了一些误报)。

./x86_64-linux-gnu/bits/posix1_lim.h:#define _POSIX_PATH_MAX      256
./X11/InitialI.h:#ifndef PATH_MAX
./X11/InitialI.h:#define PATH_MAX 512
./X11/InitialI.h:#ifndef PATH_MAX
./X11/InitialI.h:#define PATH_MAX MAXPATHLEN
./X11/InitialI.h:#define PATH_MAX 1024
./X11/Xos.h:#  define PATH_MAX 4096
./X11/Xwindows.h:#if defined(WIN32) && (!defined(PATH_MAX) || PATH_MAX < 1024)
./X11/Xwindows.h:# undef PATH_MAX
./X11/Xwindows.h:# define PATH_MAX 1024
./X11/Xosdefs.h:#  ifndef PATH_MAX
./X11/Xosdefs.h:#   define PATH_MAX 4096
./X11/Xosdefs.h:#  ifndef PATH_MAX
./X11/Xosdefs.h:#   define PATH_MAX 1024
./X11/extensions/XKBsrv.h:#define   PATH_MAX MAXPATHLEN
./X11/extensions/XKBsrv.h:#define   PATH_MAX 1024
./python2.7/osdefs.h:#ifndef PATH_MAX
./python2.7/osdefs.h:#define PATH_MAX MAXPATHLEN
./python2.7/osdefs.h:#if defined(PATH_MAX) && PATH_MAX > 1024
./python2.7/osdefs.h:#define MAXPATHLEN PATH_MAX
./linux/limits.h:#define PATH_MAX        4096   /* # chars in a path name including nul */
./linux/btrfs.h:#define BTRFS_INO_LOOKUP_PATH_MAX 4080
./linux/un.h:#define UNIX_PATH_MAX  108

头文件 /linux/limits.h 中包含的内容最丰富,应该是最正宗的。另一种策略是定义一个不同名称的自己的头文件,比如 PATHLEN(对于大多数实际情况来说,4080 已经足够长了)。我的主要观点是学会使用 find 命令来寻找你问题的答案。


3

PATH_MAX是一个系统限制。在POSIX环境中,存在三类与系统限制相关的分类。其中之一是路径名变量值。取决于文件系统的系统限制属于此类别。PATHMAX也是路径名变量值。(因此,该值可以从一个文件系统到另一个文件系统改变。) 因此,使用pathconf()/fpathconf() POSIX函数可以获取PATHNAME限制。这种方式是获得特定文件系统的PATHNAME限制的可移植方式。 示例代码如下:

long
get_pathmax(void)
{
  long pathmax = -1;

  errno = 0;
  pathmax = pathconf("/", _PC_PATH_MAX);
  if (-1 == pathmax)
  {
    if (0 == errno)
    {
#define PATHMAX_INFINITE_GUESS 4096
      pathmax = PATHMAX_INFINITE_GUESS;
    }
    else
    {
      fprintf (stderr, "pathconf() FAILED, %d, %s\n", errno, strerror(errno));
    }
  }

  return pathmax;
}

很有意思看看在Windows上pathconf("\\?\c$",_PC_PATH_MAX)返回了什么。(在Windows中以"\?"开头的文件名可以长达32K。显然,这从未是一项受欢迎的功能,而且对于Windows UNC文件名来说完全无用。) - Robin Davies

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接