免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3009 | 回复: 5
打印 上一主题 下一主题

请教environ的使用和“环境”的若干概念 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-01-13 21:24 |只看该作者 |倒序浏览
最近在学习Linux关于环境的知识时,遇到了一些问题,想向论坛上的前辈们讨个明白。
例子如下:
#include <stdio.h>
#include <unistd.h>

extern char **environ;

int main(int argc,char **argv)
{
        char *table[3];
       
        table[0] = "TERM=vt100";
        table[1] = "HOME=/on/the/range";
        table[2] = 0;
        environ = table;
        execlp("env","env",NULL);
       
        return 0;
}

例子的执行结果是打印出了table中的两个字符串。

通过学习,我了解到exec函数族对执行进程起到“洗脑”的作用,即用函数中指定的新程序取代进程中运行的原程序。显然,这里原程序的数据被打印表明execlp对其进行了复制操作。
(1)environ是全局变量,我想了解一下在被赋值前,它指向的是哪里的什么数据?它被例子程序重新赋值后是否又被重赋原来指向的值?如果是这样,在哪里被重新赋值的呢?
(2)fork操作复制进程创建子进程,如果environ所指的数据同样被复制给了子进程,那么environ这个指针有没有在fork后就指向了子进程中的那个字符串数组呢?
(3)环境是Unix系统的概念,有书说环境是Unix中进程传递信息的途径之一。这里我理解的环境是environ所指向的那个字符串数组,那么当一个进程执行时,它所依赖的环境已经被复制到进程空间里了吗?如果是这样,多个进程中的“环境”与唯一的environ是怎样保持协调的呢?

谢谢大家的光顾~~

论坛徽章:
0
2 [报告]
发表于 2008-01-13 21:47 |只看该作者
去看APUE相关章节,讲解很详细。

论坛徽章:
0
3 [报告]
发表于 2008-01-13 21:52 |只看该作者
谢谢cugb_cat

论坛徽章:
0
4 [报告]
发表于 2008-01-13 22:46 |只看该作者
1.environ是全局变量,我想了解一下在被赋值前,它指向的是哪里的什么数据?
当前执行的程序是shell进行fork后的一个子进程,并exec.
子进程继承父进程的环境变量,因此它指向的数据就是执行程序的shell的环境变量表.
如果你查看当前shell的环境变量表,在shell里执行env命令

2.它被例子程序重新赋值后是否又被重赋原来指向的值?如果是这样,在哪里被重新赋值的呢?
没有.每个进程,不管是你的程序,还是shell,都有自己的环境变量,在你的程序中TERM=vt100.但当进程结束后,该程序的环境变量自然被释放了,注意的是该程序的环境变量的更改并不会影响父进程shell的环境变量

3.fork操作复制进程创建子进程,如果environ所指的数据同样被复制给了子进程,那么environ这个指针有没有在fork后就指向了子进程中的那个字符串数组呢?
fork后,子进程获得了父进程的数据空间,堆,栈的副本.这里就包含环境environ.

4.环境是Unix系统的概念,有书说环境是Unix中进程传递信息的途径之一。这里我理解的环境是environ所指向的那个字符串数组,那么当一个进程执行时,它所依赖的环境已经被复制到进程空间里了吗?
当进程fork后,子进程就继承了父进程的环境变量,当exec如果是execl, execv, execlp, execvp环境表会传给exec后的进程.如果execle, execve 就是自己定义环境表.

5.如果是这样,多个进程中的“环境”与唯一的environ是怎样保持协调的呢?
每个进程都有自己的环境变量environ,它一般存放在该进程存储空间的高地址中.

论坛徽章:
0
5 [报告]
发表于 2008-01-14 08:54 |只看该作者
原帖由 xi2008wang 于 2008-1-13 22:46 发表
1.environ是全局变量,我想了解一下在被赋值前,它指向的是哪里的什么数据?
当前执行的程序是shell进行fork后的一个子进程,并exec.
子进程继承父进程的环境变量,因此它指向的数据就是执行程序的shell的环境变 ...

谢谢xi2008wang的耐心解答啊!

论坛徽章:
0
6 [报告]
发表于 2008-01-14 11:28 |只看该作者
apue应该说的很清楚了,env,__program,errno都是c库的变量,main函数之前会(errno在某个函数之后)被设置,随手写了一个,写的很烂,因为我不会汇编,你也可以objdump一个看看,看看C库怎么做的,原理差不多
#cc test.s -nostdlib -lc

.data
fmtd:
        .string "argc: %d\n"
fmts:
        .string "%s\n"
argc:
        .int 0
.text
.globl _start
_start:
        movl (%esp),%eax
        movl %eax,argc
#printf argc
        pushl argc
        pushl $fmtd
        call printf
        addl $8,%esp
#argv
        addl $4,%esp
        movl (%esp),%eax
#printf argv[0]
        pushl %eax
        pushl $fmts
        call printf
        addl $8, %esp
#env
        movl argc,%edx
        addl $1, %edx
        imull $4, %edx,%edx
        addl %edx, %esp
#printf env
reprint:
        movl (%esp),%eax
        testl %eax,%eax
        jz quit
        pushl %eax
        pushl $fmts
        call printf
        addl $8, %esp
        addl $4, %esp
        jmp reprint
quit:
        pushl $0
        call exit
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP