我在这里阅读了几篇文章,但仍然对 setenv()
的方式感到困惑作品:
我的理解是环境变量在用户栈底部连续存储为一堆“foo=bar\0”字符串,然后还有一个数组
envp[]
指向这些字符串的指针,也靠近用户堆栈的底部。用户堆栈在这些字节的顶部增长,这意味着向字符串区域或指针数组添加更多内容并非易事。那么如何setenv()
如果设置了新变量(需要向 envp[]
中添加元素),或者更改了变量但新值字符串比旧值字符串长(使就地修改不可能),则工作,而不移动(几乎)整个用户堆栈为新人腾出空间?一个有点相关的问题是,是否
bash
保留本地设置变量的内部列表,当用户 export
本地设置变量,bash
简单地将它从这个本地管理的列表中删除,并将它添加到上面提到的堆栈字符串区域的底部并将其指针插入到指针数组 envp[]
,以便其子进程自动继承导出的变量?
最佳答案
My understanding is that environment variables are stored as...
你的理解只是部分正确。 :微笑:
...without shifting (almost) the whole user stack to make room for newcomers?
那是不可能的。不管程序是用 C 语言编写还是操作系统是 UNIX。例如,因为堆栈上的指针可以引用堆栈上的其他位置。
首先要注意的是,环境变量存储在新进程中的位置取决于体系结构。大多数 UNIX 实现,在大多数 CPU 架构上,如您所描述的那样将其存储在堆栈中。但是 C 规范中实际上没有任何内容要求该解决方案。此外,如果您修改环境,则实现可以自由地将现有环境变量块复制到内存中的新位置。 C 实现可以自由移动环境变量块并更新魔法
__environ
变种A somewhat related question is, does bash keep an internal list of locally set variables....
不是你描述的方式。它确实保留了本地设置变量的“内部列表”。但它并没有按照您建议的方式使用它。
我很好奇是什么促使你打开这个问题
关于c - putenv()/setenv() 如何在不移动整个用户堆栈的情况下工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63497061/