-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 17/11/16 16:56, Anton Shepelev wrote:
> Keith Marshall to Anton Shepelev:
>
>>> As I can tell, the variable buf is a local one, whereas
>>> according to the putenv man entry, "The string pointed to by
>>> string becomes part of the environment, so altering the string
>>> changes the environment."
>>>
>>> Does the Microsoft implementation copy the string passed?
>>
>> Yes. Given MS-DOS' organization of the environment as a
>> contiguous sequence of NUL separated name=value C strings,
>> terminated by a single zero-length C string, that would have been
>> a practical necessity. Of course, there's no guarantee that
>> Windows' has adopted that MS-DOS environment organizational
>> legacy, but the printf() statements, which I added to the sample
>> implementation, confirm that the pointer returned by getenv()
>> bears no relationship to the original address of the string
>> passed to putenv();
>
> Thanks -- that is interesing. The result would be the same if
> getenv() returned a copy of the string as a safety measure.
True, but it doesn't work that way -- getenv() returns a pointer to
the value, immediately following the appropriate "name=" string within
the environment itself. This is readily demonstrated, by adaptation
of your example program (with attached setenv() implementation):
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main( int argc, char** argv )
{
char **p;
const char *envval;
errno = 0; setenv ("test", "1", 1);
printf (
"setenv (\"test\", \"1\", 1) returned errno = %d\n", errno
);
errno = 0; setenv ("test2", "2", 1);
printf (
"setenv (\"test2\", \"2\", 1) returned errno = %d\n", errno
);
if( (envval = getenv ("test")) != NULL )
printf (
"envval 'test' retrieved at %1$#08x; value = %1$s\n", envval
);
if( (envval = getenv ("test2")) != NULL )
printf (
"envval 'test2' retrieved at %1$#08x; value = %1$s\n", envval
);
for( p = _environ; *p; p++ )
printf( "%1$#08x: %1$s\n", *p );
errno = 0; unsetenv ("test");
printf ("unsetenv (\"test\") returned errno = %d\n", errno);
if( (envval = getenv ("test")) != NULL )
printf (
"envval 'test' retrieved at %1$#08x; value = %1$s\n", envval
);
else
printf ("envval 'test' was successfully deleted\n");
return 0;
}
which yields output (on WinXP VM):
setenv ("test", "1", 1) returned errno = 0
setenv ("test2", "2", 1) returned errno = 0
envval 'test' retrieved at 0x3d2445; value = 1
envval 'test2' retrieved at 0x3d24de; value = 2
0x3d2be0: !::=::\
0x3d2bf0: ALLUSERSPROFILE=C:\Documents and Settings\All Users
...
0x3d32b8: WINDIR=C:\WINDOWS
0x3d32d8: _=e:/a
0x3d2440: test=1
0x3d24d8: test2=2
unsetenv ("test") returned errno = 0
envval 'test' was successfully deleted
Note that the address retrieved by getenv("test") is exactly 5 bytes
beyond the corresponding "test=1" string in the environment, as it is
enumerated within the _environ pointer array, (so refers to the part
of that string immediately following "test="). Also note that the
separation of "test=1" and "test2=2" is much more than it would be,
if WinXP had adopted the MS-DOS environment organization, so that
assumption obviously wasn't valid, (although curiously, running the
same program under wine suggests that wine has adopted exactly that
organization).
Further note that the setenv("test2", "2", 1) call will overwrite the
stack space used by setenv("test", "1", 1), and the "test=1" string,
in the environment has not been affected in any way.
- --
Regards,
Keith.
Public key available from keys.gnupg.net
Key fingerprint: C19E C018 1547 DE50 E1D4 8F53 C0AD 36C6 347E 5A3F
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.20 (GNU/Linux)
iQIcBAEBAgAGBQJYLfz3AAoJEMCtNsY0flo/blcQAJaeLy1WILvb6lD8uKwkt7hJ
eq5yZCuJxM63MvT+fsH2AYwaTpYnybSEJifJtINOaRffPcz3+m3N408aBu5aI+7g
VBPKJmlniUIAhPucN1gszVoKmz6bkZd9xOQ0RmWsh9wwmQ9KuTuNbQp+xy8opiMB
PAF7vT2UwsvxBK6DTblw1M25dXGdKOPPGWyFoklu4NmdiIYJNrS7zTfolD00PLSM
3NBU8LO8H1pCpyOWgVZ06ZexI1Yykxi2uESF9aOyWcNfjWO2Lm3SvK9wopjlesmX
PWM1q+aFUtEn/O8tNJtIpvFMKR5rvvQPVoW/gliVlC55tOqDznkOLWbfbsgHlllj
v0KuUAe2Q/wY8kL+N5yJhO9VshCgzdXbOTNNXv7Q5zxZ2H13tf6nwitAHc/31o0L
MBr3q9GXCyNOe3mYAVtJks23rXYLveWrMVU9yR8L4i7hcmk+9ASZVE9LpVy370/P
VuitW0ohGU871RrvJOcCq7fOlaKwGo5/nuZLHImDVm3+QPJIaIIccqeLPrT0trr0
nzU18LlIqglVPq8xCM4E8p+nYc98bAxSKy0mORnONiuE3ksTD451sv+aqEy5M4LZ
a8CD35zgcg67FK8dGq/ehlSQdAaytCQWjY9BJFOkSSBWfYpth0U3W6IPIWiYPScE
tdIjG2KWoyy9iHL/SAR+
=QXIP
-----END PGP SIGNATURE-----
------------------------------------------------------------------------------
_______________________________________________
MinGW-users mailing list
[hidden email]
This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same. Disregard for the list etiquette may cause your account to be moderated.
_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-usersAlso: mailto:
[hidden email]?subject=unsubscribe