system()函数字符串的长度限制

Cac*_*ito 10 c linux posix

字符串可以传递多长时间system()

我知道POSIX的最小值是4096,但我想知道可以使用的实际尺寸。是否在任何标头中定义了任何宏,类似于FILENAME_MAX

char cmd[SOME_MACRO];

...
system(cmd);
Run Code Online (Sandbox Code Playgroud)

PSk*_*cik 9

systemexec是带有参数的shell "sh","-c", YourAgumentToSystem, (char*)0由POSIX保证),因此最大长度(不计'\0'终止符)为ARG_MAX -1 -3 -3 - size_of_your_environment

ARG_MAXlimits.h中定义为

“ exec函数(包括环境数据)的最大参数长度。”

如果limits.h没有定义ARG_MAX,则应该可以调用 sysconf(_SC_ARG_MAX)以获得运行时限制。

execve的linux手册页(由系统调用)提供了更多信息:

在内核2.6.23之前的Linux上,用于存储环境和参数字符串的内存限制为32页(由内核常量MAX_ARG_PAGES定义)。在页面大小为4 kB的体系结构上,这产生的最大大小为128 kB。

在内核2.6.23及更高版本上,大多数体系结构都支持从execve()调用时生效的软RLIMIT_STACK资源限制(请参阅getrlimit(2))派生的大小限制。(不具有内存管理单元的体系结构除外:它们保持在内核2.6.23之前有效的限制。)此更改允许程序具有更大的自变量和/或环境列表。对于这些体系结构,总大小限制为允许的堆栈大小的1/4。(强加1/4限制可确保新程序始终具有一定的堆栈空间。)从Linux 2.6.25开始,内核在此大小限制下设置了32页的下限,因此,即使将RLIMIT_STACK设置得很低,保证应用程序至少具有与Linux 2.6.23及更早版本提供的一样多的参数和环境空间。

要测量环境的大小,可以运行:

extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;
Run Code Online (Sandbox Code Playgroud)

(正如Zan Lynx在评论中指出的那样,如果您假设char*指向environa 的指针,则可以加快速度(根据我的测量,大约为20倍-对于我在测量时使用的100字符串6KB环境,从1600ns到80ns)连续的缓冲区,这是他们一个程序启动后做,但通话setenvputenvunsetenv一般把这样的:

extern char **environ;
char **e; for(e=environ; *e; e++) {}
size_t envsz =  ($_sz)(e[-1]+strlen(e[-1])+1 - *environ);
Run Code Online (Sandbox Code Playgroud)

在任何情况下,如果您希望很快使用fork + exec(/ system),以健壮性为代价进行的加速都没什么大不了的,因为在现代Linux上,fork + exec的成本通常至少为1-2ms。机。)