一般如果你需要复制一个未知长度的字符串,使用strncpy复制到一个有大小限制的固定大小的缓冲区(但要注意如果字符串太长,则不终止字符串的不便行为。
或者使用 strdup 来 malloc 一个副本。
如您所知,PATH_MAX 是用于指示环境变量(在本例中为 PATH 变量)的最大大小的值
不,不是;与$PATH或环境无关!!
单个文件系统路径名的最大长度。例如/foo/bar/verylongdirectoryname/x/y.txt 的长度保证最多为 PATH_MAX。否则您可能无法使用绝对路径读取它,而必须将 chdir 改为该树并使用相对路径。
PATH 环境只是一个扁平字符串,就像任何其他 env var 一样;内核不会将它们剪辑到固定长度。或者当然不限于PATH_MAX。
如何在不发生溢出或数据丢失的假设下获得 PATH 环境变量
呃,你已经有了getenv("PATH")。这将返回一个指向进程内存空间中现有字符串的指针。它有效地在静态存储中;你不需要复制它,以后对getenv 的调用不会破坏指针。 (在 Linux 上,环境变量在进程启动时位于 argv 上方的堆栈中。在任何移动堆栈指针之前运行的 CRT 启动代码将指向它们的指针存储在全局 envp 中,getenv 稍后可以找到它。)
如果您想复制环境变量的缓冲区以便延长它,或者在不更改原始内容的情况下修改它,最简单的选择是strdup(3) from <string.h> 来分配一个副本。 (POSIX 2008,以及之前的 BSD、GNU C 和之前的各种其他系统)。或strndup 设置要复制的字节数限制。
GNU C 甚至有一个基于 alloca 而不是 malloc 的版本,以防您想要更便宜的临时自动存储。
PATH_MAX
PATH_MAX 与 getwd(3) 等 POSIX 函数相关,您可以在其中提供缓冲区但没有长度限制。 (但实际上您应该改用char *getcwd(char *buf, size_t size);请参阅与getwd 相同的链接。手册页还说:
请注意,在某些系统上,PATH_MAX
可能不是编译时常量;此外,它的价值可能取决于
在文件系统上,请参阅 pathconf(3)。
Linux readdir(3) 手册页没有这么说,但是 struct dirent 成员 char d_name[256]; /* Null-terminated filename */ 的大小是这样的,因为 PATH_MAX = 255。(或者更准确地说,PATH_MAX 是 255,因为 readdir 大小限制。)
此外,像 chdir(2) 或 open(2) 这样的系统调用允许在超过 PATH_MAX (ENAMETOOLONG) 的路径上失败:
ENAMETOOLONG
路径名或路径名的组成部分太长。
readlink(2) 采用缓冲区大小,因此不需要限制链接目标的长度;它只提到 ENAMETOOLONG 作为您提供的路径中的一个可能错误,而不是链接名称。
即使在现代 Linux 上,单个文件名的 255 个字节也是一个硬限制。但是 IIRC 它确实选择允许更长的路径名(具有多个目录组件)。 POSIX 规范对于长路径上的open() 不要求错误,因此操作系统可以提供相当小的 PATH_MAX,但在可能的情况下仍然适用于更长的路径。