How do functions like getenv(3) access the environment when my program doesn't have any references to the environment?
1 Answers
Your program doesn't have a reference to the environment, but a whole copy of it.
The command line arguments and environment strings (as they were passed to the execve(2)
system call) are all packed together and copied in the address space of the process [1].
In a typical implementation [2], two NULL
-terminated lists of pointers to them (representing the argument lists and the environment) are made available on the stack to the entry point of the program (_start
), where the startup code (run before main()
) will point the char **environ
global variable to the beginning of the latter.
The getenv(3)
function is simply looking through that environ
list and comparing each entry in turn.
When some new entry has to be added to the environment (as with setenv(3)
), the environ
list will be relocated elsewhere.
[1] On Linux, the addresses of the argument list and environment variables are accessible as the 48th and 50th fields of /proc/PID/stat
, see procfs(5)
.
[2] In glibc, _start
will pop argc
, point argv
to the top of the stack, and __libc_start_main
will set __environ
(an alias for environ
) to argv + argc + 1
.

- 138,973
-
1Could you be clearer with this on this point: by "known location" do you mean static memory address? If not, how does the OS tell the C library (or similar) what this address is? – Philip Couling Jan 26 '19 at 23:51
-
1On linux at least, they're put at the end of stack, so they're accessible via registers in the program's entry point (
_start
). You can get the actual addresses from 48th-51th fields (argv_start-env_end) from the/proc/PID/stat
file, see procfs(5). – Jan 27 '19 at 00:41 -
1Could you edit your answer to include this. Putting a pointer on the stack prior to starting the program is substantially different to a "known location". – Philip Couling Jan 27 '19 at 01:01
-
I'd appreciate you could consider https://unix.stackexchange.com/questions/498425/what-are-differences-between-do-execve-and-start-copying-the-command-line – Tim Feb 03 '19 at 15:00
environ
global sym) is non-standard – Jan 26 '19 at 23:36Of course, main is just something invented by your compiler's runtime support libraries. As far as the OS is concerned, the interface is somewhat different. The same principle still stands, however. The environment is passed to the newly created program after execve on its stack.
– Philip Couling Jan 27 '19 at 01:05the interface is somewhat different
. – Philip Couling Jan 27 '19 at 11:20