system
exec adalah shell dengan argumen "sh","-c", YourAgumentToSystem, (char*)0
(dijamin oleh POSIX), jadi panjang maksimum (tidak termasuk '\0'
terminator) adalah ARG_MAX -1 -3 -3 - size_of_your_environment
.
ARG_MAX
didefinisikan dalam limit.h sebagai
"Panjang maksimum argumen untuk fungsi exec termasuk data lingkungan."
Jika limits.h
, tidak mendefinisikan ARG_MAX
, Anda seharusnya dapat memanggil sysconf(_SC_ARG_MAX)
untuk mendapatkan batas runtime.
Halaman manual linux untuk execve (dipanggil oleh sistem) memberikan informasi lebih lanjut:
Di Linux sebelum kernel 2.6.23, memori yang digunakan untuk menyimpan string argumen dan lingkungan dibatasi hingga 32 halaman (ditentukan oleh konstanta kernel MAX_ARG_PAGES). Pada arsitektur dengan ukuran halaman 4 kB, ini menghasilkan ukuran maksimum 128 kB.
Pada kernel 2.6.23 dan yang lebih baru, sebagian besar arsitektur mendukung batas ukuran yang diturunkan dari batas sumber daya lunak RLIMIT_STACK (lihat getrlimit(2)) yang berlaku pada saat panggilan execve(). (Arsitektur tanpa unit manajemen memori dikecualikan:mereka mempertahankan batas yang berlaku sebelum kernel 2.6.23.) Perubahan ini memungkinkan program memiliki argumen dan/atau daftar lingkungan yang jauh lebih besar. Untuk struktur pencarian, ukuran total dibatasi hingga 1/4 dari ukuran tumpukan yang diizinkan. (Memaksakan 1/4-batas memastikan bahwa program baru selalu memiliki beberapa ruang stack.) Sejak Linux 2.6.25, kernel menempatkan lantai 32 halaman pada batas ukuran ini, sehingga, bahkan ketika RLIMIT_STACK diatur sangat rendah, aplikasi dijamin untuk memiliki setidaknya ruang argumen dan lingkungan sebanyak yang disediakan oleh Linux 2.6.23 dan sebelumnya. (Jaminan ini tidak disediakan di Linux 2.6.23 dan 2.6.24.) Selain itu, batas per string adalah 32 halaman (konstanta kernel MAX_ARG_STRLEN), dan jumlah maksimum string adalah 0x7FFFFFFF.
Untuk mengukur ukuran lingkungan Anda, Anda dapat menjalankan:
extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;
(Seperti yang ditunjukkan oleh Zan Lynx di komentar, ini dapat dipercepat (cca 20 kali sesuai pengukuran saya—dari 1600ns menjadi 80ns untuk lingkungan 6KB 100-string yang saya miliki saat mengukur) jika Anda mengasumsikan char*
pointer di environ
menunjuk ke buffer yang berdekatan, yang mereka lakukan setelah program dimulai, tetapi memanggil setenv
, putenv
, atau unsetenv
biasanya merusak ini:
extern char **environ;
char **e; for(e=environ; *e; e++) {}
size_t envsz = ($_sz)(e[-1]+strlen(e[-1])+1 - *environ);
Bagaimanapun, kecepatan dengan biaya ketahanan seharusnya tidak terlalu menjadi masalah jika Anda mengharapkan untuk fork+exec (/ sistem) segera, mengingat bahwa fork+exec biasanya biaya setidaknya sekitar 1-2ms di Linux pada sistem modern mesin.)
Batasnya sangat bergantung pada sistem. Bahkan mungkin tergantung pada command shell yang akan digunakan. Anda harus menguji nilai kembalian dari system()
untuk melihat apakah panggilan sistem berhasil:-1
berarti kegagalan dan errno
harus memberi Anda lebih banyak informasi. Perilaku harus ditentukan untuk setiap string C yang tepat.
Dokumen POSIX yang system(command)
setara dengan:
execl(<shell path>, "sh", "-c", command, (char *)0);
Dan juga mendokumentasikan ARG_MAX
didefinisikan dalam <limits.h>
sebagai batas panjang gabungan argumen ke exec
dan variabel lingkungan.
Namun perhatikan bahwa command
mungkin berisi wildcard dan/atau kata shell lain yang perluasannya mungkin melebihi batas lainnya. Selalu periksa nilai pengembalian untuk kegagalan.