Environment inheritance under Windows NT 4, Attempt 2

Milton L. Hankins mlh at swl.msd.ray.com
Thu Jun 24 18:54:21 CEST 1999


Since I've not yet gotten a response to my first post, here's an
elaboration.

Windows NT Workstation 4.00.1381, SP5.

1.  Right click on My Computer, choose Properties, Environment tab.  Note
the value of the System Variable "windir" and press Cancel.  (On my
system, this is "C:\WINNT".)

2.  Open a Command prompt.

3.  Here's a transscript of my CMD session, you can follow along:

-----------------------------------------------------
C:\>echo %WINDIR%
C:\WINNT

C:\>python -c "import os; print os.environ['windir']"
C:\WINNT

C:\>set WINDIR=foo

C:\>echo %WINDIR%
foo

C:\>python -c "import os; print os.environ['windir']"
C:\WINNT

-----------------------------------------------------

What is going on here?  I wrote a program using VC5 to extract a variable
(1) directly from environ and _environ and (2) by calling getenv().  All
three reported "foo".  (Source provided below.)

After rummaging through the Python source, it appears that os.environ is
provided through the posix module, which in turn gets the environment data
from the "extern char** environ".

Could this have something to do with Microsoft's run-time DLLs?  I noticed
that Cygwin B19 used to exhibit this behavior as well, but it seemed to go
away in B20.1.

Python picks up the environment correctly if I go into the Control Panel,
System, Environment, and click OK.  But I have to do this each time I log
in to NT.


----------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>

extern char** environ;

#define BIG 80


int envIndex(const char** envArray, const char* key) {
	int i;
	char keyPrime[BIG];

	strcpy(keyPrime, key);
	strcat(keyPrime, "=");


	for (i = 0; envArray[i] != NULL; i++) {
		if (strstr(envArray[i], keyPrime) == envArray[i]) {
			break;
		}
	}

	return i;
}


// Don't screw with my return value...
const char* myGetEnv(const char** envArray, const char* key) {
	int i;

	i = envIndex(envArray, key);

	if (envArray[i] == NULL) return NULL;
	else return (envArray[i]+strlen(key)+1);
}


void printenvMulti(const char* key) {
	char* s;

	s = myGetEnv(_environ, key);
	if (s == NULL) printf("%s is not in _environ\n", key);
	else printf("myGetEnv(_environ, \"%s\") --> %s\n", key, s);

	s = myGetEnv(environ, key);
	if (s == NULL) printf("%s is not in environ\n", key);
	else printf("myGetEnv(environ, \"%s\") --> %s\n", key, s);

	s = getenv(key);
	if (s == NULL) printf("%s is not available to getenv()\n", key);
	else printf("getenv(\"%s\") --> %s\n", key, s);
}


int main(int argc, char** argv) {
	assert(argv[1] != NULL);

	printenvMulti(argv[1]);
	return 0;
}
----------------------------------------------------------------------

--
              Milton L. Hankins              \\  ><> Ezekiel 18:21 ><>
Software Engineer, Raytheon Systems Company  //  <mlh at swl.msd.ray.com>
      http://amasts.msd.ray.com/~mlh         \\  RayComNet  7-225-4728







More information about the Python-list mailing list