【问题标题】:Is char *envp[] as a third argument to main() portablechar *envp[] 作为 main() 的第三个参数是否可移植
【发布时间】:2012-05-06 11:28:46
【问题描述】:

为了在C 程序中获取环境变量,可以使用以下命令:

  • getenv()
  • extern char **environ;

但除了上述之外,是否使用char *envp[] 作为main() 的第三个参数来获取被视为标准一部分的环境变量?

#include <stdio.h>

int main(int argc, char *argv[], char *envp[])
{
    while(*envp)
        printf("%s\n",*envp++);
}

char *envp[] 可移植吗?

【问题讨论】:

    标签: c environment-variables main portability function-signature


    【解决方案1】:

    函数getenv 是C 标准中唯一指定的函数。函数 putenv 和 extern environ 是 POSIX 特定的。

    编辑

    main 参数 envp 未由 POSIX 指定,但得到广泛支持。

    访问环境列表的另一种方法是声明 main() 函数的第三个参数:

    int main(int argc, char *argv[], char *envp[])
    

    然后可以以与 environ 相同的方式处理此参数,使用 区别在于它的作用域是 main() 的本地。虽然这个功能是 在 UNIX 系统上广泛实施,应避免使用它,因为, 除了范围限制,SUSv3中没有规定

    【讨论】:

    • 请注意,C 标准承认这是一种常见的替代方案——甚至 C89 在附件 G(可移植性问题)中也提到了它;它在 C99 和 C11 的附件 J(可移植性问题)中。
    • 它(至少)不适用于 IBM 大型机上的 z/OS 2.4 和 xlc/c99/c89。有一个POSIX solution
    【解决方案2】:

    它不是便携式的。 *envp[] 是传统的 UNIX 事物,并非所有现代 UNIX 系统都实现它。

    另外作为旁注,您可以通过对*argv[] 进行指针遍历来访问 envp,使其溢出...但我认为这不能被视为 安全 编程。如果您查看进程内存映射,您会发现envp[] 就在argv[] 的上方。

    【讨论】:

    • 你也可以越过环境检查auxv... ;-)
    • 什么通常存储在 auxv 中,因为前几天我只是想知道为什么 envp 常量(运行之间)之后的字段在哪里?
    • elf.h 中查找以AT_ 开头的宏。一些更有趣的东西是AT_SECUREAT_RANDOMAT_EXECFNAT_HWCAP 和 uid/gid 的。否则,它们主要对动态链接器和 libc 初始化代码感兴趣。 auxv 的格式是成对的系统字大小整数,其中第一个是 AT_ 常量之一(一个标签),第二个是与该标签关联的值(可能是一个指针,取决于在标签上)。
    • 用指针找到argv的结尾,更进一步呢? char **find = argv, **envp; while(*find) find++; envp = find + 1; 可能是未定义的行为,因为不能保证操作系统在 argv 的最后一个 arg 之后放置环境内容...
    • 最后一条评论方式的更传统/惯用和简洁的版本:char **envp = argv; while(*envp++);
    【解决方案3】:

    标准描述了main 的两种格式(参见C99 Standard (pdf) 中的5.1.2.2.1)

    a)int main(void)

    b) int main(int argc, char **argv) 或同等学历

    它允许实现定义其他格式(可以允许第三个参数)

    c) 或以其他一些实现定义的方式。

    【讨论】:

    • 一个实现可能main提供更多格式,但是这两个是唯一保证在任何托管实现中存在的格式。
    【解决方案4】:

    第三个参数在 Microsoft C 和 GNU GCC 中有效:

    Visual Studio 2015: Arguments to main

    GNU C Programming Tutorial: Environment variables

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-13
      • 1970-01-01
      • 2020-12-26
      • 1970-01-01
      • 1970-01-01
      • 2011-08-14
      • 2017-03-11
      相关资源
      最近更新 更多