os/ossrv/stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/environ.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /************************************************************************
     2  *
     3  * environ.cpp - definitions of testsuite helpers
     4  *
     5  * $Id: environ.cpp 290013 2005-09-18 23:47:55Z sebor $
     6  *
     7  ************************************************************************
     8  *
     9  * Copyright (c) 1994-2005 Quovadx,  Inc., acting through its  Rogue Wave
    10  * Software division. Licensed under the Apache License, Version 2.0 (the
    11  * "License");  you may  not use this file except  in compliance with the
    12  * License.    You    may   obtain   a   copy   of    the   License    at
    13  * http://www.apache.org/licenses/LICENSE-2.0.    Unless   required    by
    14  * applicable law  or agreed to  in writing,  software  distributed under
    15  * the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR
    16  * CONDITIONS OF  ANY KIND, either  express or implied.  See  the License
    17  * for the specific language governing permissions  and limitations under
    18  * the License.
    19  * 
    20  **************************************************************************/
    21 
    22 // expand _TEST_EXPORT macros
    23 #define _RWSTD_TEST_SRC
    24 
    25 #include <environ.h>
    26 
    27 #include <assert.h>   // for assert
    28 #include <stdlib.h>   // for getenv, malloc, putenv
    29 #include <string.h>   // for strchr, strlen, ...
    30 
    31 
    32 extern "C" {
    33 
    34 #ifndef _RWSTD_NO_PUTENV_CONST_CHAR
    35 
    36 IMPORT_C int putenv (const char*) _LIBC_THROWS ();
    37 
    38 #else   // if defined (_RWSTD_NO_PUTENV_CONST_CHAR)
    39 
    40 _RWSTD_DLLIMPORT int putenv (char*) _LIBC_THROWS ();
    41 
    42 #endif   // _RWSTD_NO_PUTENV_CONST_CHAR
    43 
    44 }   // extern "C"
    45 
    46 
    47 // sets one or more sep-separated environment variables
    48 _TEST_EXPORT int
    49 rw_putenv (const char* str, int sep /* = -1 */)
    50 {
    51     int nset = 0;
    52     int ret  = 0;
    53 
    54     if (!str) {
    55         str = getenv ("RW_PUTENV");
    56         if (str)
    57             sep = *str++;
    58         else
    59             return 0;
    60     }
    61 
    62     for (const char *pvar = str; pvar && *pvar; ++nset) {
    63 
    64         const char *pend = strchr (pvar, sep);
    65         if (!pend)
    66             pend = pvar + strlen (pvar);
    67 
    68         const size_t varlen = pend - pvar;
    69 
    70         char* const envvar = (char*)malloc (pend - pvar + 1);
    71         memcpy (envvar, pvar, varlen);
    72         envvar [varlen] = '\0';
    73 
    74         // Note: calling Solaris 7 putenv() during program startup
    75         // (i.e., from ctors of namespace-scope objects) prevents
    76         // getenv() from finding that variable at program runtime
    77         ret = putenv (envvar);
    78 
    79         // determine wheteher putenv() made copy of the variable
    80         // or if it simply used the pointer passed to it; if the
    81         // former, deallocate the buffer dynamically allocated
    82         // above
    83 
    84         char namebuf [256];
    85         char* const equals = strchr (envvar, '=');
    86         if (equals) {
    87             assert (size_t (equals - envvar) < sizeof namebuf);
    88 
    89             memcpy (namebuf, envvar, equals - envvar);
    90             namebuf [equals - envvar] = '\0';
    91 
    92             const char* const var = getenv (namebuf);
    93 
    94             if (equals + 1 != var)
    95                 free (envvar);
    96         }
    97         else
    98             free (envvar);
    99 
   100         pvar = pend + !!*pend;
   101     }
   102 
   103     if (1 == nset)
   104         return ret;
   105 
   106     return nset;
   107 }