Linux中PATH_MAX在哪里定义?


112

我应该调用哪个头文件#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?



18
您可能想要char current_path[PATH_MAX];而不是char *current_path[PATH_MAX];-您想要一个字符串而不是一个指针数组。
约翰·卡特

Answers:


134

它在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)


23
以下是有关PATH_MAX的良好链接……以及为什么它不是这样的insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
paulsm4 2012年

等待...这是否意味着PATH_MAX是特定于Linux的并且不属于任何标准?
爱德华·福克

6
您可能应该使用<limits.h>;。<linux / limits.h>看起来显然不可移植。
爱德华·福克

4
当心:PATH_MAX与NAME_MAX是不同的(并且x-ref'd文章似乎至少部分混淆了这两者)。注意:POSIX <limits.h>表示:标头[…]中应省略以下列表中一个符号常量的定义,其中<limits.h>对应值等于或大于指定的最小值,但该值可以根据文件而有所不同适用于它。特定路径名支持的实际值应由pathconf()函数提供。
乔纳森·莱夫勒

1
路径名非常邪恶,不安全,而path_max只是一个谎言,甚至不是一个常量(在不同的OS功能上可能有所不同)。这是一个可怕的功能,应尽快替换。
Lothar

13

请注意,尚不清楚是否PATH_MAX定义最大长度(带或不带尾随nul字节)。在不同的操作系统上可能是一个或另一个。如果您不能或不想在编译过程中检查哪种情况,则人为限制的安全性更高PATH_MAX - 1。安全胜过遗憾。(显然,您仍然需要保留至少PATH_MAX字节的内存来缓冲字符串。)


4
> {PATH_MAX}路径名中的最大字节数,包括终止的空字符。从POSIX '01。
muh karma 2014年

8
请注意,POSIX 2008解决了这种混乱— <limits.h>(Rationale):{PATH_MAX} IEEE PASC解释1003.1#15使用路径名的定义和{PATH_MAX}的描述解决了标准中的不一致之处,允许应用程序开发人员分配{PATH_MAX}或{PATH_MAX} +1个字节。通过更正{PATH_MAX}定义以包含空字符,已消除了不一致的情况。进行此更改后,先前分配了{PATH_MAX}个字节的应用程序将继续成功。
乔纳森·莱夫勒

1
另请注意,您不应使用PATH_MAX - 1,而应使用PATH_MAX + 1。您不必再这样做了,但是您想为加上一个字节'\0'
亚历克西斯·威尔克

1
PATH_MAX是为什么人们认为Windows很烂的原因,而实际上只有程序员使用PATH_MAX很烂。在Windows上,PATH_MAX实际上至少为32k,而您几乎永远都不想声明PATH_MAX为32k。
Lothar

7

便携式的方法是:

#define _POSIX_C_SOURCE 1
#include <limits.h>

规格:https//pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html


甚至还不够。 PATH_MAX不必定义:“ 在相应值等于或大于所述最小值的特定实现上,应从标题中省略以下列表中符号常量之一的定义<limits.h>,但该值可以根据在要应用该文件的文件上。该pathconf()功能应提供特定路径名支持的实际值。” 如果Linux文件系统支持不同的值,则可能违反了Linux定义的POSIX标准PATH_MAX
安德鲁·亨利

1

在执行简单的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足够长)。我的主要观点是学习使用查找来寻找问题的答案。


0

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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.