我們在實現CGI程序的時候,有時候會用setenv設置環境變量傳遞給子進程。那麼父進程是怎麼傳遞給子進程的呢?
[cpp]
//father.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include<sys/types.h>
extern char **environ;
int main()
{
char *str = "Hello From Father";
char *emptylist[] = { NULL, };
char *filename = "./child";
if(fork() == 0)
{
setenv("QUERY_STRING",str,1);
if (execve(filename, emptylist, environ) < 0)
{
printf("Execve error");
}
}
wait(NULL);
return 0;
}
[cpp]
//child.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
printf("this is in son process\n");
char *p2 = (char *)getenv("QUERY_STRING");
if ( p2 )
printf("%s\n",p2);
return 0;
}
extern char **environ
這句話指向的就是環境變量的字符串數組。
libc中定義的全局變量environ指向環境變量表,environ沒有包含在任何頭文件中,所以在使用時要用extern聲明。要是沒有extern就會無法在子進程中獲取環境變量。下面看一個environ獲取環境變量獲取的例子:
[cpp]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include<sys/types.h>
extern char **environ;
int main()
{
char **p = environ;
while (*p != NULL)
{
printf("%s (%p)\n", *p, *p);
*p++;
}
return 0;
}
另外還要注意的一點就是,在setenv設置環境變量的時候是不能隨便設置的,比如你要設置HOLLO=“hello”,這是不行的。為什麼呢?調用fork產生子進程的時候,子進程會做一份父進程環境變量的拷貝,因為前面說了,拷貝就是通過environ來實現的,而environ是已經定義好的了。你要是非想用setenv傳遞環境變量,那麼就只能用系統的環境變量來作為臨時交換進行傳遞