GNU/Linux >> Znalost Linux >  >> Linux

omezení délky řetězce funkce system().

system exec je shell s argumenty "sh","-c", YourAgumentToSystem, (char*)0 (zaručeno POSIX), takže maximální délka (nepočítá se '\0'). terminátor) je ARG_MAX -1 -3 -3 - size_of_your_environment .

ARG_MAX je definováno v limitech.h jako

"Maximální délka argumentu funkcí exec včetně dat prostředí."

Pokud limits.h , nedefinuje ARG_MAX , měli byste být schopni zavolat sysconf(_SC_ARG_MAX) získat limit doby běhu.

Další informace poskytuje linuxová manuálová stránka pro execve (volaná systémem):

V Linuxu před jádrem 2.6.23 byla paměť používaná k ukládání řetězců prostředí a argumentů omezena na 32 stránek (definovaných konstantou jádra MAX_ARG_PAGES). Na architekturách s velikostí stránek 4 kB to poskytuje maximální velikost 128 kB.

V jádře 2.6.23 a novějších většina architektur podporuje omezení velikosti odvozené od měkkého limitu prostředků RLIMIT_STACK (viz getrlimit(2)), který je platný v době volání execve(). (Architektury bez jednotky správy paměti jsou vyjmuty:udržují si limit, který platil před jádrem 2.6.23.) Tato změna umožňuje programům mít mnohem větší seznam argumentů a/nebo prostředí. U těchto architektur je celková velikost omezena na 1/4 povolené velikosti zásobníku. (Uvedením 1/4-limitu zajistíte, že nový program bude mít vždy nějaké místo na zásobníku.) Od Linuxu 2.6.25 jádro umisťuje na tento limit velikosti 32 stránek, takže i když je RLIMIT_STACK nastaveno velmi nízko, aplikace jsou zaručeny mít alespoň tolik prostoru pro argumenty a prostředí, jaký poskytoval Linux 2.6.23 a starší. (Tato záruka nebyla poskytnuta v Linuxu 2.6.23 a 2.6.24.) Navíc je limit na řetězec 32 stránek (konstanta jádra MAX_ARG_STRLEN) a maximální počet řetězců je 0x7FFFFFFF.

Chcete-li změřit velikost vašeho prostředí, můžete spustit:

extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;

(Jak poukázal Zan Lynx v komentářích, lze to urychlit (cca 20krát podle mých měření – z 1600ns na 80ns pro 100-řetězcové 6KB prostředí, které jsem měl při měření), pokud předpokládáte char* ukazatele v environ ukazují na souvislou vyrovnávací paměť, což dělají po spuštění programu, ale volají setenv , putenv nebo unsetenv obvykle to porušte:

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

V každém případě by na zrychlení na úkor robustnosti nemělo moc záležet, pokud očekáváte, že fork+exec (/system) brzy, vzhledem k tomu, že fork+exec obvykle stojí alespoň kolem 1-2 ms na Linuxu na moderním stroj.)


Limit je vysoce závislý na systému. Může to dokonce záviset na příkazovém shellu, který bude použit. Měli byste otestovat návratovou hodnotu system() abyste zjistili, zda bylo systémové volání úspěšné:-1 znamená selhání a errno by vám měl poskytnout více informací. Chování by mělo být definováno pro jakýkoli správný řetězec C.

Dokumenty POSIX, které system(command) je ekvivalentní:

execl(<shell path>, "sh", "-c", command, (char *)0);

A také dokumenty ARG_MAX definováno v <limits.h> jako limit pro kombinované délky argumentů na exec a proměnné prostředí.

Všimněte si však, že command může obsahovat zástupné znaky a/nebo jiná shellová slova, jejichž expanze může překročit nějaký jiný limit. Vždy zkontrolujte návratovou hodnotu kvůli selhání.


Linux
  1. Jak najít délku struny v Bash [Rychlý tip]

  2. Limit paměti PHP

  3. Příklady manipulace s bashovým řetězcem – délka, podřetězec, najít a nahradit

  1. 13 Základní systémová volání Linuxu vysvětlena pomocí zábavného virového programu Linux

  2. Proč je moje funkce cat se systémovými voláními pomalejší ve srovnání s kočkou v Linuxu?

  3. in_addr_t do řetězce

  1. jak omezit délku řetězce přítomného v řádku pomocí linuxu

  2. Návratová hodnota x =os.system(..)

  3. Jaká je maximální délka uživatelského jména na současných systémech GNU/Linux