system
exec - оболочка с аргументами "sh","-c", YourAgumentToSystem, (char*)0
( гарантируется POSIX ), поэтому максимальная длина (не считая терминатора '\0'
) составляет ARG_MAX -1 -3 -3 - size_of_your_environment
.
ARG_MAX
определяется в limit.h как
"Максимальная длина аргумента для функций exec, включая данные среды."
Если limits.h
, не определяет ARG_MAX
, вы должны иметь возможность вызывать sysconf(_SC_ARG_MAX)
для получения лимита времени выполнения.
Страница Linux для execve (вызывается системой) предоставляет дополнительную информацию:
В Linux до ядра 2.6.23 объем памяти, используемой для хранения среды и строк аргументов, был ограничен 32 страницами (определяемыми константой ядра MAX_ARG_PAGES).На архитектурах с размером страницы 4 КБ это дает максимальный размер 128 КБ.
В ядре 2.6.23 и более поздних версиях большинство архитектур поддерживают ограничение размера, полученное из мягкого ограничения ресурса RLIMIT_STACK (см. Getrlimit (2)), который действует во время вызова execve ().(Архитектуры без модуля управления памятью исключаются: они поддерживают предел, который действовал до ядра 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 в комментариях, это можно ускорить (около 20в соответствии с моими измерениями - от 1600 нс до 80 нс для 100-струнной среды 6 КБ, которую я имел при измерении), если предположить, что указатели char*
в environ
указывают на непрерывный буфер, который они делают после запуска программы, но вызываютдо setenv
, putenv
или unsetenv
, как правило, ломайте это:
extern char **environ;
char **e; for(e=environ; *e; e++) {}
size_t envsz = ($_sz)(e[-1]+strlen(e[-1])+1 - *environ);
В любом случае, ускорение за счет надежности не должно иметь большого значения, если вы ожидаете раскошелиться+ exec (/ system) в ближайшее время, учитывая, что fork + exec обычно стоит минимум 1-2 мс в Linux на современной машине.)