getenv() in my C++ apache/cgi gives me weird things, then I checked the environ inside /proc/${PID_OF_THE_RUNNING_PROCESS}, they did not match, which I think they should, I am wondering what was wrong with /proc or it was getenv()?
shell@kernel # xargs --null --max-args=1 echo < /proc/${PID_OF_THE_RUNNING_PROCESS}/environ
PATH=/usr/bin:/bin:/usr/sbin:/sbin
LD_LIBRARY_PATH=/usr/local/httpd-2.2.19/lib:
Code of PID_OF_THE_RUNNING_PROCESS
#include<stdio.h>
extern char **environ;
void run()
{
char* s = *environ;
printf("declare -x all env begin\n");
for (int i = 1; NULL != s; ++i) {
printf("declare -x %s\n", s);
s = *(environ+i);
}
printf("declare -x all env end\n");
}
Console log of PID_OF_THE_RUNNING_PROCESS
declare -x all env begin
declare -x FCGI_ROLE=RESPONDER
declare -x UNIQUE_ID=Wvq-Cn8AAAEAAAkmJlsAAAmM
declare -x HTTP_HOST=www.example.com
declare -x HTTP_X_CLIENT_PROTO=https
declare -x HTTP_X_CLIENT_PROTO_VER=HTTP/1.1
declare -x HTTP_X_REAL_IP=112.96.194.222
declare -x HTTP_X_FORWARDED_FOR=112.96.194.222
declare -x CONTENT_LENGTH=177
declare -x HTTP_CHARSET=utf-8
declare -x HTTP_ACCEPT_ENCODING=gzip
declare -x HTTP_REFERER=https://serviceexample.com/exbb58374cdce267a6/91/page-frame.html
declare -x CONTENT_TYPE=application/x-www-form-urlencoded
declare -x HTTP_USER_AGENT=Mozilla/5.0 (Linux; Android 5.1; vivo X6Plus D Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044030 Mobile Safari/537.36 MicroMessenger/6.6.6.1300(0x26060637) NetType/4G Language/zh_CN MicroMessenger/6.6.6.1300(0x26060637) NetType/4G Language/zh_CN
declare -x PATH=/usr/bin:/bin:/usr/sbin:/sbin
declare -x SERVER_SIGNATURE=
declare -x SERVER_SOFTWARE=Apache/2.2.19 (Unix) mod_ssl/2.2.19 OpenSSL/1.0.1t DAV/2 mod_fcgid/2.3.9
declare -x SERVER_NAME=www.example.com
declare -x SERVER_ADDR=10.241.94.209
declare -x SERVER_PORT=80
declare -x REMOTE_ADDR=10.56.81.214
declare -x DOCUMENT_ROOT=/data/doc/www.example.com/htdocs
declare -x SERVER_ADMIN=webmaster@tencent.com
declare -x SCRIPT_FILENAME=/data/doc/www.example.com/cgi-bin/ex/common/www_ex_time.cgi
declare -x REMOTE_PORT=46151
declare -x GATEWAY_INTERFACE=CGI/1.1
declare -x SERVER_PROTOCOL=HTTP/1.1
declare -x REQUEST_METHOD=POST
declare -x QUERY_STRING=
declare -x REQUEST_URI=/cgi-bin/ex/common/www_ex_time.cgi
declare -x SCRIPT_NAME=/cgi-bin/ex/common/www_ex_time.cgi
declare -x HTTP_CONNECTION=close
declare -x all env end
declare -x 112.96.194.222
The /proc/$pid/environ data shows the state of the env vars when the process started. If the environment vars were subsequently modified (e.g., via putenv()
) that will be reflected in the return value of getenv()
but not /proc/$pid/environ. You can see this in action by compiling and running the following program in one terminal and looking at its proc/.../environ in another terminal.
#include <stdio.h>
#include <stdlib.h>
int main() {
putenv("HOME=WTF");
char *home = getenv("HOME");
printf("pid %d HOME=%s\n", getpid(), home);
sleep(300);
}
P.S., Theoretically updates to the environ could be reflected in /proc/$pid/environ but in practice I'm not aware of any implementation which does so.