[C-prog-lang-l] traversing argv vs. environment variables

Vladimír Kotal vlada at kotalovi.cz
Wed Apr 6 23:04:48 CEST 2022


Hi Walter,

firstly, thanks for reaching out. According to my experience, not many students/programmers are able to admit an error in their programs in a public forum, which is somewhat surprising given that errors are excellent learning ground.

In C99 std the environment is mentioned in the long Annex J, specifically J.5.1 Environment arguments: 

In a hosted environment, the *main *function receives a third argument, *char *envp[]*, that points to a null-terminated array of pointers to *char*, each of which points to a string that provides information about the environment for this execution of the program (5.1.2.2.1).


One example of the argv/envp layout is nicely visible in the OpenBSD code. When handling the exec syscall to execute a new program, the kernel http://bxr.su/OpenBSD/sys/kern/kern_exec.c#494 calls copyargs() function http://bxr.su/OpenBSD/sys/kern/kern_exec.c#copyargs that populates the stack of the new program with argument and environment vector. Inside the function it is nicely visible what is going on. The 'sp' and 'dp' are source and destination pointers, respectively. Initially, the 'dp' is set to leave the space for the argv/envp pointers and the 2 terminating NULL pointers (and auxiliary ELF vector) and then progresses through the source, simultaneously storing each pointer and the associtated string in each iteration of the respective cycle (nifty!). One can see that the function basically stores the pointer arrays followed by the actual strings on the stack of the new program, so the arrays and the strings are in one contiguous block on the stack. The copyout() and copyoutstr() are used to copy pieces of kernel memory to userland. Now, changing the environment variables via functions like putenv() might actually move the environment to heap.


Best regards,


V. Kotal

On Tue, Apr 5, 2022, at 22:53, Walter Herold Veedla wrote:
> Hello,
> 
> it was my code that ran from program arguments through the environment 
> variables [and on...] until segfaulting.
> 
> From the following link:
> https://www.gnu.org/software/libc/manual/html_node/Program-Arguments.html
> I was able to gather that "In Unix systems you can define main a third 
> way, using three arguments: int main (int argc, char *argv[], char 
> *envp[]) ... where the the third argument envp gives the program's 
> environment."
> 
> This somehow implies that the program arguments and program variables 
> happen to be laid out somewhat sequentially in memory and we run over 
> them when we carelessly keep incrementing '++*argv' [and a whole lot 
> more cryptic stuff]:).
> 
> The accepted answer in this stackoverflow post: 
> https://stackoverflow.com/questions/18681078/in-which-memory-segment-command-line-arguments-get-stored
> seems to confirm this.
> 
> Kind regards
> Walter Herold Veedla
> 
> On 05.04.2022 22:15, Vladimír Kotal wrote:
> > Hi all,
> > 
> > when writing the programs to print the argument vector using various 
> > methods, someone raised a question in a Zoom chat that his program 
> > actually printed environment variables (on a Unix box).
> > 
> > Could someone say what likely happened and why the environment variables 
> > were printed ?
> > 
> > Best regards,
> > 
> > 
> > V. Kotal
> > 
> > _______________________________________________
> > c-prog-lang-l mailing list
> > c-prog-lang-l at mff.cuni.cz
> > http://mbox.ms.mff.cuni.cz/listserv/listinfo/c-prog-lang-l
> _______________________________________________
> c-prog-lang-l mailing list
> c-prog-lang-l at mff.cuni.cz
> http://mbox.ms.mff.cuni.cz/listserv/listinfo/c-prog-lang-l
> 
-------------- next part --------------
HTML attachment scrubbed and removed


More information about the c-prog-lang-l mailing list