system()函数字符串长度限制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了system()函数字符串长度限制相关的知识,希望对你有一定的参考价值。
字符串传递给system()
多长时间?
我知道POSIX最小值是4096,但我想知道我可以使用的实际大小。是否有任何标题中定义的宏,类似于FILENAME_MAX
?
char cmd[SOME_MACRO];
...
system(cmd);
system
exec是一个带有参数"sh","-c", YourAgumentToSystem, (char*)0
(guaranteed by POSIX)的shell,所以最大长度(不包括' '
终结符)是ARG_MAX -1 -3 -3 - size_of_your_environment
。
ARG_MAX
在limits.h中被定义为
“exec函数的最大参数长度,包括环境数据。”
如果limits.h
,没有定义ARG_MAX
,你should be able to call 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及更早版本提供的参数和环境空间。 (Linux 2.6.23和2.6.24中未提供此保证。)此外,每个字符串的限制为32页(内核常量MAX_ARG_STRLEN),最大字符串数为0x7FFFFFFF。
要衡量环境的大小,您可以运行:
extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;
(正如Zan Lynx在评论中指出的那样,如果你假设在char*
指向的environ
指针,这可以加速(根据我的测量结果为20倍 - 从测量时的100弦6KB环境从1600ns到80ns)一个连续的缓冲区,它们在程序启动后执行,但调用setenv
,putenv
或unsetenv
通常会打破这个:
extern char **environ;
char **e; for(e=environ; *e; e++) {}
size_t envsz = ($_sz)(e[-1]+strlen(e[-1])+1 - *environ);
在任何情况下,如果您希望尽快使用fork + exec(/ system),那么以鲁棒性为代价的加速速度应该不会太大,因为fork + exec在Linux上通常至少需要1-2毫秒的现代成本机。)
该限制高度依赖于系统。它甚至可能取决于将要使用的命令shell。您应该测试system()
的返回值以查看系统调用是否成功:-1
表示失败,errno
应该为您提供更多信息。应该为任何正确的C字符串定义行为。
POSIX证明system(command)
相当于:
execl(<shell path>, "sh", "-c", command, (char *)0);
还有ARG_MAX
中定义的文件<limits.h>
作为exec
和环境变量的参数组合长度的限制。
但请注意,command
可能包含通配符和/或其他shell语言,其扩展可能会超出其他限制。始终检查失败的返回值。
男人3系统
给我们
描述
system()库函数使用fork(2)创建一个子进程,该进程使用execl(3)执行命令中指定的shell命令,如下所示:
execl("/bin/sh", "sh", "-c", command, (char *) 0); system() returns after the command has been completed.
所以system()是
execl()
的包装器
从同一页面我们也看到此调用符合某些标准。
符合
POSIX.1-2001,POSIX.1-2008,C89,C99。
查找POSIX.1-2008会产生以下在线参考
https://pubs.opengroup.org/onlinepubs/9699919799/
我们可以在哪里搜索execl
函数的信息,系统将我们带到哪里
https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
其中提供了以下内容
可用于新进程的组合参数和环境列表的字节数为{ARG_MAX}。实现定义是否在此总计中包含空终止符,指针和/或任何对齐字节。
最后......
错误
如果出现以下情况,exec函数将失败
[E2BIG]新进程映像的参数列表和环境列表使用的字节数大于系统强加的{ARG_MAX}字节限制。
因此,在这里执行的最终检查是实际的exec实现,而不是仅仅在实现偏离标准的情况下依赖于标准。
因此,man 3 execl
报告返回的错误与execve(2)
记录的相同,man 2 execvw
报告如下:
错误
E2BIG环境中的总字节数(envp)和参数列表(argv)太大。
不像POSIX标准那么精确?最好检查代码或看到(现在)接受的答案:)
以上是关于system()函数字符串长度限制的主要内容,如果未能解决你的问题,请参考以下文章
用javascript编写一个字符串验证函数,要求输入字符长度限制6至20个任意字符且至少包含三个字母
2021-12-24:划分字母区间。 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。 力扣763。某大厂面试