On Wed, 4 Apr 2012, Honza wrote:

2012/4/4  <michael.vancann...@wisa.be>:
I do not agree with this interpretation.

First of all, you are calling execv() in your code, not execve(). That libc
changes this to execve() is IMHO not permissible.
So all bets and conclusions are off from that point onwards.

Why not permissible? The POSIX specs describe what the semantics
and/or effects of executing a defined function are. The semantics and
effects of libc's execv() are what is said about it in POSIX. I don't
see any 'off' conclusion derivable ;-)


Secondly, we interpret differently 'external variable environ'. (note the
'external'). For me this clearly means the original environment as passed on
to the current process.

From the moment main() starts executing, environ is the process
current environment. Initially, as it was passed, after any mutation
well, that mutated state. No copy of the original environment of a
process exists anywhere in the process nor in the kernel.

I think you'll find that the environment block is copied as soon as you
add a new environment variable.

Since the original environment as passed by the kernel is not in the heap, so how could you add something to it, except by copying the array
of pointers and enlarging it ?

What happens to it in a library, is currently open for speculation.

 A copy might
still exists, though not necessarily, in the originating process, but
that is anyway not accessible by the new/now executing process (modulo
shmem etc.).

Also the 'external variable' is just a reference to the C
specification, i.e. that's the way C says to the linker to find the
variable defined elsewhere, not in this compilation unit/produced
object code.

I agree a C person might interpret it like that.


Which probably is what happens if you'd call the
execv() kernel function, although that would need testing.

I can perhaps save someone's time, as there's no execv() kernel call.
There's only execve() and that's why a POSIX compliant libc calls
execve() with the current value of environ.

I stand corrected on this front.


Thirdly, the 2 referenced pages clearly indicate that the whole environment
handling is hairy at best in corner cases like this.

Perhaps, not relevant to us, IMO.

And lastly: We on purpose do not follow Libc; Otherwise we'd simply have
built the whole RTL on top of it. So we are not under any obligation to
mimic its behaviour.

No one said so. Actually that's just fine. The discussion went about
various claims from various people that in POSIX the environment is
either immutable at all, or the mutations are not visible in
libraries, or not inherited on exec() - we (you and me) were not
discussing FPC at all, IMO.

Yes. I was sloppy in my terminology.


AFAICS, all the above claims were not true. Actually it's the first
time ever I saw such claims, as mutating environment in a POSIX
program, because of child process inherits that by default, is so
common, that I have never even thought before of a possibility it
could be otherwise, so I wanted to verify, to my own benefit, "how
that stuff I never really looked into actually works" ;-)

I think the confusion came from the original posters request to modify the 'global environment', which - I hope you'll agree - is not possible on Posix, as the environment is passed on from process to process using execve.

So, my conclusions:

* The SetEnvironment() call on windows will do something totally
  different than what happens under Posix, and the Windows behaviour
  cannot be mimicked. Which is why it isn't in sysutils.

* A posixy SetEnv() could be implemented for the Unix layer, to mimic
  Libc. But I think it would not be usable for libraries, since the
  environment copy of the RTL would not be shareable with the library
  without pulling in the C memory manager.
  At best it could be used to be passed on to a new process.

Michael.

--
_______________________________________________
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to