GNU/Linux >> Linux の 問題 >  >> Linux

system() 関数の文字列の長さ制限

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) を呼び出すことができるはずです ランタイム制限を取得します。

execve (システムによって呼び出される) の Linux マンページには、詳細情報が記載されています。

<ブロック引用>

カーネル 2.6.23 より前の Linux では、環境と引数の文字列を格納するために使用されるメモリは 32​​ ページ (カーネル定数 MAX_ARG_PAGES で定義) に制限されていました。ページサイズが 4 kB のアーキテクチャでは、最大サイズは 128 kB になります。

カーネル 2.6.23 以降では、ほとんどのアーキテクチャが、execve() 呼び出し時に有効なソフト RLIMIT_STACK リソース制限 (getrlimit(2) を参照) から派生したサイズ制限をサポートしています。 (メモリ管理ユニットのないアーキテクチャは例外です。カーネル 2.6.23 より前に有効だった制限を維持します。) この変更により、プログラムはより大きな引数や環境リストを持つことができます。 searchitectures の場合、合計サイズは許可されたスタックサイズの 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 がコメントで指摘しているように、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);

いずれにせよ、fork+exec (/system) がすぐに実行されることを期待している場合、堅牢性を犠牲にして高速化しても大した問題にはならないはずです。


制限はシステムに大きく依存します。使用するコマンド シェルに依存する場合もあります。 system() の戻り値をテストする必要があります システムコールが成功したかどうかを確認するには:-1 失敗を意味し、errno より多くの情報を提供する必要があります。動作は、適切な C 文字列に対して定義する必要があります。

system(command) の POSIX ドキュメント と同等です:

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

ARG_MAX のドキュメントも <limits.h> で定義 exec までの引数の合計長の制限として および環境変数。

ただし、command に注意してください。 ワイルドカードやその他のシェル ワードが含まれている可能性があり、その拡張は他の制限を超える可能性があります。失敗の戻り値を常にチェックしてください。


Linux
  1. Linux の cat に比べて、システム コールを使用した cat 関数が遅いのはなぜですか?

  2. Linuxを使用して行に存在する文字列の長さを制限する方法

  3. x =os.system(..) の戻り値

  1. システムログNG

  2. Bashで文字列の長さを見つける方法[クイックヒント]

  3. unix/linux システムでのパスワードの最大長は?

  1. PHPのメモリ制限

  2. Bash 文字列操作の例 – 長さ、部分文字列、検索と置換

  3. 楽しいLinuxウイルスプログラムを使用して説明された13の基本的なLinuxシステムコール