C语言标准库函数getenv可获取环境参数(根据参数名称),
函数声明:char* getenv(char*name);
extern char **environ

其实现如下:

---------------glibc-1.09.1/sysdeps/generic/getenv.c

[cpp] view plain copy
  1. /* Return the value of the environment variable NAME.  */
  2. char *
  3. DEFUN(getenv, (name), register CONST char *name)
  4. {
  5. register CONST size_t len = strlen(name);
  6. register char **ep;
  7. if (__environ == NULL)
  8. return NULL;
  9. for (ep = __environ; *ep != NULL; ++ep)
  10. if (!strncmp(*ep, name, len) && (*ep)[len] == '=')
  11. return &(*ep)[len + 1];
  12. return NULL;
  13. }

其中全局指针__environ指向环境参数串的指针数组,通过循环匹配找到指定的参数名称,获取=后的参数值并返回其指针。
那么__environ是在哪定义的呢?是在start.c中。

---------------glibc-1.09.1/sysdeps/unix/start.c
C程序链接时,这部分stub代码会链接到在程序开始处,_start是C程序真正的入口,_start调用start1,
而start1在调用初始化代码__libc_init后会调用main()。
从下面的代码看出,为什么main中末尾无需exit(),因为start1代劳了。至于堆栈中的argc,argv,envp
这些都是操作系统在调用系统调用execve执行程序时就安排好的,start1的形参可以去到这些进程参数和环境变量,
全局指针environ则等于envp(指向环境参数指针数组的指针)。

[cpp] view plain copy
  1. …………
  2. #define __environ   environ
  3. …………
  4. static void start1();
  5. …………
  6. /* N.B.: It is important that this be the first function.
  7. This file is the first thing in the text section.  */
  8. void
  9. DEFUN_VOID(_start)
  10. {
  11. start1();
  12. }
  13. …………
  14. /* ARGSUSED */
  15. static void
  16. start1(ARG_DUMMIES argc, argp)
  17. DECL_DUMMIES
  18. int argc;
  19. char *argp;
  20. {
  21. char **argv = &argp;
  22. /* The environment starts just after ARGV.  */
  23. __environ = &argv[argc + 1];
  24. /* If the first thing after ARGV is the arguments
  25. themselves, there is no environment.  */
  26. if ((char *) __environ == *argv)
  27. /* The environment is empty.  Make __environ
  28. point at ARGV[ARGC], which is NULL.  */
  29. --__environ;
  30. /* Do C library initializations.  */
  31. __libc_init (argc, argv, __environ);
  32. /* Call the user program.  */
  33. exit(main(argc, argv, __environ));
  34. }

正常的内存堆栈布局是这样的 地址从低到高:
int argc 
char** argv(指针数组,0结尾)
char** envp(指针数组,0结尾)
string[] arg(顺序排列的参数串数组,每个参数串0结尾) 
string[] env(顺序排列的环境参数串数组,每个参数串0结尾) 
其中argv[0]指向arg[0],argv[1]指向arg[1],……。
正常情况 &argv[argc+1]=envp,但是如果环境参数没有,那么堆栈中就没有envp指针数组和env串数组,那么argv后就直接是
arg的参数串数组了,此时堆栈布局如下:
int argc 
char** argv(指针数组,0结尾)
string[] arg(顺序排列的参数串数组,每个参数串0结尾)

所以有&argv[argc+1]=*argv (第一个参数指针argv[0]是指向第一个参数串的),这是上述代码中
if ((char *) __environ == *argv)
    /* The environment is empty.  Make __environ
       point at ARGV[ARGC], which is NULL.  */
    --__environ;

的由来。

C语言标准库函数getenv的实现相关推荐

  1. srt文件解析 c语言,c语言标准库函数srt排序的介绍与使用.docx

    c语言标准库函数srt排序的介绍与使用 C语言标准库函数qsort排序的介绍与使用 2007-05-22 19:24 qsort函数包含在的头文件里.qsort函数声明如下:void qsort(vo ...

  2. 常用ANSI C语言标准库函数汇总(一)

    常用ANSI C语言标准库函数汇总(一) C语言被发明出来时并没有什么库函数,随着C语言的流行,越来越多的厂商和组织开始提供C语言的编译器,同时把经常用到的函数封装成"库"的形式发 ...

  3. C语言标准库函数qsort( )——数据排序

    大家好!我是保护小周ღ,本期为大家带来的是深度解剖C语言标准库函数 qsort(),qsort()函数他可以对任意类型的数据排序,博主会详细解释函数使用方法,以及使用快速排序的左右指针法模拟实现函数功 ...

  4. c语言标准库函数大全.chm,C语言标准库函数(word版).doc

    标准库函数 exit itoa exit 原型:extern void exit(int retval); 用法:#include 功能:结束程序 说明:返回值将被忽略 举例: // exit.c # ...

  5. c语言标准库函数system,C 库函数

    C 库函数 - system() 描述 C 库函数 int system(const char *command) 把 command 指定的命令名称或程序名称传给要被命令处理器执行的主机环境,并在命 ...

  6. c语言函数大全 pdf,C语言标准库函数大全.pdf

    Page 1 of 22 Arther's Blog 准备是成功的首要前提 博客园 社区 首页 新随笔 联系 管理 订阅 随笔- 208 文章- 0 评论- 14 c语言库函数大全--资料收集 与我联 ...

  7. C语言标准库函数qsort(快速排序函数)

    文章目录 一.函数原型 二.函数解析 比较函数 三.手写快排 四.使用qsort 1.对int数组排序 2.对double数组排序 3.对char数组排序 4.对字符串排序 (1)char s[][] ...

  8. C语言标准库函数qsort排序的介绍与使用

    qsort函数包含在<stdlib.h>的头文件里. qsort函数声明如下: void qsort(void *base, size_t nmemb, size_t size, int( ...

  9. C语言标准库函数qsort具体解释

    1 函数简单介绍 功 能: 使用高速排序例程进行排序 头文件:stdlib.h 用 法: void qsort(void *base,int nelem,int width,int (*fcmp)(c ...

最新文章

  1. 云计算灾备原理与预防恢复方案
  2. Java面试没过_Java面试中遇到的坑【填坑篇】
  3. python学习笔记(十 三)、网络编程
  4. Spring 框架基础(02):Bean的生命周期,作用域,装配总结
  5. linux串口环形缓冲区,能不能讲解下串口环形缓冲区的概念?
  6. 如何避免面试现场被虐?
  7. 图解:如何修改CSDN账号昵称?
  8. 【起航计划ObjC 002】印第安老斑鸠ObjC的幻想 ---- Ubuntu下安装并使用MAC虚拟机
  9. 最常用的父子组件传值方式prop详解
  10. 解决win7 若要安装Office2010,需要在计算机上安装MSXML版本6.10.1129.0 问题
  11. origin登录显示无网络连接到服务器,origin显示“您初次登录时必须保持联网。请检查您的网络连接后再试一次”,怎么处理...
  12. nodejs之setTimeout
  13. 【FreeRTOS】软件定时器的使用
  14. ACM POJ 题目分类(完整整理版本)
  15. 利用switch实现春夏秋冬
  16. 深圳多家银行设立取款限额 ATM机限时取款(图)
  17. UML类图以及类与类之间的关系
  18. error: Failed dependencies: mysql-community-common(x86-64) >= 5.7.9 is needed by mysql-commu
  19. 【Java】环境搭建
  20. 【To be a better man】Timing(时机)---有想做的事情就赶快去做吧!

热门文章

  1. 重磅!可以发朋友圈和搜一搜的PC端微信来了,赶紧来下载!
  2. 皮一皮:女友是有多么体贴...
  3. 为什么 GROUP BY 之后不能直接引用原表中的列?
  4. 华为:0元 + 3个月 = WEB全栈前端工程师
  5. 永远不要在 MySQL 中使用“utf8”
  6. Git 版本控制之 GitFlow
  7. sqlserver sql行专列_sqlserver----记录转载(行转列)、列转行、pivot、unpivot
  8. MultiResUNet笔记
  9. c++ socket 结构体
  10. python DbUtils 使用教程