Web lists-archives.com

Re: [Mingw-users] setenv()




Keith Marshall:
> Anton Shepelev:
> > Keith Marshall:
> >
> > > 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 sam-
> > > ple  implementation,  confirm that the pointer
> > > returned by getenv() bears no relationship  to
> > > the  original  address of the string passed to
> > > putenv(); altering  that  latter  string,  (or
> > > even just allowing it to be discarded from the
> > > stack, as in that sample implementation),  af-
> > > ter passing it to putenv() will not change the
> > > environment, (nor will it lead to  environment
> > > corruption).  OTOH, the temptation to strdup()
> > > the source  string,  before  passing  that  to
> > > putenv(), would create a memory leak.
> >
> > The  result  would   be the same if getenv() re-
> > turned a copy of the string as a safety measure.
>
> True, but it doesn't work that way -- getenv() re-
> turns  a pointer to the value, immediately follow-
> ing the appropriate "name=" string within the  en-
> vironment  itself.   This is readily demonstrated,
> by adaptation of your example  program  (with  at-
> tached setenv() implementation):

Thanks for the patch!

>   #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 enu-
> merated within the  _environ  pointer  array,  (so
> refers to the part of that string immediately fol-
> lowing "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  pro-
> gram under wine suggests that wine has adopted ex-
> actly 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.

Understood.

-- 
()  ascii ribbon campaign - against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]


------------------------------------------------------------------------------
_______________________________________________
MinGW-users mailing list
MinGW-users@xxxxxxxxxxxxxxxxxxxxx

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-users
Also: mailto:mingw-users-request@xxxxxxxxxxxxxxxxxxxxx?subject=unsubscribe