グローバル変数「environ」を介してアクセスされる文字列は、環境への変更を反映しませんか?

グローバル変数「environ」を介してアクセスされる文字列は、環境への変更を反映しませんか?

~からhttps://unix.stackexchange.com/a/436631/674

ファイル/proc/$$/environ...は、環境への変更を反映せず、単にexecプロセスで編集したときにプログラムが受信した内容を報告します。

APUEから:

各プログラムには環境リストも渡されます。引数リストと同様に、環境リストは文字ポインタの配列であり、各ポインタはnullで終わるC文字列のアドレスを含みます。ポインタ配列のアドレスはグローバル変数に含まれていますenviron

extern char **environ;

特定の環境変数へのアクセスは通常、環境変数ではなく、getenv関数(セクション7.9で説明されている)を介して行われます。putenvただし、環境全体をナビゲートするにはenvironポインタを使用する必要があります。

/proc/$$/environenviron それらは互いに独立していますか、それともグローバル変数と一致しますか?

を介してアクセスされた文字environ列も環境への変更を反映しませんが、receiveを介して環境のみを報告しますか execve()

それとも、常に最新の環境文字列を取得するかのように、アクセスする文字列はenviron常に変更を反映していますか?getenv

を介してアクセスされる文字列は getenv常に変更を反映し、常に最新の状態ですか?

ありがとうございます。

答え1

/proc/$$/environそして変数はenviron独立しています。実際、環境変数がenvironポインタ値を介して環境に追加されると、変更も変更されます(ただし、これは実装の詳細です)。environputenv()

システムコールレベルとライブラリレベルを区別する必要があります。システムコールレベルでは、環境に関連する唯一のメカニズムは呼び出しenvpのパラメータですexecve。このパラメーターname=valueには、新しいプログラム環境を構成するペアが含まれると予想されます。環境は、ユーザースペースの開始コードが選択できる新しいプロセスのスタックにコピーされます。

図書館レベルでは、

  • environ環境コピーを指すグローバル変数
  • 機能性検査getenv()putenv()修正環境
  • 暗黙的に(渡す)または明示的に(パラメータを介して渡す)環境にアクセスする一連のexec*関数(含まれていません)execveenviron

ライブラリexec*関数は最終的にexecveシステムコールを呼び出します。変数environはスタックの環境を指しません。代わりに、environ変数が設定される前に環境がプロセスヒープにコピーされます。これは再実装の詳細です。

/proc/$$/environなぜ環境変化を反映できないのでしょうか?/proc/$$/environカーネルが提供する仮想ファイルなので、カーネルはユーザープロセスのアドレス空間の下位レベルで何が起こっているのかわかりません。カーネルは、このenviron変数や環境を保存するためにプロセスが使用するデータ構造について知りません。

関連情報