system()函数字符串长度限制
system() function string length limit
一个字符串可以传递给system()
多长时间?
我知道 POSIX 最小值是 4096,但我想知道我可以使用的实际大小。是否在 header 中为此定义了任何宏,类似于 FILENAME_MAX
?
char cmd[SOME_MACRO];
...
system(cmd);
该限制高度依赖于系统。它甚至可能取决于将要使用的命令 shell。您应该测试 system()
的 return 值以查看系统调用是否成功:-1
表示失败,errno
应该会为您提供更多信息。应该为任何适当的 C 字符串定义行为。
POSIX 记录 system(command)
等同于:
execl(<shell path>, "sh", "-c", command, (char *)0);
还有文档 ARG_MAX
在 <limits.h>
中定义为 exec
的参数和环境变量的组合长度的限制。
但是请注意,command
可能包含通配符 and/or 其他 shell 扩展可能超过其他限制的单词。始终检查 return 值是否失败。
system
exec's a shell with arguments "sh","-c", YourAgumentToSystem, (char*)0
(guaranteed by POSIX), 所以
最大长度(不包括 '[=14=]'
终止符)是 ARG_MAX -1 -3 -3 - size_of_your_environment
.
ARG_MAX
在 limits.h 中定义为
"Maximum length of argument to the exec functions including
environment data."
如果limits.h
,没有定义ARG_MAX
,你should be able to call
sysconf(_SC_ARG_MAX)
获得 运行 时间限制。
execve(由系统调用)的 linux 联机帮助页提供了更多信息:
On Linux prior to kernel 2.6.23, the memory used to store the
environment and argument strings was limited to 32 pages (defined by
the kernel constant MAX_ARG_PAGES). On architectures with a 4-kB page
size, this yields a maximum size of 128 kB.
On kernel 2.6.23 and later, most architectures support a size limit
derived from the soft RLIMIT_STACK resource limit (see getrlimit(2))
that is in force at the time of the execve() call. (Architectures with
no memory management unit are excepted: they maintain the limit that
was in effect before kernel 2.6.23.) This change allows programs to
have a much larger argument and/or environment list. For these
architectures, the total size is limited to 1/4 of the allowed stack
size. (Imposing the 1/4-limit ensures that the new program always has
some stack space.) Since Linux 2.6.25, the kernel places a floor of 32
pages on this size limit, so that, even when RLIMIT_STACK is set very
low, applications are guaranteed to have at least as much argument and
environment space as was provided by Linux 2.6.23 and earlier. (This
guarantee was not provided in Linux 2.6.23 and 2.6.24.) Additionally,
the limit per string is 32 pages (the kernel constant MAX_ARG_STRLEN),
and the maximum number of strings is 0x7FFFFFFF.
要测量环境的大小,您可以 运行:
extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;
(正如 Zan Lynx 在评论中所指出的那样,这可以加快(根据我的测量结果,cca 20 倍——对于我测量时的 100 串 6KB 环境,从 1600ns 到 80ns)
如果您假设 environ
中的 char*
指针指向一个连续的缓冲区,它们在程序启动后执行,但调用 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 通常至少花费 1-2 毫秒左右Linux 在现代机器上。)
man 3 system
给我们
DESCRIPTION
The system() library function uses fork(2) to create a child process that executes the shell command specified in command
using execl(3) as follows:
execl("/bin/sh", "sh", "-c", command, (char *) 0);
system() returns after the command has been completed.
so system() is a wrapper for execl()
从同一页面我们也看到这个调用符合一些标准。
CONFORMING TO
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
提供以下内容
The number of bytes available for the new process' combined argument and environment lists is {ARG_MAX}. It is implementation-defined whether null terminators, pointers, and/or any alignment bytes are included in this total.
最后...
ERRORS
The exec functions shall fail if:
[E2BIG] The number of bytes used by the new process image's argument
list and environment list is greater than the system-imposed limit of
{ARG_MAX} bytes.
所以这里要执行的最后检查是实际的 exec 实现,而不是依赖标准以防万一实现偏离标准。
因此,man 3 execl
报告返回的错误与 execve(2)
的记录相同,man 2 execvw
报告如下:
ERRORS
E2BIG The total number of bytes in the environment (envp) and argument list (argv) is too large.
不如 POSIX 标准精确?最好检查代码或查看(现在)接受的答案:)
一个字符串可以传递给system()
多长时间?
我知道 POSIX 最小值是 4096,但我想知道我可以使用的实际大小。是否在 header 中为此定义了任何宏,类似于 FILENAME_MAX
?
char cmd[SOME_MACRO];
...
system(cmd);
该限制高度依赖于系统。它甚至可能取决于将要使用的命令 shell。您应该测试 system()
的 return 值以查看系统调用是否成功:-1
表示失败,errno
应该会为您提供更多信息。应该为任何适当的 C 字符串定义行为。
POSIX 记录 system(command)
等同于:
execl(<shell path>, "sh", "-c", command, (char *)0);
还有文档 ARG_MAX
在 <limits.h>
中定义为 exec
的参数和环境变量的组合长度的限制。
但是请注意,command
可能包含通配符 and/or 其他 shell 扩展可能超过其他限制的单词。始终检查 return 值是否失败。
system
exec's a shell with arguments "sh","-c", YourAgumentToSystem, (char*)0
(guaranteed by POSIX), 所以
最大长度(不包括 '[=14=]'
终止符)是 ARG_MAX -1 -3 -3 - size_of_your_environment
.
ARG_MAX
在 limits.h 中定义为
"Maximum length of argument to the exec functions including environment data."
如果limits.h
,没有定义ARG_MAX
,你should be able to call
sysconf(_SC_ARG_MAX)
获得 运行 时间限制。
execve(由系统调用)的 linux 联机帮助页提供了更多信息:
On Linux prior to kernel 2.6.23, the memory used to store the environment and argument strings was limited to 32 pages (defined by the kernel constant MAX_ARG_PAGES). On architectures with a 4-kB page size, this yields a maximum size of 128 kB.
On kernel 2.6.23 and later, most architectures support a size limit derived from the soft RLIMIT_STACK resource limit (see getrlimit(2)) that is in force at the time of the execve() call. (Architectures with no memory management unit are excepted: they maintain the limit that was in effect before kernel 2.6.23.) This change allows programs to have a much larger argument and/or environment list. For these architectures, the total size is limited to 1/4 of the allowed stack size. (Imposing the 1/4-limit ensures that the new program always has some stack space.) Since Linux 2.6.25, the kernel places a floor of 32 pages on this size limit, so that, even when RLIMIT_STACK is set very low, applications are guaranteed to have at least as much argument and environment space as was provided by Linux 2.6.23 and earlier. (This guarantee was not provided in Linux 2.6.23 and 2.6.24.) Additionally, the limit per string is 32 pages (the kernel constant MAX_ARG_STRLEN), and the maximum number of strings is 0x7FFFFFFF.
要测量环境的大小,您可以 运行:
extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;
(正如 Zan Lynx 在评论中所指出的那样,这可以加快(根据我的测量结果,cca 20 倍——对于我测量时的 100 串 6KB 环境,从 1600ns 到 80ns)
如果您假设 environ
中的 char*
指针指向一个连续的缓冲区,它们在程序启动后执行,但调用 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 通常至少花费 1-2 毫秒左右Linux 在现代机器上。)
man 3 system
给我们
DESCRIPTION
The system() library function uses fork(2) to create a child process that executes the shell command specified in command using execl(3) as follows:
execl("/bin/sh", "sh", "-c", command, (char *) 0); system() returns after the command has been completed.
so system() is a wrapper for
execl()
从同一页面我们也看到这个调用符合一些标准。
CONFORMING TO
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
提供以下内容
The number of bytes available for the new process' combined argument and environment lists is {ARG_MAX}. It is implementation-defined whether null terminators, pointers, and/or any alignment bytes are included in this total.
最后...
ERRORS
The exec functions shall fail if:
[E2BIG] The number of bytes used by the new process image's argument list and environment list is greater than the system-imposed limit of {ARG_MAX} bytes.
所以这里要执行的最后检查是实际的 exec 实现,而不是依赖标准以防万一实现偏离标准。
因此,man 3 execl
报告返回的错误与 execve(2)
的记录相同,man 2 execvw
报告如下:
ERRORS
E2BIG The total number of bytes in the environment (envp) and argument list (argv) is too large.
不如 POSIX 标准精确?最好检查代码或查看(现在)接受的答案:)