전역 변수 "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변수나 환경을 저장하기 위해 프로세스에서 사용하는 데이터 구조에 대해 알지 못합니다 .

관련 정보