VirtualBox

Changeset 80827 in vbox for trunk/src/VBox/Runtime/generic


Ignore:
Timestamp:
Sep 16, 2019 2:04:02 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
133397
Message:

IPRT: Added RTEnvCreateEx and RTEnvCreateChangeRecordEx so flags can be specified when creating custom environments. Defined one flag RTENV_CREATE_F_ALLOW_EQUAL_FIRST_IN_VAR for accomodating windows style environment variables (used for CWD by driver letter). The flag is set by default on windows hosts, however it does not work for the default environment due to CRT limitations.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/generic/env-generic.cpp

    r80764 r80827  
    8080
    8181
     82/** @def RTENV_ALLOW_EQUAL_FIRST_IN_VAR
     83 * Allows a variable to start with an '=' sign.  This is used by windows to
     84 * maintain CWDs of non-current drives.
     85 * @note Not supported by _wputenv AFAIK. */
     86#if defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
     87# define RTENV_ALLOW_EQUAL_FIRST_IN_VAR 1
     88#endif
     89
     90
    8291/*********************************************************************************************************************************
    8392*   Structures and Typedefs                                                                                                      *
     
    92101    /** Set if this is a record of environment changes, putenv style. */
    93102    bool        fPutEnvBlock;
     103    /** Set if starting a variable with an equal sign is okay, clear if not okay
     104     * (RTENV_CREATE_F_ALLOW_EQUAL_FIRST_IN_VAR). */
     105    bool        fFirstEqual;
    94106    /** Number of variables in the array.
    95107     * This does not include the terminating NULL entry. */
     
    142154 *                          block.  We will keep unsets in putenv format, i.e.
    143155 *                          just the variable name without any equal sign.
    144  */
    145 static int rtEnvCreate(PRTENVINTERNAL *ppIntEnv, size_t cAllocated, bool fCaseSensitive, bool fPutEnvBlock)
     156 * @param   fFirstEqual     The RTENV_CREATE_F_ALLOW_EQUAL_FIRST_IN_VAR value.
     157                                                      */
     158static int rtEnvCreate(PRTENVINTERNAL *ppIntEnv, size_t cAllocated, bool fCaseSensitive, bool fPutEnvBlock, bool fFirstEqual)
    146159{
    147160    /*
     
    156169        pIntEnv->u32Magic = RTENV_MAGIC;
    157170        pIntEnv->fPutEnvBlock = fPutEnvBlock;
     171        pIntEnv->fFirstEqual = fFirstEqual;
    158172        pIntEnv->pfnCompare = fCaseSensitive ? RTStrNCmp : RTStrNICmp;
    159173        pIntEnv->papszEnvOtherCP = NULL;
     
    177191{
    178192    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    179     return rtEnvCreate(pEnv, RTENV_GROW_SIZE, true /*fCaseSensitive*/, false /*fPutEnvBlock*/);
     193#ifdef RTENV_ALLOW_EQUAL_FIRST_IN_VAR
     194    return rtEnvCreate(pEnv, RTENV_GROW_SIZE, true /*fCaseSensitive*/, false /*fPutEnvBlock*/, true /*fFirstEqual*/);
     195#else
     196    return rtEnvCreate(pEnv, RTENV_GROW_SIZE, true /*fCaseSensitive*/, false /*fPutEnvBlock*/, false/*fFirstEqual*/);
     197#endif
    180198}
    181199RT_EXPORT_SYMBOL(RTEnvCreate);
     200
     201
     202RTDECL(int) RTEnvCreateEx(PRTENV phEnv, uint32_t fFlags)
     203{
     204    AssertPtrReturn(phEnv, VERR_INVALID_POINTER);
     205    AssertReturn(!(fFlags & ~RTENV_CREATE_F_VALID_MASK), VERR_INVALID_FLAGS);
     206    return rtEnvCreate(phEnv, RTENV_GROW_SIZE, true /*fCaseSensitive*/, false /*fPutEnvBlock*/,
     207                       RT_BOOL(fFlags & RTENV_CREATE_F_ALLOW_EQUAL_FIRST_IN_VAR));
     208}
     209RT_EXPORT_SYMBOL(RTEnvCreateEx);
    182210
    183211
     
    233261    bool fCaseSensitive = true;
    234262    bool fPutEnvBlock   = false;
     263    bool fFirstEqual    = false;
    235264    size_t cVars;
    236265    const char * const *papszEnv;
     
    267296        fCaseSensitive = false;
    268297#endif
     298#ifdef RTENV_ALLOW_EQUAL_FIRST_IN_VAR
     299        fFirstEqual = true;
     300#endif
    269301    }
    270302    else
     
    276308
    277309        fPutEnvBlock = pIntEnvToClone->fPutEnvBlock;
     310        fFirstEqual = pIntEnvToClone->fFirstEqual;
    278311        papszEnv = pIntEnvToClone->papszEnv;
    279312        cVars = pIntEnvToClone->cVars;
     
    284317     */
    285318    PRTENVINTERNAL pIntEnv;
    286     int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive, fPutEnvBlock);
     319    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive, fPutEnvBlock, fFirstEqual);
    287320    if (RT_SUCCESS(rc))
    288321    {
     
    372405     */
    373406    PRTENVINTERNAL pIntEnv;
    374     int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, false /*fCaseSensitive*/, false /*fPutEnvBlock*/);
     407#ifdef RTENV_ALLOW_EQUAL_FIRST_IN_VAR
     408    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, false /*fCaseSensitive*/, false /*fPutEnvBlock*/, true /*fFirstEqual*/);
     409#else
     410    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, false /*fCaseSensitive*/, false /*fPutEnvBlock*/, false /*fFirstEqual*/);
     411#endif
    375412    if (RT_SUCCESS(rc))
    376413    {
     
    586623{
    587624    AssertPtrReturn(pszVar, VERR_INVALID_POINTER);
    588     AssertReturn(*pszVar, VERR_INVALID_PARAMETER);
    589625    AssertPtrReturn(pszValue, VERR_INVALID_POINTER);
    590626    size_t const cchVar = strlen(pszVar);
     627    AssertReturn(cchVar > 0, VERR_ENV_INVALID_VAR_NAME);
     628#ifdef RTENV_ALLOW_EQUAL_FIRST_IN_VAR
     629    char const *pszEq = (char const *)memchr(pszVar, '=', cchVar);
     630    if (!pszEq)
     631    { /* likely */ }
     632    else
     633    {
     634        AssertReturn(Env != RTENV_DEFAULT, VERR_ENV_INVALID_VAR_NAME);
     635        PRTENVINTERNAL pIntEnv = Env;
     636        AssertPtrReturn(pIntEnv, VERR_INVALID_HANDLE);
     637        AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
     638        AssertReturn(pIntEnv->fFirstEqual, VERR_ENV_INVALID_VAR_NAME);
     639        AssertReturn(memchr(pszVar + 1, '=', cchVar - 1) == NULL, VERR_ENV_INVALID_VAR_NAME);
     640    }
     641#else
    591642    AssertReturn(memchr(pszVar, '=', cchVar) == NULL, VERR_ENV_INVALID_VAR_NAME);
     643#endif
    592644
    593645    return rtEnvSetExWorker(Env, pszVar, cchVar, pszValue);
     
    599651{
    600652    AssertPtrReturn(pszVar, VERR_INVALID_POINTER);
    601     AssertReturn(*pszVar, VERR_INVALID_PARAMETER);
    602     AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
     653    AssertReturn(*pszVar, VERR_ENV_INVALID_VAR_NAME);
    603654
    604655    int rc;
     
    627678        AssertPtrReturn(pIntEnv, VERR_INVALID_HANDLE);
    628679        AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
     680        const size_t cchVar = strlen(pszVar);
     681        AssertReturn(cchVar > 0, VERR_ENV_INVALID_VAR_NAME);
     682        AssertReturn(strchr(pIntEnv->fFirstEqual ? pszVar + 1 : pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
    629683
    630684        RTENV_LOCK(pIntEnv);
     
    634688         */
    635689        rc = VINF_ENV_VAR_NOT_FOUND;
    636         const size_t cchVar = strlen(pszVar);
    637690        size_t iVar;
    638691        for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
     
    689742    AssertPtrReturn(pszVarEqualValue, VERR_INVALID_POINTER);
    690743    const char *pszEq = strchr(pszVarEqualValue, '=');
     744#ifdef RTENV_ALLOW_EQUAL_FIRST_IN_VAR
     745    if (   pszEq == pszVarEqualValue
     746        && Env != RTENV_DEFAULT)
     747    {
     748        PRTENVINTERNAL pIntEnv = Env;
     749        AssertPtrReturn(pIntEnv, VERR_INVALID_HANDLE);
     750        AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
     751        if (pIntEnv->fFirstEqual)
     752            pszEq = strchr(pszVarEqualValue + 1, '=');
     753    }
     754#endif
    691755    if (!pszEq)
    692756        rc = RTEnvUnsetEx(Env, pszVarEqualValue);
    693757    else
     758    {
     759        AssertReturn(pszEq != pszVarEqualValue, VERR_ENV_INVALID_VAR_NAME);
    694760        rc = rtEnvSetExWorker(Env, pszVarEqualValue, pszEq - pszVarEqualValue, pszEq + 1);
     761    }
    695762    return rc;
    696763}
     
    704771    AssertPtrNullReturn(pcchActual, VERR_INVALID_POINTER);
    705772    AssertReturn(pcchActual || (pszValue && cbValue), VERR_INVALID_PARAMETER);
    706     AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
    707773
    708774    if (pcchActual)
     
    755821        AssertPtrReturn(pIntEnv, VERR_INVALID_HANDLE);
    756822        AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
     823        const size_t cchVar = strlen(pszVar);
     824        AssertReturn(cchVar > 0, VERR_ENV_INVALID_VAR_NAME);
     825        AssertReturn(strchr(pIntEnv->fFirstEqual ? pszVar + 1 : pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
    757826
    758827        RTENV_LOCK(pIntEnv);
     
    762831         */
    763832        rc = VERR_ENV_VAR_NOT_FOUND;
    764         const size_t cchVar = strlen(pszVar);
    765833        size_t iVar;
    766834        for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
     
    827895        AssertPtrReturn(pIntEnv, false);
    828896        AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, false);
     897        const size_t cchVar = strlen(pszVar);
     898        AssertReturn(cchVar > 0, false);
     899        AssertReturn(strchr(pIntEnv->fFirstEqual ? pszVar + 1 : pszVar, '=') == NULL, false);
    829900
    830901        RTENV_LOCK(pIntEnv);
     
    833904         * Simple search.
    834905         */
    835         const size_t cchVar = strlen(pszVar);
    836906        for (size_t iVar = 0; iVar < pIntEnv->cVars; iVar++)
    837907            if (!pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar))
     
    12131283{
    12141284    AssertPtrReturn(phEnv, VERR_INVALID_POINTER);
    1215     return rtEnvCreate(phEnv, RTENV_GROW_SIZE, true /*fCaseSensitive*/, true /*fPutEnvBlock*/);
     1285#ifdef RTENV_ALLOW_EQUAL_FIRST_IN_VAR
     1286    return rtEnvCreate(phEnv, RTENV_GROW_SIZE, true /*fCaseSensitive*/, true /*fPutEnvBlock*/, true /*fFirstEqual*/);
     1287#else
     1288    return rtEnvCreate(phEnv, RTENV_GROW_SIZE, true /*fCaseSensitive*/, true /*fPutEnvBlock*/, false /*fFirstEqual*/);
     1289#endif
     1290}
     1291RT_EXPORT_SYMBOL(RTEnvCreateChangeRecord);
     1292
     1293
     1294RTDECL(int) RTEnvCreateChangeRecordEx(PRTENV phEnv, uint32_t fFlags)
     1295{
     1296    AssertPtrReturn(phEnv, VERR_INVALID_POINTER);
     1297    AssertReturn(!(fFlags & ~RTENV_CREATE_F_VALID_MASK), VERR_INVALID_FLAGS);
     1298    return rtEnvCreate(phEnv, RTENV_GROW_SIZE, true /*fCaseSensitive*/, true /*fPutEnvBlock*/,
     1299                       RT_BOOL(fFlags & RTENV_CREATE_F_ALLOW_EQUAL_FIRST_IN_VAR));
    12161300}
    12171301RT_EXPORT_SYMBOL(RTEnvCreateChangeRecord);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette