2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/* $Id$ */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @file
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * IPRT - Environment, Generic.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/*
f4c45a1ca8a0bbdb88cf32e34c29474850ab0ee8vboxsync * Copyright (C) 2006-2012 Oracle Corporation
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync *
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * available from http://www.virtualbox.org. This file is free software;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * you can redistribute it and/or modify it under the terms of the GNU
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * General Public License (GPL) as published by the Free Software
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync *
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * The contents of this file may alternatively be used under the terms
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * of the Common Development and Distribution License Version 1.0
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * VirtualBox OSE distribution, in which case the provisions of the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * CDDL are applicable instead of those of the GPL.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync *
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * You may elect to license modified versions of this file under the
7b9f0c34e9ea328981c99e97054bdf8684d9d620vboxsync * terms and conditions of either the GPL or the CDDL or both.
9e7e0b61d29309a0ed7af9472c8d6d865f9e8a2dvboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/*******************************************************************************
0fd108a555ae02f2fb557d5f2c40281999b60d15vboxsync* Header Files *
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync*******************************************************************************/
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/env.h>
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#include "internal/iprt.h"
b1cc3e87518139898395f96974ecff9e6bf228fbvboxsync
b1cc3e87518139898395f96974ecff9e6bf228fbvboxsync#include <iprt/assert.h>
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#include <iprt/alloc.h>
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync#include <iprt/alloca.h>
388b6b190a5407548753b7fde12fa58134ec3563vboxsync#include <iprt/string.h>
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync#include <iprt/sort.h>
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#include <iprt/err.h>
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#include "internal/magics.h"
f9ce005e61f0fbb51a2cabc53d58c3485151faa9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#include <stdlib.h>
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync#if !defined(RT_OS_WINDOWS)
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync# include <unistd.h>
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync#endif
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync#ifdef RT_OS_DARWIN
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync# include <crt_externs.h>
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#endif
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#if defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD) || defined(RT_OS_NETBSD) || defined(RT_OS_OPENBSD)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsyncRT_C_DECLS_BEGIN
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsyncextern char **environ;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsyncRT_C_DECLS_END
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#endif
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync/*******************************************************************************
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync* Defined Constants And Macros *
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync*******************************************************************************/
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync/** The allocation granularity of the RTENVINTERNAL::papszEnv memory. */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#define RTENV_GROW_SIZE 16
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync/** Macro that unlocks the specified environment block. */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#define RTENV_LOCK(pEnvInt) do { } while (0)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync/** Macro that unlocks the specified environment block. */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#define RTENV_UNLOCK(pEnvInt) do { } while (0)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync/** @def RTENV_HAVE_WENVIRON
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * Indicates that we have a _wenviron variable with UTF-16 strings that we
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * better use instead of the current-cp strings in environ. */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#if defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync# define RTENV_HAVE_WENVIRON 1
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#endif
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync/** @def RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * Indicates the RTEnv*Utf8 APIs are implemented. */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#if defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync# define RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API 1
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#endif
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync/*******************************************************************************
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync* Structures and Typedefs *
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync*******************************************************************************/
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync/**
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * The internal representation of a (non-default) environment.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync */
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsynctypedef struct RTENVINTERNAL
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync{
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync /** Magic value . */
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync uint32_t u32Magic;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync /** Number of variables in the array.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * This does not include the terminating NULL entry. */
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync size_t cVars;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync /** Capacity (allocated size) of the array.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * This includes space for the terminating NULL element (for compatibility
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * with the C library), so that c <= cCapacity - 1. */
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync size_t cAllocated;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync /** Array of environment variables. */
e38a1f5933935fe8db152ea06dac5aa1be27d870vboxsync char **papszEnv;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync /** Array of environment variables in the process CP.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * This get (re-)constructed when RTEnvGetExecEnvP method is called. */
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync char **papszEnvOtherCP;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync /** The compare function we're using. */
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync DECLCALLBACKMEMBER(int, pfnCompare)(const char *psz1, const char *psz2, size_t cchMax);
e38a1f5933935fe8db152ea06dac5aa1be27d870vboxsync} RTENVINTERNAL, *PRTENVINTERNAL;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync/**
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * Internal worker that resolves the pointer to the default
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * process environment. (environ)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync *
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @returns Pointer to the default environment.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * This may be NULL.
e38a1f5933935fe8db152ea06dac5aa1be27d870vboxsync */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsyncstatic const char * const *rtEnvDefault(void)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync{
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync#ifdef RT_OS_DARWIN
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync return *(_NSGetEnviron());
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync#else
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync return environ;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync#endif
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync}
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync/**
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * Internal worker that creates an environment handle with a specified capacity.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync *
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @returns IPRT status code.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @param ppIntEnv Where to store the result.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @param cAllocated The initial array size.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @param fCaseSensitive Whether the environment block is case sensitive or
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * not.
e38a1f5933935fe8db152ea06dac5aa1be27d870vboxsync */
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsyncstatic int rtEnvCreate(PRTENVINTERNAL *ppIntEnv, size_t cAllocated, bool fCaseSensitive)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync{
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync /*
581f0625e43a928987623d7cf59e1b1ab61ca6c8vboxsync * Allocate environment handle.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync PRTENVINTERNAL pIntEnv = (PRTENVINTERNAL)RTMemAlloc(sizeof(*pIntEnv));
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if (pIntEnv)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Pre-allocate the variable array.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pIntEnv->u32Magic = RTENV_MAGIC;
3f5dd727ecbcf3e99217c70f04bc2340beb9072cvboxsync pIntEnv->pfnCompare = fCaseSensitive ? RTStrNCmp : RTStrNICmp;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pIntEnv->papszEnvOtherCP = NULL;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pIntEnv->cVars = 0;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pIntEnv->cAllocated = RT_ALIGN_Z(RT_MAX(cAllocated, RTENV_GROW_SIZE), RTENV_GROW_SIZE);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pIntEnv->papszEnv = (char **)RTMemAllocZ(sizeof(pIntEnv->papszEnv[0]) * pIntEnv->cAllocated);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if (pIntEnv->papszEnv)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync *ppIntEnv = pIntEnv;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync return VINF_SUCCESS;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync }
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RTMemFree(pIntEnv);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync }
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync return VERR_NO_MEMORY;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncRTDECL(int) RTEnvCreate(PRTENV pEnv)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rtEnvCreate(pEnv, RTENV_GROW_SIZE, false /*fCaseSensitive*/);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync}
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsyncRT_EXPORT_SYMBOL(RTEnvCreate);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsyncRTDECL(int) RTEnvDestroy(RTENV Env)
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync{
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Ignore NIL_RTENV and validate input.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if ( Env == NIL_RTENV
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync || Env == RTENV_DEFAULT)
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync return VINF_SUCCESS;
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync PRTENVINTERNAL pIntEnv = Env;
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync AssertPtrReturn(pIntEnv, VERR_INVALID_HANDLE);
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync /*
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * Do the cleanup.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync RTENV_LOCK(pIntEnv);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pIntEnv->u32Magic++;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync size_t iVar = pIntEnv->cVars;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync while (iVar-- > 0)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync RTStrFree(pIntEnv->papszEnv[iVar]);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RTMemFree(pIntEnv->papszEnv);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pIntEnv->papszEnv = NULL;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync if (pIntEnv->papszEnvOtherCP)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync for (iVar = 0; pIntEnv->papszEnvOtherCP[iVar]; iVar++)
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync {
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync RTStrFree(pIntEnv->papszEnvOtherCP[iVar]);
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync pIntEnv->papszEnvOtherCP[iVar] = NULL;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync }
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync RTMemFree(pIntEnv->papszEnvOtherCP);
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync pIntEnv->papszEnvOtherCP = NULL;
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync }
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync RTENV_UNLOCK(pIntEnv);
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync /*RTCritSectDelete(&pIntEnv->CritSect) */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync RTMemFree(pIntEnv);
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync return VINF_SUCCESS;
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync}
c2590a722c15520a45551ed7dc02d4831fb1a48evboxsyncRT_EXPORT_SYMBOL(RTEnvDestroy);
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync
cd5df721f068659172f3bf95de8fedeb465f057dvboxsyncRTDECL(int) RTEnvClone(PRTENV pEnv, RTENV EnvToClone)
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync{
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /*
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * Validate input and figure out how many variable to clone and where to get them.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync */
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync bool fCaseSensitive = true;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync size_t cVars;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync const char * const *papszEnv;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync#ifdef RTENV_HAVE_WENVIRON
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync PCRTUTF16 const * papwszEnv;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync#endif
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync PRTENVINTERNAL pIntEnvToClone;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync if (EnvToClone == RTENV_DEFAULT)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync {
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync cVars = 0;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync pIntEnvToClone = NULL;
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync#ifdef RTENV_HAVE_WENVIRON
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync papszEnv = NULL;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync papwszEnv = (PCRTUTF16 * const)_wenviron;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync if (!papwszEnv)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync {
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync _wgetenv(L"Path"); /* Force the CRT to initalize it. */
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync papwszEnv = (PCRTUTF16 * const)_wenviron;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync }
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync if (papwszEnv)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync while (papwszEnv[cVars])
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync cVars++;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync#else
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync papszEnv = rtEnvDefault();
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync if (papszEnv)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync while (papszEnv[cVars])
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync cVars++;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync#endif
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync /* DOS systems was case insensitive. A prime example is the 'Path'
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync variable on windows which turns into the 'PATH' variable. */
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync fCaseSensitive = false;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#endif
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync else
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pIntEnvToClone = EnvToClone;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync AssertPtrReturn(pIntEnvToClone, VERR_INVALID_HANDLE);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync AssertReturn(pIntEnvToClone->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RTENV_LOCK(pIntEnvToClone);
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync papszEnv = pIntEnvToClone->papszEnv;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync cVars = pIntEnvToClone->cVars;
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync }
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Create the duplicate.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync PRTENVINTERNAL pIntEnv;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if (RT_SUCCESS(rc))
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pIntEnv->cVars = cVars;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pIntEnv->papszEnv[pIntEnv->cVars] = NULL;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if (EnvToClone == RTENV_DEFAULT)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync /* ASSUMES the default environment is in the current codepage. */
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync size_t iDst = 0;
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync for (size_t iSrc = 0; iSrc < cVars; iSrc++)
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync {
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync#ifdef RTENV_HAVE_WENVIRON
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc2 = RTUtf16ToUtf8(papwszEnv[iSrc], &pIntEnv->papszEnv[iDst]);
4517f3d60a86111c8b70238b29d59f26c15291a7vboxsync#else
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync int rc2 = RTStrCurrentCPToUtf8(&pIntEnv->papszEnv[iDst], papszEnv[iSrc]);
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync#endif
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync if (RT_SUCCESS(rc2))
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync iDst++;
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync else if (rc2 == VERR_NO_TRANSLATION)
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync rc = VWRN_ENV_NOT_FULLY_TRANSLATED;
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync else
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync {
f044158ee9eb7045a43f2c4ef2fbc07cb11329aevboxsync pIntEnv->cVars = iDst;
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync RTEnvDestroy(pIntEnv);
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync return rc2;
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync }
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync }
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync pIntEnv->cVars = iDst;
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync }
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync else
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync {
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync for (size_t iVar = 0; iVar < cVars; iVar++)
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync {
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync char *pszVar = RTStrDup(papszEnv[iVar]);
f044158ee9eb7045a43f2c4ef2fbc07cb11329aevboxsync if (RT_UNLIKELY(!pszVar))
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync {
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync RTENV_UNLOCK(pIntEnvToClone);
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync pIntEnv->cVars = iVar;
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync RTEnvDestroy(pIntEnv);
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync return VERR_NO_STR_MEMORY;
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync }
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync pIntEnv->papszEnv[iVar] = pszVar;
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync }
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync }
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync
f044158ee9eb7045a43f2c4ef2fbc07cb11329aevboxsync /* done */
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync *pEnv = pIntEnv;
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync }
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync if (pIntEnvToClone)
4517f3d60a86111c8b70238b29d59f26c15291a7vboxsync RTENV_UNLOCK(pIntEnvToClone);
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync return rc;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync}
cd5df721f068659172f3bf95de8fedeb465f057dvboxsyncRT_EXPORT_SYMBOL(RTEnvClone);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsyncRTDECL(int) RTEnvPutEx(RTENV Env, const char *pszVarEqualValue)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync{
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync int rc;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync AssertPtrReturn(pszVarEqualValue, VERR_INVALID_POINTER);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync const char *pszEq = strchr(pszVarEqualValue, '=');
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync if (!pszEq)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync rc = RTEnvUnsetEx(Env, pszVarEqualValue);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync else
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Make a copy of the variable name so we can terminate it
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync * properly and then pass the request on to RTEnvSetEx.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync const char *pszValue = pszEq + 1;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync size_t cchVar = pszEq - pszVarEqualValue;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync Assert(cchVar < 1024);
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync char *pszVar = (char *)alloca(cchVar + 1);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync memcpy(pszVar, pszVarEqualValue, cchVar);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pszVar[cchVar] = '\0';
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync rc = RTEnvSetEx(Env, pszVar, pszValue);
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync }
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync return rc;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync}
2f3883b126a405f92b19e829472f614c7352b4f9vboxsyncRT_EXPORT_SYMBOL(RTEnvPutEx);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsyncRTDECL(int) RTEnvSetEx(RTENV Env, const char *pszVar, const char *pszValue)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync{
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync AssertPtrReturn(pszVar, VERR_INVALID_POINTER);
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync AssertReturn(*pszVar, VERR_INVALID_PARAMETER);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync AssertPtrReturn(pszValue, VERR_INVALID_POINTER);
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync int rc;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if (Env == RTENV_DEFAULT)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#ifdef RT_OS_WINDOWS
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync rc = RTEnvSetUtf8(pszVar, pszValue);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#else
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Since RTEnvPut isn't UTF-8 clean and actually expects the strings
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * to be in the current code page (codeset), we'll do the necessary
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * conversions here.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync char *pszVarOtherCP;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync rc = RTStrUtf8ToCurrentCP(&pszVarOtherCP, pszVar);
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync if (RT_SUCCESS(rc))
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync char *pszValueOtherCP;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync rc = RTStrUtf8ToCurrentCP(&pszValueOtherCP, pszValue);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if (RT_SUCCESS(rc))
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync rc = RTEnvSet(pszVarOtherCP, pszValueOtherCP);
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync RTStrFree(pszValueOtherCP);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync }
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RTStrFree(pszVarOtherCP);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync }
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#endif
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync }
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync else
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync PRTENVINTERNAL pIntEnv = Env;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync AssertPtrReturn(pIntEnv, VERR_INVALID_HANDLE);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync /*
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * Create the variable string.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync const size_t cchVar = strlen(pszVar);
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync const size_t cchValue = strlen(pszValue);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync char *pszEntry = (char *)RTMemAlloc(cchVar + cchValue + 2);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync if (pszEntry)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync memcpy(pszEntry, pszVar, cchVar);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pszEntry[cchVar] = '=';
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync memcpy(&pszEntry[cchVar + 1], pszValue, cchValue + 1);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync RTENV_LOCK(pIntEnv);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /*
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync * Find the location of the variable. (iVar = cVars if new)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync rc = VINF_SUCCESS;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync size_t iVar;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync if ( !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync && pIntEnv->papszEnv[iVar][cchVar] == '=')
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync break;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if (iVar < pIntEnv->cVars)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync /*
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Replace the current entry. Simple.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RTMemFree(pIntEnv->papszEnv[iVar]);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pIntEnv->papszEnv[iVar] = pszEntry;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync }
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync else
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Adding a new variable. Resize the array if required
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * and then insert the new value at the end.
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync */
7e8ef90d3160234df0f254131b87af4243d79476vboxsync if (pIntEnv->cVars + 2 > pIntEnv->cAllocated)
7e8ef90d3160234df0f254131b87af4243d79476vboxsync {
7e8ef90d3160234df0f254131b87af4243d79476vboxsync void *pvNew = RTMemRealloc(pIntEnv->papszEnv, sizeof(char *) * (pIntEnv->cAllocated + RTENV_GROW_SIZE));
7e8ef90d3160234df0f254131b87af4243d79476vboxsync if (!pvNew)
7e8ef90d3160234df0f254131b87af4243d79476vboxsync rc = VERR_NO_MEMORY;
7e8ef90d3160234df0f254131b87af4243d79476vboxsync else
7e8ef90d3160234df0f254131b87af4243d79476vboxsync {
7e8ef90d3160234df0f254131b87af4243d79476vboxsync pIntEnv->papszEnv = (char **)pvNew;
7e8ef90d3160234df0f254131b87af4243d79476vboxsync pIntEnv->cAllocated += RTENV_GROW_SIZE;
7e8ef90d3160234df0f254131b87af4243d79476vboxsync for (size_t iNewVar = pIntEnv->cVars; iNewVar < pIntEnv->cAllocated; iNewVar++)
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync pIntEnv->papszEnv[iNewVar] = NULL;
7e8ef90d3160234df0f254131b87af4243d79476vboxsync }
7e8ef90d3160234df0f254131b87af4243d79476vboxsync }
7e8ef90d3160234df0f254131b87af4243d79476vboxsync if (RT_SUCCESS(rc))
7e8ef90d3160234df0f254131b87af4243d79476vboxsync {
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync pIntEnv->papszEnv[iVar] = pszEntry;
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync pIntEnv->papszEnv[iVar + 1] = NULL; /* this isn't really necessary, but doesn't hurt. */
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync pIntEnv->cVars++;
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync Assert(pIntEnv->cVars == iVar + 1);
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync }
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync }
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync RTENV_UNLOCK(pIntEnv);
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync if (RT_FAILURE(rc))
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync RTMemFree(pszEntry);
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync }
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync else
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync rc = VERR_NO_MEMORY;
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync }
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync return rc;
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync}
2f3883b126a405f92b19e829472f614c7352b4f9vboxsyncRT_EXPORT_SYMBOL(RTEnvSetEx);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsyncRTDECL(int) RTEnvUnsetEx(RTENV Env, const char *pszVar)
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync{
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync AssertPtrReturn(pszVar, VERR_INVALID_POINTER);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync AssertReturn(*pszVar, VERR_INVALID_PARAMETER);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync int rc;
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync if (Env == RTENV_DEFAULT)
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync {
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#ifdef RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync rc = RTEnvUnsetUtf8(pszVar);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#else
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync /*
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync * Since RTEnvUnset isn't UTF-8 clean and actually expects the strings
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * to be in the current code page (codeset), we'll do the necessary
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync * conversions here.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync char *pszVarOtherCP;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync rc = RTStrUtf8ToCurrentCP(&pszVarOtherCP, pszVar);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if (RT_SUCCESS(rc))
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync {
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync rc = RTEnvUnset(pszVarOtherCP);
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync RTStrFree(pszVarOtherCP);
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync }
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync#endif
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync }
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync else
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync {
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync PRTENVINTERNAL pIntEnv = Env;
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync AssertPtrReturn(pIntEnv, VERR_INVALID_HANDLE);
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync RTENV_LOCK(pIntEnv);
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync /*
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync * Remove all variable by the given name.
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync */
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync rc = VINF_ENV_VAR_NOT_FOUND;
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync const size_t cchVar = strlen(pszVar);
1cd59fdf671ca60c64d77e3f7046aaecf7003824vboxsync size_t iVar;
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if ( !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync && pIntEnv->papszEnv[iVar][cchVar] == '=')
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RTMemFree(pIntEnv->papszEnv[iVar]);
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync pIntEnv->cVars--;
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync if (pIntEnv->cVars > 0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pIntEnv->papszEnv[iVar] = pIntEnv->papszEnv[pIntEnv->cVars];
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync pIntEnv->papszEnv[pIntEnv->cVars] = NULL;
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync rc = VINF_SUCCESS;
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync /* no break, there could be more. */
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync }
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync RTENV_UNLOCK(pIntEnv);
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync }
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync return rc;
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync}
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsyncRT_EXPORT_SYMBOL(RTEnvUnsetEx);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsyncRTDECL(int) RTEnvGetEx(RTENV Env, const char *pszVar, char *pszValue, size_t cbValue, size_t *pcchActual)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync{
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync AssertPtrReturn(pszVar, VERR_INVALID_POINTER);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync AssertPtrNullReturn(pszValue, VERR_INVALID_POINTER);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync AssertPtrNullReturn(pcchActual, VERR_INVALID_POINTER);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync AssertReturn(pcchActual || (pszValue && cbValue), VERR_INVALID_PARAMETER);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync if (pcchActual)
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync *pcchActual = 0;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync int rc;
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync if (Env == RTENV_DEFAULT)
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync {
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync#ifdef RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync rc = RTEnvGetUtf8(pszVar, pszValue, cbValue, pcchActual);
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync#else
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync /*
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync * Since RTEnvGet isn't UTF-8 clean and actually expects the strings
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync * to be in the current code page (codeset), we'll do the necessary
53b41bf9cfe74839ada5f98dca17cddcb47cf687vboxsync * conversions here.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync char *pszVarOtherCP;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync rc = RTStrUtf8ToCurrentCP(&pszVarOtherCP, pszVar);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if (RT_SUCCESS(rc))
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync const char *pszValueOtherCP = RTEnvGet(pszVarOtherCP);
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync RTStrFree(pszVarOtherCP);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync if (pszValueOtherCP)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync char *pszValueUtf8;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync rc = RTStrCurrentCPToUtf8(&pszValueUtf8, pszValueOtherCP);
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync if (RT_SUCCESS(rc))
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync rc = VINF_SUCCESS;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync size_t cch = strlen(pszValueUtf8);
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync if (pcchActual)
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync *pcchActual = cch;
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync if (pszValue && cbValue)
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync {
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync if (cch < cbValue)
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync memcpy(pszValue, pszValueUtf8, cch + 1);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync else
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync rc = VERR_BUFFER_OVERFLOW;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync }
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RTStrFree(pszValueUtf8);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync }
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync }
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync else
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync rc = VERR_ENV_VAR_NOT_FOUND;
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync }
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync#endif
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync }
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync else
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync {
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync PRTENVINTERNAL pIntEnv = Env;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync AssertPtrReturn(pIntEnv, VERR_INVALID_HANDLE);
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync RTENV_LOCK(pIntEnv);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /*
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * Locate the first variable and return it to the caller.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_ENV_VAR_NOT_FOUND;
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync const size_t cchVar = strlen(pszVar);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync size_t iVar;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if ( !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync && pIntEnv->papszEnv[iVar][cchVar] == '=')
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync {
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync rc = VINF_SUCCESS;
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync const char *pszValueOrg = pIntEnv->papszEnv[iVar] + cchVar + 1;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync size_t cch = strlen(pszValueOrg);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pcchActual)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync *pcchActual = cch;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pszValue && cbValue)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (cch < cbValue)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync memcpy(pszValue, pszValueOrg, cch + 1);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync else
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc = VERR_BUFFER_OVERFLOW;
c193ae401647c574d0ef52af57c32cf5d7c44966vboxsync }
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync break;
c193ae401647c574d0ef52af57c32cf5d7c44966vboxsync }
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
c193ae401647c574d0ef52af57c32cf5d7c44966vboxsync RTENV_UNLOCK(pIntEnv);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync return rc;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync}
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsyncRT_EXPORT_SYMBOL(RTEnvGetEx);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncRTDECL(bool) RTEnvExistEx(RTENV Env, const char *pszVar)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(pszVar, false);
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync bool fExists = false;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync if (Env == RTENV_DEFAULT)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync {
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync#ifdef RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync fExists = RTEnvExistsUtf8(pszVar);
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync#else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /*
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * Since RTEnvExist isn't UTF-8 clean and actually expects the strings
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * to be in the current code page (codeset), we'll do the necessary
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * conversions here.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync */
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync char *pszVarOtherCP;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync int rc = RTStrUtf8ToCurrentCP(&pszVarOtherCP, pszVar);
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync if (RT_SUCCESS(rc))
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync {
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync fExists = RTEnvExist(pszVarOtherCP);
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync RTStrFree(pszVarOtherCP);
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync }
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync#endif
510567648d46488f4166e5f69ffffe3eeeeec4d9vboxsync }
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync else
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync {
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync PRTENVINTERNAL pIntEnv = Env;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync AssertPtrReturn(pIntEnv, false);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, false);
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync RTENV_LOCK(pIntEnv);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /*
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Simple search.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync */
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync const size_t cchVar = strlen(pszVar);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync for (size_t iVar = 0; iVar < pIntEnv->cVars; iVar++)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if ( !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync && pIntEnv->papszEnv[iVar][cchVar] == '=')
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync fExists = true;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync break;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync RTENV_UNLOCK(pIntEnv);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync return fExists;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync}
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsyncRT_EXPORT_SYMBOL(RTEnvExistEx);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsyncRTDECL(char const * const *) RTEnvGetExecEnvP(RTENV Env)
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync{
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync const char * const *papszRet;
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync if (Env == RTENV_DEFAULT)
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync {
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync /** @todo fix this API it's fundamentally wrong! */
4517f3d60a86111c8b70238b29d59f26c15291a7vboxsync papszRet = rtEnvDefault();
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (!papszRet)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync static const char * const s_papszDummy[2] = { NULL, NULL };
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync papszRet = &s_papszDummy[0];
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync else
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync PRTENVINTERNAL pIntEnv = Env;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync AssertPtrReturn(pIntEnv, NULL);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, NULL);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync RTENV_LOCK(pIntEnv);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /*
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync * Free any old envp.
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (pIntEnv->papszEnvOtherCP)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync for (size_t iVar = 0; pIntEnv->papszEnvOtherCP[iVar]; iVar++)
dea3e7faa80f4aab41e08945b9308fd2e3ffe7fcvboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync RTStrFree(pIntEnv->papszEnvOtherCP[iVar]);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync pIntEnv->papszEnvOtherCP[iVar] = NULL;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync RTMemFree(pIntEnv->papszEnvOtherCP);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync pIntEnv->papszEnvOtherCP = NULL;
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /*
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync * Construct a new envp with the strings in the process code set.
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync char **papsz;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync papszRet = pIntEnv->papszEnvOtherCP = papsz = (char **)RTMemAlloc(sizeof(char *) * (pIntEnv->cVars + 1));
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (papsz)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync papsz[pIntEnv->cVars] = NULL;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync for (size_t iVar = 0; iVar < pIntEnv->cVars; iVar++)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync int rc = RTStrUtf8ToCurrentCP(&papsz[iVar], pIntEnv->papszEnv[iVar]);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_FAILURE(rc))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* RTEnvDestroy / we cleans up later. */
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync papsz[iVar] = NULL;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync AssertRC(rc);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync papszRet = NULL;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync break;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync RTENV_UNLOCK(pIntEnv);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync return papszRet;
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync}
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsyncRT_EXPORT_SYMBOL(RTEnvGetExecEnvP);
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync/**
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync * RTSort callback for comparing two environment variables.
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync *
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync * @returns -1, 0, 1. See PFNRTSORTCMP.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * @param pvElement1 Variable 1.
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync * @param pvElement2 Variable 2.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * @param pvUser Ignored.
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync */
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsyncDECLCALLBACK(int) rtEnvSortCompare(const void *pvElement1, const void *pvElement2, void *pvUser)
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync{
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync NOREF(pvUser);
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync int iDiff = strcmp((const char *)pvElement1, (const char *)pvElement2);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (iDiff < 0)
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync iDiff = -1;
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync else if (iDiff > 0)
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync iDiff = 1;
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync return iDiff;
56484ba959c372f0196716100568e02412b0dbd5vboxsync}
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync
4517f3d60a86111c8b70238b29d59f26c15291a7vboxsync
f044158ee9eb7045a43f2c4ef2fbc07cb11329aevboxsyncRTDECL(int) RTEnvQueryUtf16Block(RTENV hEnv, PRTUTF16 *ppwszzBlock)
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync{
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync RTENV hClone = NIL_RTENV;
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync PRTENVINTERNAL pIntEnv;
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync int rc;
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /*
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync * Validate / simplify input.
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync if (hEnv == RTENV_DEFAULT)
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync {
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync rc = RTEnvClone(&hClone, RTENV_DEFAULT);
e86baafe99d1f1eb37adcca5fdecfd06e7f13bc5vboxsync if (RT_FAILURE(rc))
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync return rc;
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync pIntEnv = hClone;
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync }
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync else
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync pIntEnv = hEnv;
b8bb9c9f6b8ebfd0a7d6df0c0289f9fe80241750vboxsync AssertPtrReturn(pIntEnv, VERR_INVALID_HANDLE);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync rc = VINF_SUCCESS;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync RTENV_LOCK(pIntEnv);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /*
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync * Sort it first.
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync */
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync RTSortApvShell((void **)pIntEnv->papszEnv, pIntEnv->cVars, rtEnvSortCompare, pIntEnv);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /*
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync * Calculate the size.
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync size_t cwc;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync size_t cwcTotal = 2;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync for (size_t iVar = 0; iVar < pIntEnv->cVars; iVar++)
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = RTStrCalcUtf16LenEx(pIntEnv->papszEnv[iVar], RTSTR_MAX, &cwc);
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync AssertRCBreak(rc);
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync cwcTotal += cwc + 1;
5050fc8de0b121eab1b738d7c1007cde4903284dvboxsync }
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync PRTUTF16 pwszzBlock = NULL;
b8bb9c9f6b8ebfd0a7d6df0c0289f9fe80241750vboxsync if (RT_SUCCESS(rc))
b8bb9c9f6b8ebfd0a7d6df0c0289f9fe80241750vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /*
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync * Perform the conversion.
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync PRTUTF16 pwszz = pwszzBlock = (PRTUTF16)RTMemAlloc(cwcTotal * sizeof(RTUTF16));
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync if (pwszz)
5050fc8de0b121eab1b738d7c1007cde4903284dvboxsync {
5050fc8de0b121eab1b738d7c1007cde4903284dvboxsync size_t cwcLeft = cwcTotal;
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync for (size_t iVar = 0; iVar < pIntEnv->cVars; iVar++)
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync {
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync rc = RTStrToUtf16Ex(pIntEnv->papszEnv[iVar], RTSTR_MAX,
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync &pwszz, cwcTotal - (pwszz - pwszzBlock), &cwc);
ca3db470494a8b6eaec69ea37468a5cda65e2da8vboxsync AssertRCBreak(rc);
81dfa298981df637a707b142ebd03cb7d3385097vboxsync pwszz += cwc + 1;
81dfa298981df637a707b142ebd03cb7d3385097vboxsync cwcLeft -= cwc + 1;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync AssertBreakStmt(cwcLeft >= 2, rc = VERR_INTERNAL_ERROR_3);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync AssertStmt(cwcLeft == 2 || RT_FAILURE(rc), rc = VERR_INTERNAL_ERROR_2);
ca3db470494a8b6eaec69ea37468a5cda65e2da8vboxsync if (RT_SUCCESS(rc))
ca3db470494a8b6eaec69ea37468a5cda65e2da8vboxsync {
5050fc8de0b121eab1b738d7c1007cde4903284dvboxsync pwszz[0] = '\0';
ca3db470494a8b6eaec69ea37468a5cda65e2da8vboxsync pwszz[1] = '\0';
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
ca3db470494a8b6eaec69ea37468a5cda65e2da8vboxsync else
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync RTMemFree(pwszzBlock);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync pwszzBlock = NULL;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync else
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = VERR_NO_MEMORY;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
ca3db470494a8b6eaec69ea37468a5cda65e2da8vboxsync RTENV_UNLOCK(pIntEnv);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
ca3db470494a8b6eaec69ea37468a5cda65e2da8vboxsync if (hClone != NIL_RTENV)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync RTEnvDestroy(hClone);
ca3db470494a8b6eaec69ea37468a5cda65e2da8vboxsync if (RT_SUCCESS(rc))
5050fc8de0b121eab1b738d7c1007cde4903284dvboxsync *ppwszzBlock = pwszzBlock;
81dfa298981df637a707b142ebd03cb7d3385097vboxsync return rc;
81dfa298981df637a707b142ebd03cb7d3385097vboxsync}
81dfa298981df637a707b142ebd03cb7d3385097vboxsyncRT_EXPORT_SYMBOL(RTEnvGetExecEnvP);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
dea3e7faa80f4aab41e08945b9308fd2e3ffe7fcvboxsync
dea3e7faa80f4aab41e08945b9308fd2e3ffe7fcvboxsyncRTDECL(void) RTEnvFreeUtf16Block(PRTUTF16 pwszzBlock)
dea3e7faa80f4aab41e08945b9308fd2e3ffe7fcvboxsync{
81dfa298981df637a707b142ebd03cb7d3385097vboxsync RTMemFree(pwszzBlock);
81dfa298981df637a707b142ebd03cb7d3385097vboxsync}
81dfa298981df637a707b142ebd03cb7d3385097vboxsyncRT_EXPORT_SYMBOL(RTEnvFreeUtf16Block);
81dfa298981df637a707b142ebd03cb7d3385097vboxsync
81dfa298981df637a707b142ebd03cb7d3385097vboxsync
81dfa298981df637a707b142ebd03cb7d3385097vboxsyncRTDECL(uint32_t) RTEnvCountEx(RTENV hEnv)
81dfa298981df637a707b142ebd03cb7d3385097vboxsync{
81dfa298981df637a707b142ebd03cb7d3385097vboxsync PRTENVINTERNAL pIntEnv = hEnv;
81dfa298981df637a707b142ebd03cb7d3385097vboxsync AssertPtrReturn(pIntEnv, UINT32_MAX);
81dfa298981df637a707b142ebd03cb7d3385097vboxsync AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, UINT32_MAX);
81dfa298981df637a707b142ebd03cb7d3385097vboxsync
81dfa298981df637a707b142ebd03cb7d3385097vboxsync RTENV_LOCK(pIntEnv);
81dfa298981df637a707b142ebd03cb7d3385097vboxsync uint32_t cVars = (uint32_t)pIntEnv->cVars;
81dfa298981df637a707b142ebd03cb7d3385097vboxsync RTENV_UNLOCK(pIntEnv);
81dfa298981df637a707b142ebd03cb7d3385097vboxsync
81dfa298981df637a707b142ebd03cb7d3385097vboxsync return cVars;
81dfa298981df637a707b142ebd03cb7d3385097vboxsync}
81dfa298981df637a707b142ebd03cb7d3385097vboxsyncRT_EXPORT_SYMBOL(RTEnvCountEx);
81dfa298981df637a707b142ebd03cb7d3385097vboxsync
81dfa298981df637a707b142ebd03cb7d3385097vboxsync
81dfa298981df637a707b142ebd03cb7d3385097vboxsyncRTDECL(uint32_t) RTEnvGetByIndexEx(RTENV hEnv, uint32_t iVar, char *pszVar, size_t cbVar, char *pszValue, size_t cbValue)
81dfa298981df637a707b142ebd03cb7d3385097vboxsync{
5050fc8de0b121eab1b738d7c1007cde4903284dvboxsync PRTENVINTERNAL pIntEnv = hEnv;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(pIntEnv, UINT32_MAX);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, UINT32_MAX);
ca3db470494a8b6eaec69ea37468a5cda65e2da8vboxsync if (cbVar)
ca3db470494a8b6eaec69ea37468a5cda65e2da8vboxsync AssertPtrReturn(pszVar, VERR_INVALID_POINTER);
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync if (cbValue)
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync AssertPtrReturn(pszValue, VERR_INVALID_POINTER);
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync RTENV_LOCK(pIntEnv);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync int rc;
88cc9bf61296bc5526344415167bb2625ae1dd99vboxsync if (iVar < pIntEnv->cVars)
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync const char *pszSrcVar = pIntEnv->papszEnv[iVar];
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync const char *pszSrcValue = strchr(pszSrcVar, '=');
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync bool fHasEqual = pszSrcValue != NULL;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (pszSrcValue)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync pszSrcValue++;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync else
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync pszSrcValue = strchr(pszSrcVar, '\0');
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = VINF_SUCCESS;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (cbVar)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = RTStrCopyEx(pszVar, cbVar, pszSrcVar, pszSrcValue - pszSrcVar - fHasEqual);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (cbValue)
d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync int rc2 = RTStrCopy(pszValue, cbValue, pszSrcValue);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = rc2;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync else
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = VERR_ENV_VAR_NOT_FOUND;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync RTENV_UNLOCK(pIntEnv);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync return rc;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync}
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsyncRT_EXPORT_SYMBOL(RTEnvGetByIndexEx);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync