正如您所知道的,PATH_MAX是用于指示环境变量(在本例中为PATH变量)的最大大小的值,但在大多数情况下并不是这样的。看看这段用于将环境变量复制到大小为PATH_MAX的数组中的代码
char env[PATH_MAX];
strcpy(path, getenv("PATH"));如果您可以看到它可以如此容易地溢出,人们会说使用strncpy可以避免溢出,但是如果您使用它并且PATH很大,那么MAX_PATH我们将无法获得完整的PATH环境变量,这让我思考,如何在假设不会溢出或丢失数据的情况下获得路径环境变量
发布于 2019-07-07 18:25:46
通常,如果您需要复制长度未知的字符串,请使用strncpy将其复制到有大小限制的固定大小的缓冲区中(但要注意,如果字符串太长,则不终止字符串的不便行为)。
或者使用strdup对副本进行malloc。
如您所知,
PATH_MAX是用于指示环境变量(在本例中为PATH变量)的最大大小的值。
不,它不是;它与$PATH或环境无关!!
它是单个文件系统路径名的最大长度。例如,保证/foo/bar/verylongdirectoryname/x/y.txt的长度最多为PATH_MAX。
PATH环境只是一个简单的字符串,就像任何其他环境变量一样;内核不会将它们裁剪成固定的长度。或者肯定不会被限制在PATH_MAX。
如何在假设没有溢出或数据丢失的情况下获得PATH环境变量
Uh,你已经在 getenv("PATH").上有了它返回一个指向进程内存空间中现有字符串的指针。它实际上是在静态存储中;您不需要复制它,将来对getenv的调用也不会破坏指针。(在Linux上,env var在进程启动时位于argv之上的堆栈中。在移动堆栈指针之前运行的CRT启动代码在全局envp中存储指向堆栈指针的指针,getenv稍后可以在全局CRT中找到该指针。)
如果你想复制一个环境变量的缓冲区,这样你就可以加长它,或者修改它而不改变原始文件,最简单的选择是 来malloc一个副本.(POSIX2008,以及之前的BSD和之前的各种系统)。或strndup来设置要复制的字节数限制。
GNU C甚至有一个基于alloca而不是malloc的版本,以防你想要一个更便宜的临时自动存储。
PATH_MAX
PATH_MAX 是相关的,例如,在像 这样的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。(或者更准确地说,由于readdir大小的限制,PATH_MAX是255。)
此外,允许chdir(2)或open(2)等系统调用在比PATH_MAX (ENAMETOOLONG)更长的路径上失败:
ENAMETOOLONG
路径名或路径名的组成部分太长。
readlink(2)采用缓冲区大小,因此它不需要限制链接目标的长度;它只提到ENAMETOOLONG是您提供的路径中可能出现的错误,而不是链接名称。
即使在现代Linux上,单个文件名的255个字节也是一个硬限制。但IIRC它确实选择允许更长的路径名(具有多个目录组件)。
发布于 2019-07-07 18:06:01
避免假设$PATH已定义或长度有限是您问题的解决方案,并使用如下所示的通用代码。
char *path = NULL;
const char *temp = getenv("PATH");
if (temp != NULL) {
path = (char*) malloc(strlen(temp) + 1);
if (path == NULL) {
/* Handle error condition */
} else {
strcpy(path, temp);
}
/* Use path */
}https://stackoverflow.com/questions/56921129
复制相似问题