`getenv`, `getenv_s` 함수
getenv, getenv_s 함수 (getenv, getenv_s)
환경 변수는 프로그램 밖에서 동작을 조정할 수 있게 해 주는 창구예요. 예를 들어 PATH나 HOME 같은 값이 필요할 때 getenv로 그 값을 읽어 와요. 그냥 읽기만 하는 함수라 단순해 보이지만, 반환된 문자열을 어떻게 대해야 하는지가 미묘해서 그 부분을 꼭 짚어 볼게요.
출처: cppreference
본문
함수 원형
<stdlib.h>에 정의돼 있어요.
char *getenv( const char *name ); // (1)
errno_t getenv_s( size_t *restrict len, char *restrict value, // (2) (since C11)
rsize_t valuesz, const char *restrict name );
설명 (Explanation)
-
호스트가 제공하는 환경 목록에서 이름이
name인 환경 변수를 찾아, 그 변수에 연결된 문자열을 가리키는 포인터를 돌려줘요. 환경 변수의 집합과 그것을 바꾸는 방법은 구현 정의예요.이 함수는 스레드 안전이 보장되지 않아요.
getenv에 대한 다른 호출이나 POSIX의setenv(),unsetenv(),putenv()호출이 이전 호출이 돌려준 포인터를 무효화하거나 그 문자열을 수정할 수 있어요.getenv가 돌려준 문자열을 수정하면 동작이 정의되지 않아요(undefined behavior). -
(1)과 같지만, 환경 변수의 값을 사용자가 준 버퍼
value에 쓰고(value가 널이 아니면), 실제로 쓴 바이트 수를*len에 저장해요(len이 널이 아니면). 환경 변수가 설정되어 있지 않으면*len에0을 쓰고(len이 널이 아니면)value[0]에'\0'을 써요(value가 널이 아니면). 또한 다음 오류들을 실행 시 감지해 현재 설치된 제약 핸들러를 호출해요:name이 널 포인터valuesz가RSIZE_MAX보다 큼value가 널 포인터인데valuesz가 0이 아님
다른 모든 경계 검사 함수와 마찬가지로,
getenv_s는 구현이__STDC_LIB_EXT1__을 정의하고 사용자가<stdlib.h>를 포함하기 전에__STDC_WANT_LIB_EXT1__을 정수 상수1로 정의한 경우에만 사용할 수 있다는 점이 보장돼요.
매개변수 (Parameters)
name— 찾으려는 환경 변수의 이름을 나타내는 널 종료 문자열len—getenv_s가 환경 변수의 길이를 저장할 사용자 제공 위치를 가리키는 포인터value—getenv_s가 환경 변수 내용을 저장할 사용자 제공 문자 배열을 가리키는 포인터valuesz—getenv_s가 쓸 수 있는 최대 문자 수(버퍼 크기)
반환값 (Return value)
-
환경 변수의 값을 나타내는 문자열, 또는 해당 변수가 없으면 널 포인터.
-
환경 변수를 찾았으면
0, 찾지 못했거나 실행 제약 위반이 발생했으면 0이 아닌 값. 오류가 나면*len에0을 써요(len이 널 포인터가 아닌 경우).
주의할 점 (Notes)
POSIX에서는 환경 변수를 전역 변수 environ(<unistd.h>에 extern char **environ;로 선언)이나 main 함수의 선택적 세 번째 인자 envp로도 접근할 수 있어요.
value가 널 포인터이고 valuesz가 0인 getenv_s 호출은 전체 결과를 담는 데 필요한 버퍼 크기를 알아내는 용도로 쓰여요.
예제 (Example)
PATH 환경 변수의 값을 읽어 출력하는 간단한 예시예요.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
const char *name = "PATH";
const char *env_p = getenv(name);
if (env_p)
printf("Your %s is %s\n", name, env_p);
}
가능한 출력:
Your PATH is /home/gamer/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/share/games