http://bugs.winehq.org/show_bug.cgi?id=8924
--- Comment #33 from jvlad dmda@yandex.ru 2009-10-03 01:54:44 ---
Apps should not save the pointer returned by getenv().
Maybe you're right. But I didn't find any documents specifying how long such pointers can be used. Seems MSVCRT leaves all previously allocated environment blocks intact, so the pointers can be used for whole the process lifetime.
If you take a look at the php.exe sources (that's the application I talked about from the beginning of this issue), you'll find that they are calling getenv and keep the pointers for relatively short period - the startup. It reads all the values keeping the pointers, adds new values, then uses them all See init_request_info() in cgi_main.c:
static void init_request_info(TSRMLS_D) { char *env_script_filename = sapi_cgibin_getenv("SCRIPT_FILENAME",0 TSRMLS_CC); char *env_path_translated = sapi_cgibin_getenv("PATH_TRANSLATED",0 TSRMLS_CC); ^^^^^^^^^ reads the pointers
if (env_path_translated) { _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED",env_path_translated TSRMLS_CC); } if (env_path_info) { _sapi_cgibin_putenv("ORIG_PATH_INFO",env_path_info TSRMLS_CC); } if (env_script_name) { _sapi_cgibin_putenv("ORIG_SCRIPT_NAME",env_script_name TSRMLS_CC); } if (env_script_filename) { _sapi_cgibin_putenv("ORIG_SCRIPT_FILENAME",env_script_filename TSRMLS_CC); } ^^^^^^^^^^^^^^^^^^^^ updates the environment
if (script_path_translated && stat( script_path_translated, &st ) == -1 ) { ^^^^^^^^^^^^^^^^^^ then uses the pointers
And it all works fine under windows. It this is a "bug" in MSVCRT that it preserves old block intact after it allocates new buffer for the environment, this bug should be reproduced in wine (IMHO). (Still it's my assumption that MSVCRT works this way and does not free the blocks, I didn't try to neither reengineer it nor learn its sources)