Nick Burrett wrote:
Now, `environ', as the name suggests, contains the current environment variables, i.e. the ones that were set when the process started plus the ones the process set itself (by setenv() or putenv()).
The `environ' variable only contains the array of strings of the environment at process startup. It does not change with calls to setenv or putenv.
According to my tests, it does change!?
Another way to get at the environment is the third parameter to `main' (which GPC could access internally, that's not a problem). However, this variable only contains the environment at the start of the process. When the process does some putenv()s, the pointer gets invalid (DJGPP), or the environment pointed to just seems to be unmodified (the other systems I tested). Perhaps the DJGPP behaviour is a bug, I don't know, but in any case the parameter is not useful to get the current environment at a later time.
The third argument to main is equivalent to the `environ' variable and should point to the same place.
Well, not on the systems I tried. The third argument became invalid after putenv (DJGPP), or did not change (other systems).
So, does anybody know what's the matter with `environ'? Can one just declare it as `extern char **environ;' even if it's not declared in any header? Or is there another way to get at the current environment?
Yes you can just declare it as `extern char **environ'. There's no guarantee that `environ' actually exists so just declaring it extern and using it could give you linker errors. You'd have to find a solution to this, perhaps using autoconf to check for it's existence and declaring your own version if it doesn't.
I think if I have to write my own version, anyway, I can just as well use it on all systems. I think it would be more consistent then than using a (partially undocumented) libc declaration on some systems and my own version on others.
If not, in the worst case, this would mean that the GPC RTS has do to its own environment handling, i.e. get the initial environment for the `main' parameter, and provide its own versions of getenv() and putenv() which work on a copy of that. Though it would not be terribly much work, I hope to avoid it...
I don't see why the GPC RTS would need to do it's own environment handling. Unless you are thinking of the extreme case where the `getenv', `setenv' and `putenv' functions are missing. Or are you thinking that a Pascal character array pointer should always point to an up-to-date environment list ?
Yes, I think it should. E.g., in a program of mine, I do some `putenv's, and then I want to pass the up-to-date environment to a child process (started by execve() in the Pipe unit). But I also want to read the (new and old) environment variables via `getenv' in the program itself. So, if `environ' doesn't point to an up-to-date environment, I'd have to do each `putenv' twice, once for the (hidden?) environment that `getenv' uses, and once for my own environment that is given to execve(). I'd consider this quite ugly, and rather than doing this, I'd prefer to write my own versions of putenv, getenv. etc.
Frank