환경변수에 관하여

bluesoho의 이미지

putenv, setenv, unsetenv등 합수로 환경변수를 개변하여도 environ이 가리키는 원 환경변수는 변하지 않는다고 알고있습니다
그런데 이상한 일이 발생하는 군요, 무슨 영문인지 몰라서 지도를 바랍니다
아래의 코드에서 comment한 부분이 있을때와 없을때 전혀 다른 결과가 나옵니다

#include <stdio.h>
#include <stdlib.h>

extern char **environ;

int main(int argc, const char **argv, const char **envp)
{
/*
while(*environ)
puts(*environ++);
puts("\n----------------------\n");
*/

printf("HOME=%s\n", getenv("HOME"));
putenv("HOME=/usr/kingsoho");
printf("HOME=%s\n", getenv("HOME"));
setenv("HOME", "/usr/bluesoho/kim", 1);
printf("HOME=%s\n", getenv("HOME"));
unsetenv("HOME");
if(!getenv("HOME"))
puts("HOME has been deleted");

printf("\n--------------------------------\n");

while(*envp)
puts(*envp++);

return 0;
}

cdpark의 이미지

comment한 부분이 외부변수 environ 값을 바꾸네요. 당연히 어떤 side effect가 있겠죠?

vinus의 이미지

while(*environ) 
puts(*environ++); 

에서 환경변수의 포인트를 증가 시켜 두고 다시 복원을 하지 않아서 발생하는 문제 입니다.

char ** lenv;

lenv=environ;
while(*environ) 
       puts(*environ++); 
environ=lenv
;

정도로 하시던지..

while(*environ) 
    puts(*environ++); 
environ=envp;

이렇게 해주셔야 할 것 같으네요.

>>>행복한 웃음<<<

vness의 이미지

cdpark 님의 글에 첨언하자면..

environ 과 envp는 동일한 주소를 가지고 있는 포인터입니다.(아시겠지만...)

하지만 getenv와 setenv, unsetenv는 모두 environ 변수의 주소값과 관련이 깊은 함수들입니다.
environ 변수의 주소값에서부터 인자로 넘어가는 환경변수를 찾으려고 하는거죠.

comment 하신 부분에서 environ이 담고있는 주소값을 변경시켰기 때문에 발생하는 문제입니다.


while(*environ)
puts(*environ++);
puts("\n----------------------\n");

부분 다음에

environ = (char **)envp;

를 해준다음 프로그램을 수행하시면 동일한 결과가 나타남을 보실 수 있으실 겁니다.

bluesoho의 이미지

setenv, putenv, unsetenv등함수를 수행한후 environ이 가리키는 환경변수도 따라서 변하는 겁니까?

vinus의 이미지

setenv, putenv, unsetenv등함수를 수행한후 environ이 가리키는 환경변수도 따라서 변하는 겁니까?

environ이라는 변수는 unistd.h인가에 선언 되어 있습니다.
이 변수의 역할은 현재 실행되는 프로그램의 환경변수들을 저장 하는
역할을 합니다.

위의 환경 변수 관련 함수들을 호출 하게 되면, environ이라는 변수에서
환경변수를 하나 추가, 삭제, 변경의 기능을 하게 됩니다.

environ이라는 변수에 저장되어 있는 값이 변경 된다는 것은 현재 실행중에
있는 프로그램이 참조 하는 환경변수의 값이 변경된다는 말과 같습니다.

>>>행복한 웃음<<<

cdpark의 이미지

char ** lenv; 

lenv=environ; 
while(*lenv) 
       puts(*lenv++); 

라고 해야 조금 더 안전하겠죠?
bluesoho의 이미지

고맙습니다. ^_^

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.