From: Pierre Joye Date: Mon, 18 Aug 2008 07:09:20 +0000 (+0000) Subject: - [DOC] make putenv behaves like unix putenv on Windows: X-Git-Tag: BEFORE_HEAD_NS_CHANGE~669 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7a1487b0250cfc2cf75d55d2adde5cd48ee67c52;p=php - [DOC] make putenv behaves like unix putenv on Windows: . FOO=1234 => set FOO to 1234 . FOO= => set FOO to an empty string . FOO= => unset FOO . Use Set/GetEnvironmnent variable only --- diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 470c2bbead..754263f50d 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -61,7 +61,11 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #include #endif -#include +#ifndef PHP_WIN32 +# include +#else +# include "win32/inet.h" +#endif #if HAVE_ARPA_INET_H # include @@ -4391,15 +4395,39 @@ PHP_FUNCTION(getenv) /* SAPI method returns an emalloc()'d string */ ptr = sapi_getenv(str, str_len TSRMLS_CC); if (ptr) { - RETURN_RT_STRING(ptr, ZSTR_AUTOFREE); + RETURN_STRING(ptr, ZSTR_AUTOFREE); } +#ifdef PHP_WIN32 + { + char dummybuf; + int size; + + SetLastError(0); + /*If the given bugger is not large enough to hold the data, the return value is + the buffer size, in characters, required to hold the string and its terminating + null character. We use this return value to alloc the final buffer. */ + size = GetEnvironmentVariableA(str, &dummybuf, 0); + if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) { + /* The environment variable doesn't exist. */ + RETURN_FALSE; + } + + if (size == 0) { + /* env exists, but it is empty */ + RETURN_EMPTY_STRING(); + } + ptr = emalloc(size); + size = GetEnvironmentVariableA(str, ptr, size); + RETURN_STRING(ptr, 0); + } +#else /* system method returns a const */ ptr = getenv(str); if (ptr) { RETURN_RT_STRING(ptr, ZSTR_DUPLICATE); } - +#endif RETURN_FALSE; } /* }}} */ @@ -4419,14 +4447,33 @@ PHP_FUNCTION(putenv) if (setting_len) { char *p, **env; putenv_entry pe; +#ifdef PHP_WIN32 + char *value = NULL; + int equals = 0; +#endif pe.putenv_string = estrndup(setting, setting_len); pe.key = estrndup(setting, setting_len); if ((p = strchr(pe.key, '='))) { /* nullify the '=' if there is one */ *p = '\0'; +#ifdef PHP_WIN32 + equals = 1; +#endif } + pe.key_len = strlen(pe.key); +#ifdef PHP_WIN32 + if (equals) { + if (pe.key_len < setting_len - 2) { + value = p + 1; + } else { + /* empty string*/ + value = p; + } + } +#endif + zend_hash_del(&BG(putenv_ht), pe.key, pe.key_len+1); /* find previous value */ @@ -4443,23 +4490,19 @@ PHP_FUNCTION(putenv) } } -#if _MSC_VER >= 1300 - /* VS.Net has a bug in putenv() when setting a variable that - * is already set; if the SetEnvironmentVariable() API call - * fails, the Crt will double free() a string. - * We try to avoid this by setting our own value first */ - SetEnvironmentVariable(pe.key, "bugbug"); -#endif - #if HAVE_UNSETENV if (!p) { /* no '=' means we want to unset it */ unsetenv(pe.putenv_string); } if (!p || putenv(pe.putenv_string) == 0) { /* success */ #else +# ifndef PHP_WIN32 if (putenv(pe.putenv_string) == 0) { /* success */ +# else + if (SetEnvironmentVariableA(pe.key, value) != 0) { /* success */ +# endif #endif - zend_hash_add(&BG(putenv_ht), pe.key, pe.key_len+1, (void **) &pe, sizeof(putenv_entry), NULL); + zend_hash_add(&BG(putenv_ht), pe.key, pe.key_len + 1, (void **) &pe, sizeof(putenv_entry), NULL); #ifdef HAVE_TZSET if (!strncmp(pe.key, "TZ", pe.key_len)) { tzset();