07
exec ist eine Shell mit den Argumenten 16
(garantiert durch POSIX), also die maximale Länge (ohne Berücksichtigung der 28
Abschlusszeichen) ist 30
.
47
ist in limits.h als
"Maximale Länge des Arguments für die Ausführungsfunktionen, einschließlich Umgebungsdaten."
Wenn 57
, definiert 64
nicht , sollten Sie 72
anrufen können um ein Laufzeitlimit zu erhalten.
Die Linux-Manpage für execve (vom System aufgerufen) bietet weitere Informationen:
Unter Linux vor Kernel 2.6.23 war der zum Speichern der Umgebungs- und Argumentzeichenfolgen verwendete Speicher auf 32 Seiten begrenzt (definiert durch die Kernelkonstante MAX_ARG_PAGES). Auf Architekturen mit einer Seitengröße von 4 KB ergibt dies eine maximale Größe von 128 KB.
Unter Kernel 2.6.23 und höher unterstützen die meisten Architekturen eine Größenbegrenzung, die von der weichen RLIMIT_STACK-Ressourcenbegrenzung (siehe getrlimit(2)) abgeleitet ist, die zum Zeitpunkt des Aufrufs von execve() in Kraft ist. (Ausgenommen sind Architekturen ohne Speicherverwaltungseinheit:Sie behalten das Limit bei, das vor Kernel 2.6.23 galt.) Diese Änderung ermöglicht es Programmen, eine viel größere Argument- und/oder Umgebungsliste zu haben. Für die Suchstrukturen ist die Gesamtgröße auf 1/4 der zulässigen Stapelgröße begrenzt. (Das Auferlegen des 1/4-Limits stellt sicher, dass das neue Programm immer etwas Stack-Speicherplatz hat.) Seit Linux 2.6.25 legt der Kernel eine Untergrenze von 32 Seiten auf diese Größenbegrenzung, so dass Anwendungen garantiert sind, selbst wenn RLIMIT_STACK sehr niedrig eingestellt ist mindestens so viel Platz für Argumente und Umgebungen zu haben wie Linux 2.6.23 und früher. (Diese Garantie wurde in Linux 2.6.23 und 2.6.24 nicht bereitgestellt.) Außerdem beträgt die Begrenzung pro Zeichenfolge 32 Seiten (die Kernelkonstante MAX_ARG_STRLEN) und die maximale Anzahl von Zeichenfolgen 0x7FFFFFFF.
Um die Größe Ihrer Umgebung zu messen, können Sie Folgendes ausführen:
extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;
(Wie Zan Lynx in den Kommentaren darauf hingewiesen hat, kann dies beschleunigt werden (ca. 20-mal gemäß meinen Messungen – von 1600 ns auf 80 ns für die 100-String-6-KB-Umgebung, die ich beim Messen hatte), wenn Sie den 87
91
zeigen auf einen zusammenhängenden Puffer, was sie tun, nachdem ein Programm gestartet wurde, rufen aber 104
auf , 116
, oder 123
In der Regel bricht dies:
extern char **environ;
char **e; for(e=environ; *e; e++) {}
size_t envsz = ($_sz)(e[-1]+strlen(e[-1])+1 - *environ);
In jedem Fall sollte die Beschleunigung auf Kosten der Robustheit keine große Rolle spielen, wenn Sie bald Fork+Exec (/system) erwarten, da Fork+Exec unter Linux auf einem modernen System normalerweise mindestens 1-2 ms kostet Maschine.)
Die Grenze ist stark systemabhängig. Es kann sogar von der verwendeten Befehlsshell abhängen. Sie sollten den Rückgabewert von 136
testen um zu sehen, ob der Systemaufruf erfolgreich war:144
bedeutet Fehler und 154
sollte dir mehr infos geben. Das Verhalten sollte für jeden geeigneten C-String definiert werden.
POSIX dokumentiert das 169
entspricht:
execl(<shell path>, "sh", "-c", command, (char *)0);
Und auch Dokumente 177
definiert in 187
als Grenze für die kombinierte Länge der Argumente auf 195
und die Umgebungsvariablen.
Beachten Sie jedoch, dass 209
kann Platzhalter und/oder andere Shell-Wörter enthalten, deren Erweiterung einige andere Grenzen überschreiten kann. Überprüfen Sie immer den Rückgabewert auf Fehler.