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