Author: faridz
Date: Sat Mar 15 19:01:12 2008
New Revision: 637508

URL: http://svn.apache.org/viewvc?rev=637508&view=rev
Log:
2008-03-16 Farid Zaripov <[EMAIL PROTECTED]>

        STDCXX-646
        * tests/src/environ.cpp (rw_putenv): Worked around the putenv()
        limitations on Windows.

Modified:
    stdcxx/trunk/tests/src/environ.cpp

Modified: stdcxx/trunk/tests/src/environ.cpp
URL: 
http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/environ.cpp?rev=637508&r1=637507&r2=637508&view=diff
==============================================================================
--- stdcxx/trunk/tests/src/environ.cpp (original)
+++ stdcxx/trunk/tests/src/environ.cpp Sat Mar 15 19:01:12 2008
@@ -93,7 +93,8 @@
 
         const size_t varlen = pend - pvar;
 
-        char* const envvar = (char*)malloc (pend - pvar + 1);
+        // reserve the one more character for Windows mode
+        char* const envvar = (char*)malloc (varlen + 2);
         if (0 == envvar)
             return -1;
 
@@ -101,10 +102,13 @@
         envvar [varlen] = '\0';
 
         // look for the first equals sign
-        const char* const equals = strchr (envvar, '=');
+        char* const equals = strchr (envvar, '=');
 
         char *var = 0;
 
+        // putenv mode: 0 - POSIX; 1 - undefined; 2 - Windows
+        static int mode = 1;
+
         if (equals) {
             // add the variable to the environment or modify it if
             // it's already defined
@@ -112,21 +116,46 @@
             // Note: calling Solaris 7 putenv() during program startup
             // (i.e., from ctors of namespace-scope objects) prevents
             // getenv() from finding that variable at program runtime
-            ret = putenv (envvar);
+
+            char namebuf [256];
+            const size_t namelen = equals - envvar;
+            assert (namelen < sizeof (namebuf));
+
+            memcpy (namebuf, envvar, namelen);
+            namebuf [namelen] = '\0';
+
+            switch (!equals [1] * mode) {
+            case 0:
+                ret = putenv (envvar);
+                break;
+            case 1:
+                ret = putenv (envvar);
+                if (getenv (namebuf)) {
+                    mode = 0;
+                    break;
+                }
+                mode = 2;
+                // fall through
+            case 2:
+                // on Windows it's impossible to set empty environment variable
+                // append any character after '='
+                equals [1] = '1';
+                equals [2] = '\0';
+                ret = putenv (envvar);
+                equals [1] = '\0';
+                break;
+            }
 
             // determine wheteher putenv() made copy of the variable
             // or if it simply used the pointer passed to it; if the
             // former, deallocate the buffer dynamically allocated
             // above
-
-            char namebuf [256];
-            assert (size_t (equals - envvar) < sizeof namebuf);
-
-            memcpy (namebuf, envvar, equals - envvar);
-            namebuf [equals - envvar] = '\0';
-
             var = getenv (namebuf);
 
+            // empty the environment variable directly on Windows
+            if (!equals [1] && 2 == mode)
+                *var = '\0';
+
             if (equals + 1 != var)
                 free (envvar);
         }
@@ -143,7 +172,27 @@
             ret = unsetenv (envvar);
 #  endif   // FreeBSD ...
 #else   // ifdef _RWSTD_NO_UNSETENV
-            ret = putenv (envvar);
+            switch (mode) {
+            case 0:
+                ret = putenv (envvar);
+                break;
+            case 1:
+                ret = putenv (envvar);
+                if (!getenv (envvar)) {
+                    mode = 0;
+                    break;
+                }
+                mode = 2;
+                // fall through
+            case 2:
+                // on Windows append '=' character to remove
+                // the environment variable
+                envvar [varlen] = '=';
+                envvar [varlen + 1] = '\0';
+                ret = putenv (envvar);
+                envvar [varlen] = '\0';
+                break;
+            }
 #endif   // _RWSTD_NO_UNSETENV
 
             if (0 == ret) {


Reply via email to