[Lazarus] SetEnv on Linux 64bit

Honza befelemepeseveze at gmail.com
Wed Apr 4 14:44:59 CEST 2012


2012/4/4  <michael.vancanneyt at wisa.be>:
> Output of strace:
>
> brk(0)                                  = 0x21a5000 brk(0x21c6000)
>                = 0x21c6000 write(1, "a2: MYVALUE\n", 12a2: MYVALUE )
>   = 12 execve("./b.out", [0], [/* 57 vars */]) = 0 brk(0)
>                = 0x189e000 access("/etc/ld.so.nohwcap", F_OK)      = -1
> ENOENT (No such file or
> directory)
>
> As you can see, it uses execve() behind the scenes to be able to pass the
> modified
> local environment.
>
> This is libc-specific behaviour.

I think I cannot agree. IMO its a POSIX specified behavior. libc, at
least in this case, just implements the POSIX specs:
http://pubs.opengroup.org/onlinepubs/007904975/functions/exec.html

And as the ouptut of executing a.out shows, libc implements it
correctly: "For those forms not containing an envp pointer ( execl(),
execv(), execlp(), and execvp()), the environment for the new process
image shall be taken from the external variable environ in the calling
process.", which libc achieves by calling execve() with the current
environ, effectively just filling the prescribed default.

'extern **char environ' is no [kernel] magic*, it's just an ordinary
pointer variable sitting in the process address space, it's only
special in that it gets set (by means which are not important to this
discussion) before main() starts executing.

-- jan

(*) One can e.g. happily set it directly to any other value:
14:41 myname at tux64:~/tmp/c$ cat a.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

extern char **environ;

main() {
	char *e = getenv("MYVAR");
	printf("a1: %s\n", e);
	setenv("MYVAR", "MYVALUE", 1);
	e = getenv("MYVAR");
	printf("a2: %s\n", e);
	environ = NULL;
	e = getenv("MYVAR");
	printf("a3: %s\n", e);
}
14:41 myname at tux64:~/tmp/c$ gcc a.c && ./a.out
a1: (null)
a2: MYVALUE
a3: (null)
14:41 myname at tux64:~/tmp/c$




More information about the Lazarus mailing list