NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Silly shell question



On 3/22/2016 5:16 PM, Johnny Billquist wrote:
On 2016-03-22 22:07, Swift Griggs wrote:
On Tue, 22 Mar 2016, Johnny Billquist wrote:
Only environment variables are propagated to child processes.

Thanks for the info, but do you happen to know what the actual mechanism
that the child processes is able to "import" the exported variable ?
Ie.. is it some special OS glue/magic, or is it just straight getenv()
calls by the client shell/app ? I don't see anything magical in the man
page for getenv() that would distinguish an exported versus non-exported
variable.

A child process gets the environment as a part of the image activation. It's actually provided as an argument to each program, except most programs do not care to pick it up.

In case it wasn't clear, this refers to a function argument to the main function, i.e.:
    int main(int argc, char **argv, char **environ)
not command line arguments.

The special OS glue/magic that happens is that the kernel takes the list of environment variables passed to the execve() system call, and copies them to the stack of the newly executing binary (kern_exec.c if you want to go look). Then, the code that runs before main() (which comes from crt0.o and automatically gets included in your program when you link) figures out what's on the stack (which also includes the command line arguments, i.e. argv) and passes the appropriate things to main().

If your program (/bin/sh in this case) calls one of the exec* functions that don't take an explicit environ pointer, the implementation in libc (e.g. execl.c) actually calls execve() and passes along the current environment for you (which is available as the global variable "environ").

Shell local variables aren't stored in environ at all and aren't passed along to the execve() call when the shell forks+execs some new process, they're just arbitrary data that the shell process keeps in its memory and uses when it sees a variable reference on a command line. Actually, there's no reason that the shell needs to store even exported variables in its own environ global variable either, it just needs to make sure that it generates an appropriate array of variables when it starts a new process and calls execve(). (that might be what /bin/sh actually does, I haven't actually looked)

Eric


Home | Main Index | Thread Index | Old Index