putenv()/ setenv()は、ユーザースタック全体をシフトせずにどのように機能しますか?
私はここでいくつかの投稿を読みましたが、それでもどのようにsetenv()
機能するかについて混乱しています:
- linux-where-are-environment-variables-stored
- where-is-the-environment-string-actual-stored
- how-do-i-program-my-own-setenv
私の理解では、環境変数はユーザースタックの最下部に連続して「foo = bar \ 0」文字列の束として格納され、次にenvp[]
これらの文字列を指すポインタの配列があり、これも最下部にあります。ユーザースタック。ユーザースタックはこれらのバイトの上に大きくなります。つまり、文字列領域またはポインタ配列にさらに多くのものを追加することは簡単ではありません。したがってsetenv()
、新しい変数が設定された場合(に要素を追加する必要がある場合envp[]
)、または変数が変更されたが、新しい値の文字列が古い値の文字列よりも長い(インプレース変更が不可能になる)場合、(ほとんど)シフトせずにどのように機能しますか?新規参入者のためのスペースを作るためのユーザースタック全体?
やや関連する質問は、bash
ローカルに設定された変数の内部リストを保持し、ローカルに設定された変数をユーザーexport
がbash
このローカルに管理されたリストから削除し、上記のスタック文字列領域の下部に追加して、そのポインタをに挿入することです。envp[]
その子プロセスがエクスポートされた変数を自動的に継承するように、ポインタ配列?
回答
私の理解では、環境変数は次のように格納されます...
あなたの理解は部分的にしか正しくありません。:スマイル:
...ユーザースタック全体を(ほぼ)シフトせずに、新規参入者のためのスペースを確保しますか?
それは不可能でしょう。プログラムが書かれた言語がCであるか、オペレーティングシステムがUNIXであるかに関係なく。たとえば、スタック上のポインタはスタック上の他の場所を参照できるためです。
最初に注意することは、env変数が新しいプロセスに格納される場所はアーキテクチャに依存するということです。ほとんどのUNIX実装は、ほとんどのCPUアーキテクチャで、説明したようにスタックに格納します。しかし、C仕様には、その解決策を義務付ける文字通り何もありません。また、環境を変更した場合、実装は既存の環境変数のブロックをメモリ内の新しい場所に自由にコピーできます。C実装は、env変数のブロックを自由に移動し、魔法変数を更新でき__environ
ます。
やや関連する質問は、bashがローカルに設定された変数の内部リストを保持するかどうかです。
あなたが説明する方法ではありません。ローカルに設定された変数の「内部リスト」を保持します。しかし、それはあなたが提案する方法でそれを使用しません。
この号を開くきっかけとなった理由を知りたい