VirtualBox

Changeset 55588 in vbox for trunk/src/VBox/Main/include


Ignore:
Timestamp:
May 1, 2015 7:37:46 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
99961
Message:

Main: Environment cleanup in the guest control area. The GuestEnvironment class implementation has been replaced by one based on IPRT's RTEnv API and it has been changed into a way of recording environment changes, thus renamed to GuestEnvironmentChanges.

Location:
trunk/src/VBox/Main/include
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h

    r55535 r55588  
    66
    77/*
    8  * Copyright (C) 2011-2013 Oracle Corporation
     8 * Copyright (C) 2011-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2121
    2222#include "ConsoleImpl.h"
     23#include "Global.h"
    2324
    2425#include <iprt/asm.h>
     26#include <iprt/env.h>
    2527#include <iprt/semaphore.h>
    2628
     
    6062
    6163
    62 typedef std::vector <Utf8Str> GuestEnvironmentArray;
    63 class GuestEnvironment
    64 {
    65 public:
    66 
    67     int BuildEnvironmentBlock(void **ppvEnv, size_t *pcbEnv, uint32_t *pcEnvVars);
    68 
    69     void Clear(void);
    70 
    71     int CopyFrom(const GuestEnvironmentArray &environment);
    72 
    73     int CopyTo(GuestEnvironmentArray &environment);
    74 
    75     static void FreeEnvironmentBlock(void *pvEnv);
    76 
    77     Utf8Str Get(const Utf8Str &strKey);
    78 
    79     Utf8Str Get(size_t nPos);
    80 
    81     bool Has(const Utf8Str &strKey);
    82 
    83     int Set(const Utf8Str &strKey, const Utf8Str &strValue);
    84 
    85     int Set(const Utf8Str &strPair);
    86 
    87     size_t Size(void);
    88 
    89     int Unset(const Utf8Str &strKey);
    90 
    91 public:
    92 
    93     GuestEnvironment& operator=(const GuestEnvironmentArray &that);
    94 
    95     GuestEnvironment& operator=(const GuestEnvironment &that);
    96 
    97 protected:
    98 
    99     int appendToEnvBlock(const char *pszEnv, void **ppvList, size_t *pcbList, uint32_t *pcEnvVars);
    100 
    101 protected:
    102 
    103     std::map <Utf8Str, Utf8Str> mEnvironment;
     64
     65/**
     66 * Wrapper around the RTEnv API, unusable base class.
     67 *
     68 * @remarks Feel free to elevate this class to iprt/cpp/env.h as RTCEnv.
     69 */
     70class GuestEnvironmentBase
     71{
     72public:
     73    /**
     74     * Default constructor.
     75     *
     76     * The user must invoke one of the init methods before using the object.
     77     */
     78    GuestEnvironmentBase(void)
     79        : m_hEnv(NIL_RTENV)
     80    { }
     81
     82    /**
     83     * Destructor.
     84     */
     85    virtual ~GuestEnvironmentBase(void)
     86    {
     87        int rc = RTEnvDestroy(m_hEnv); AssertRC(rc);
     88        m_hEnv = NIL_RTENV;
     89    }
     90
     91    /**
     92     * Initialize this as a normal environment block.
     93     * @returns IPRT status code.
     94     */
     95    int initNormal(void)
     96    {
     97        AssertReturn(m_hEnv == NIL_RTENV, VERR_WRONG_ORDER);
     98        return RTEnvCreate(&m_hEnv);
     99    }
     100
     101    /**
     102     * Returns the variable count.
     103     * @return Number of variables.
     104     * @sa      RTEnvCountEx
     105     */
     106    uint32_t count(void) const
     107    {
     108        return RTEnvCountEx(m_hEnv);
     109    }
     110
     111    /**
     112     * Deletes the environment change record entirely.
     113     *
     114     * The count() method will return zero after this call.
     115     *
     116     * @sa      RTEnvReset
     117     */
     118    void reset(void)
     119    {
     120        int rc = RTEnvReset(m_hEnv);
     121        AssertRC(rc);
     122    }
     123
     124    /**
     125     * Exports the environment change block as an array of putenv style strings.
     126     *
     127     *
     128     * @returns VINF_SUCCESS or VERR_NO_MEMORY.
     129     * @param   pArray              The output array.
     130     */
     131    int queryPutEnvArray(std::vector<com::Utf8Str> *pArray) const
     132    {
     133        uint32_t cVars = RTEnvCountEx(m_hEnv);
     134        try
     135        {
     136            pArray->resize(cVars);
     137            for (uint32_t iVar = 0; iVar < cVars; iVar++)
     138            {
     139                const char *psz = RTEnvGetByIndexRawEx(m_hEnv, iVar);
     140                AssertReturn(psz, VERR_INTERNAL_ERROR_3); /* someone is racing us! */
     141                (*pArray)[iVar] = psz;
     142            }
     143            return VINF_SUCCESS;
     144        }
     145        catch (std::bad_alloc &)
     146        {
     147            return VERR_NO_MEMORY;
     148        }
     149    }
     150
     151    /**
     152     * Applies an array of putenv style strings.
     153     *
     154     * @returns IPRT status code.
     155     * @param   rArray              The array with the putenv style strings.
     156     * @sa      RTEnvPutEnvEx
     157     */
     158    int applyPutEnvArray(const std::vector<com::Utf8Str> &rArray)
     159    {
     160        size_t cArray = rArray.size();
     161        for (size_t i = 0; i < cArray; i++)
     162        {
     163            int rc = RTEnvPutEx(m_hEnv, rArray[i].c_str());
     164            if (RT_FAILURE(rc))
     165                return rc;
     166        }
     167        return VINF_SUCCESS;
     168    }
     169
     170    /**
     171     * See RTEnvQueryUtf8Block for details.
     172     * @returns IPRT status code.
     173     * @param   ppszzBlock      Where to return the block pointer.
     174     * @param   pcbBlock        Where to optionally return the block size.
     175     * @sa      RTEnvQueryUtf8Block
     176     */
     177    int queryUtf8Block(char **ppszzBlock, size_t *pcbBlock)
     178    {
     179        return RTEnvQueryUtf8Block(m_hEnv, true /*fSorted*/, ppszzBlock, pcbBlock);
     180    }
     181
     182    /**
     183     * Frees what queryUtf8Block returned, NULL ignored.
     184     * @sa      RTEnvFreeUtf8Block
     185     */
     186    static void freeUtf8Block(char *pszzBlock)
     187    {
     188        return RTEnvFreeUtf8Block(pszzBlock);
     189    }
     190
     191    /**
     192     * Get an environment variable.
     193     *
     194     * @returns IPRT status code.
     195     * @param   rName               The variable name.
     196     * @param   pValue              Where to return the value.
     197     * @sa      RTEnvGetEx
     198     */
     199    int getVariable(const com::Utf8Str &rName, com::Utf8Str *pValue) const
     200    {
     201        size_t cchNeeded;
     202        int rc = RTEnvGetEx(m_hEnv, rName.c_str(), NULL, 0, &cchNeeded);
     203        if (   RT_SUCCESS(rc)
     204            || rc == VERR_BUFFER_OVERFLOW)
     205        {
     206            try
     207            {
     208                pValue->reserve(cchNeeded + 1);
     209                rc = RTEnvGetEx(m_hEnv, rName.c_str(), pValue->mutableRaw(), pValue->capacity(), NULL);
     210                pValue->jolt();
     211            }
     212            catch (std::bad_alloc &)
     213            {
     214                rc = VERR_NO_STR_MEMORY;
     215            }
     216        }
     217        return rc;
     218    }
     219
     220    /**
     221     * Set an environment variable.
     222     *
     223     * @returns IPRT status code.
     224     * @param   rName               The variable name.
     225     * @param   rValue              The value of the variable.
     226     * @sa      RTEnvSetEx
     227     */
     228    int setVariable(const com::Utf8Str &rName, const com::Utf8Str &rValue)
     229    {
     230        return RTEnvSetEx(m_hEnv, rName.c_str(), rValue.c_str());
     231    }
     232
     233    /**
     234     * Unset an environment variable.
     235     *
     236     * @returns IPRT status code.
     237     * @param   rName               The variable name.
     238     * @sa      RTEnvUnsetEx
     239     */
     240    int unsetVariable(const com::Utf8Str &rName)
     241    {
     242        return RTEnvUnsetEx(m_hEnv, rName.c_str());
     243    }
     244
     245#if 0
     246private:
     247    /* No copy operator. */
     248    GuestEnvironmentBase(const GuestEnvironmentBase &) { throw E_FAIL; }
     249#else
     250    /**
     251     * Copy constructor.
     252     * @throws HRESULT
     253     */
     254    GuestEnvironmentBase(const GuestEnvironmentBase &rThat, bool fChangeRecord)
     255        : m_hEnv(NIL_RTENV)
     256    {
     257        int rc = cloneCommon(rThat, fChangeRecord);
     258        if (RT_FAILURE(rc))
     259            throw (Global::vboxStatusCodeToCOM(rc));
     260    }
     261#endif
     262
     263protected:
     264    /**
     265     * Common clone/copy method with type conversion abilities.
     266     *
     267     * @returns IPRT status code.
     268     * @param   rThat           The object to clone.
     269     * @param   fChangeRecord   Whether the this instance is a change record (true)
     270     *                          or normal (false) environment.
     271     */
     272    int cloneCommon(const GuestEnvironmentBase &rThat, bool fChangeRecord)
     273    {
     274        int   rc = VINF_SUCCESS;
     275        RTENV hNewEnv = NIL_RTENV;
     276        if (rThat.m_hEnv != NIL_RTENV)
     277        {
     278            if (RTEnvIsChangeRecord(rThat.m_hEnv) == fChangeRecord)
     279                rc = RTEnvClone(&hNewEnv, rThat.m_hEnv);
     280            else
     281            {
     282                /* Need to type convert it. */
     283                if (fChangeRecord)
     284                    rc = RTEnvCreateChangeRecord(&hNewEnv);
     285                else
     286                    rc = RTEnvCreate(&hNewEnv);
     287                if (RT_SUCCESS(rc))
     288                {
     289                    rc = RTEnvApplyChanges(hNewEnv, rThat.m_hEnv);
     290                    if (RT_FAILURE(rc))
     291                        RTEnvDestroy(hNewEnv);
     292                }
     293            }
     294
     295        }
     296        if (RT_SUCCESS(rc))
     297        {
     298            RTEnvDestroy(m_hEnv);
     299            m_hEnv = hNewEnv;
     300        }
     301        return rc;
     302    }
     303
     304
     305    /** The environment change record. */
     306    RTENV       m_hEnv;
     307};
     308
     309
     310#if 0 /* Not currently used. */
     311/**
     312 * Wrapper around the RTEnv API for a normal environment.
     313 */
     314class GuestEnvironment : public GuestEnvironmentBase
     315{
     316public:
     317    /**
     318     * Default constructor.
     319     *
     320     * The user must invoke one of the init methods before using the object.
     321     */
     322    GuestEnvironment(void)
     323        : GuestEnvironmentBase()
     324    { }
     325
     326    /**
     327     * Copy operator.
     328     * @param   rThat       The object to copy.
     329     * @throws HRESULT
     330     */
     331    GuestEnvironment(const GuestEnvironment &rThat)
     332        : GuestEnvironmentBase(rThat, false /*fChangeRecord*/)
     333    { }
     334
     335    /**
     336     * Copy operator.
     337     * @param   rThat       The object to copy.
     338     * @throws HRESULT
     339     */
     340    GuestEnvironment(const GuestEnvironmentBase &rThat)
     341        : GuestEnvironmentBase(rThat, false /*fChangeRecord*/)
     342    { }
     343
     344    /**
     345     * Initialize this as a normal environment block.
     346     * @returns IPRT status code.
     347     */
     348    int initNormal(void)
     349    {
     350        AssertReturn(m_hEnv == NIL_RTENV, VERR_WRONG_ORDER);
     351        return RTEnvCreate(&m_hEnv);
     352    }
     353
     354    /**
     355     * Replaces this environemnt with that in @a rThat.
     356     *
     357     * @returns IPRT status code
     358     * @param   rThat       The environment to copy. If it's a different type
     359     *                      we'll convert the data to a normal environment block.
     360     */
     361    int copy(const GuestEnvironmentBase &rThat)
     362    {
     363        return cloneCommon(rThat, false /*fChangeRecord*/);
     364    }
     365};
     366#endif /* unused */
     367
     368
     369/**
     370 * Wrapper around the RTEnv API for a environment change record.
     371 *
     372 * This class is used as a record of changes to be applied to a different
     373 * environment block (in VBoxService before launching a new process).
     374 */
     375class GuestEnvironmentChanges : public GuestEnvironmentBase
     376{
     377public:
     378    /**
     379     * Default constructor.
     380     *
     381     * The user must invoke one of the init methods before using the object.
     382     */
     383    GuestEnvironmentChanges(void)
     384        : GuestEnvironmentBase()
     385    { }
     386
     387    /**
     388     * Copy operator.
     389     * @param   rThat       The object to copy.
     390     * @throws HRESULT
     391     */
     392    GuestEnvironmentChanges(const GuestEnvironmentChanges &rThat)
     393        : GuestEnvironmentBase(rThat, true /*fChangeRecord*/)
     394    { }
     395
     396    /**
     397     * Copy operator.
     398     * @param   rThat       The object to copy.
     399     * @throws HRESULT
     400     */
     401    GuestEnvironmentChanges(const GuestEnvironmentBase &rThat)
     402        : GuestEnvironmentBase(rThat, true /*fChangeRecord*/)
     403    { }
     404
     405    /**
     406     * Initialize this as a environment change record.
     407     * @returns IPRT status code.
     408     */
     409    int initChangeRecord(void)
     410    {
     411        AssertReturn(m_hEnv == NIL_RTENV, VERR_WRONG_ORDER);
     412        return RTEnvCreateChangeRecord(&m_hEnv);
     413    }
     414
     415    /**
     416     * Replaces this environemnt with that in @a rThat.
     417     *
     418     * @returns IPRT status code
     419     * @param   rThat       The environment to copy. If it's a different type
     420     *                      we'll convert the data to a set of changes.
     421     */
     422    int copy(const GuestEnvironmentBase &rThat)
     423    {
     424        return cloneCommon(rThat, true /*fChangeRecord*/);
     425    }
    104426};
    105427
     
    225547    /** Arguments vector (starting with argument \#0). */
    226548    ProcessArguments            mArguments;
    227     GuestEnvironment            mEnvironment;
     549    /** The process environment change record.  */
     550    GuestEnvironmentChanges     mEnvironment;
    228551    /** Process creation flags. */
    229552    uint32_t                    mFlags;
  • trunk/src/VBox/Main/include/GuestSessionImpl.h

    r55541 r55588  
    391391public:
    392392    /** @name Public internal methods.
     393     * @todo r=bird: Most of these are public for no real reason...
    393394     * @{ */
    394395    int                     i_closeSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc);
     
    415416    int                     i_fsQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData, int *pGuestRc);
    416417    const GuestCredentials &i_getCredentials(void);
    417     const GuestEnvironment &i_getEnvironment(void);
    418418    EventSource            *i_getEventSource(void) { return mEventSource; }
    419419    Utf8Str                 i_getName(void);
     
    441441    int                     i_startTaskAsync(const Utf8Str &strTaskDesc, GuestSessionTask *pTask,
    442442                                             ComObjPtr<Progress> &pProgress);
    443     int                     i_queryInfo(void);
     443    int                     i_determineProtocolVersion(void);
    444444    int                     i_waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestSessionWaitResult_T &waitResult, int *pGuestRc);
    445445    int                     i_waitForStatusChange(GuestWaitEvent *pEvent, uint32_t fWaitFlags, uint32_t uTimeoutMS,
     
    470470        /** The session's current status. */
    471471        GuestSessionStatus_T        mStatus;
    472         /** The session's environment block. Can be
    473          *  overwritten/extended by ProcessCreate(Ex). */
    474         GuestEnvironment            mEnvironment;
     472        /** The set of environment changes for the session for use when
     473         *  creating new guest processes. */
     474        GuestEnvironmentChanges     mEnvironment;
    475475        /** Directory objects bound to this session. */
    476476        SessionDirectories          mDirectories;
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