linux环境变量
来源:互联网 发布:农村淘宝服务站点查询 编辑:程序博客网 时间:2024/06/10 17:46
一 环境变量的作用
使用环境变量的好处是:不用重新编译源程序即可通过环境变量可以改变程序的行为。
二 实现原理
char **__environ = 0;
weak_alias(__environ, environ)
weak_alias(__environ, environ)
__environ 是libc中定义的char **类型指针变量,初始化过程:
__uClibc_main()
{
...........
/* The environment begins right after argv. */
__environ = &argv[argc + 1];
__environ = &argv[argc + 1];
..........
result = main (argc, argv, __environ);
}
应用添加环境变量通过setenv()函数:
int setenv(const char *name, const char *value, int replace)
{
/* NB: setenv("VAR", NULL, 1) inserts "VAR=" string */
return __add_to_environ(name, value ? value : "", replace);
}
{
/* NB: setenv("VAR", NULL, 1) inserts "VAR=" string */
return __add_to_environ(name, value ? value : "", replace);
}
static int __add_to_environ(const char *name, const char *value,
int replace)
int replace)
{
ep = __environ;
size = 0;
if (ep != NULL) {
while (*ep != NULL) {
if (!strncmp(*ep, name, namelen) && (*ep)[namelen] == '=') {
/* Found */
if (!replace)
goto DONE_OK;
goto REPLACE;
}
++size;
++ep;
}
}
size = 0;
if (ep != NULL) {
while (*ep != NULL) {
if (!strncmp(*ep, name, namelen) && (*ep)[namelen] == '=') {
/* Found */
if (!replace)
goto DONE_OK;
goto REPLACE;
}
++size;
++ep;
}
}
/* Not found, add at the end */
/* We allocated this space; we can extend it. */
new_environ = realloc(last_environ, (size + 2) * sizeof(char *));
if (new_environ == NULL) {
__set_errno(ENOMEM);
goto DONE;
}
if (__environ != last_environ) {
memcpy(new_environ, __environ, size * sizeof(char *));
}
last_environ = __environ = new_environ;
ep = &new_environ[size];
/* Ensure env is NULL terminated in case malloc below fails */
ep[0] = NULL;
ep[1] = NULL;
/* We allocated this space; we can extend it. */
new_environ = realloc(last_environ, (size + 2) * sizeof(char *));
if (new_environ == NULL) {
__set_errno(ENOMEM);
goto DONE;
}
if (__environ != last_environ) {
memcpy(new_environ, __environ, size * sizeof(char *));
}
last_environ = __environ = new_environ;
ep = &new_environ[size];
/* Ensure env is NULL terminated in case malloc below fails */
ep[0] = NULL;
ep[1] = NULL;
REPLACE:
var_val = (char*) name;
/* Build VAR=VAL if we called by setenv, not putenv. */
if (value != NULL) {
const size_t vallen = strlen(value) + 1;
var_val = malloc(namelen + 1 + vallen);
if (var_val == NULL) {
__set_errno(ENOMEM);
goto DONE;
}
memcpy(var_val, name, namelen);
var_val[namelen] = '=';
memcpy(&var_val[namelen + 1], value, vallen);
}
*ep = var_val;
var_val = (char*) name;
/* Build VAR=VAL if we called by setenv, not putenv. */
if (value != NULL) {
const size_t vallen = strlen(value) + 1;
var_val = malloc(namelen + 1 + vallen);
if (var_val == NULL) {
__set_errno(ENOMEM);
goto DONE;
}
memcpy(var_val, name, namelen);
var_val[namelen] = '=';
memcpy(&var_val[namelen + 1], value, vallen);
}
*ep = var_val;
...........
}
通过代码很容易理解,后来添加的环境变量是存放在堆上的。
调用clearenv()清除所有的环境变量,包括栈上的
int clearenv(void)
{
__UCLIBC_MUTEX_LOCK(mylock);
/* If we allocated this environment we can free it.
* If we did not allocate this environment, it's NULL already
* and is safe to free(). */
free(last_environ);
last_environ = NULL;
/* Clearing environ removes the whole environment. */
__environ = NULL;
__UCLIBC_MUTEX_UNLOCK(mylock);
return 0;
}
{
__UCLIBC_MUTEX_LOCK(mylock);
/* If we allocated this environment we can free it.
* If we did not allocate this environment, it's NULL already
* and is safe to free(). */
free(last_environ);
last_environ = NULL;
/* Clearing environ removes the whole environment. */
__environ = NULL;
__UCLIBC_MUTEX_UNLOCK(mylock);
return 0;
}
关于环境变量的继承也很简单,看看execv()函数的实现:
int execv(__const char *path, char *__const argv[])
{
return execve(path, argv, __environ);
}
{
return execve(path, argv, __environ);
}
通过将所有环境变量拷贝到栈上,由父进程向子进程传递。
阅读全文
0 0
- linux环境变量自定义环境变量
- linux环境变量
- linux环境变量
- linux环境变量
- Linux环境变量
- Linux 环境变量
- linux环境变量
- Linux环境变量
- linux环境变量
- Linux环境变量
- linux环境变量
- linux环境变量
- linux环境变量
- Linux 环境变量
- linux环境变量
- linux环境变量
- Linux环境变量
- linux环境变量
- 官方推荐的Dialog——DialogFragment
- GreenDao使用说明(一)
- Android Dialog 源码研究
- HTML5学习04-HTML5列表、快和布局
- FTP 编写 3:同时为多个客户端服务(多线程)
- linux环境变量
- 微信支付和连连支付
- 设置状态栏颜色
- Oracle卸载
- 判断是否是图片,java实现
- mysql数据库表删除的奥秘
- 为什么身为程序员月入三万的他,却要放弃?
- group by和聚合函数、having关键字一起使用
- springboot 资料连接