VirtualBox

Changeset 57659 in vbox


Ignore:
Timestamp:
Sep 9, 2015 11:17:17 AM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
102561
Message:

Guest Control/VBoxService: Addressed some todos.

Location:
trunk/src/VBox/Additions/common/VBoxService
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp

    r57416 r57659  
    866866     */
    867867    if (fUserSession)
    868         return VBoxServiceControlSessionForkInit(argc, argv);
     868        return VBoxServiceControlSessionSpawnInit(argc, argv);
    869869#endif
    870870
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp

    r57358 r57659  
    130130    else if (!strcmp(argv[*pi], "--control-dump-stdout"))
    131131    {
    132         g_Session.uFlags |= VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT;
     132        g_Session.fFlags |= VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT;
    133133        rc = 0; /* Flag this command as parsed. */
    134134    }
    135135    else if (!strcmp(argv[*pi], "--control-dump-stderr"))
    136136    {
    137         g_Session.uFlags |= VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR;
     137        g_Session.fFlags |= VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR;
    138138        rc = 0; /* Flag this command as parsed. */
    139139    }
     
    372372                                           ssInfo.szPassword, sizeof(ssInfo.szPassword),
    373373                                           ssInfo.szDomain,   sizeof(ssInfo.szDomain),
    374                                            &ssInfo.uFlags,    &ssInfo.uSessionID);
     374                                           &ssInfo.fFlags,    &ssInfo.uSessionID);
    375375    if (RT_SUCCESS(rc))
    376376    {
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h

    r56294 r57659  
    8282    /** Session creation flags.
    8383     *  @sa VBOXSERVICECTRLSESSIONSTARTUPFLAG_* flags. */
    84     uint32_t                        uFlags;
     84    uint32_t                        fFlags;
    8585} VBOXSERVICECTRLSESSIONSTARTUPINFO;
    8686/** Pointer to thread data. */
     
    136136typedef VBOXSERVICECTRLSESSIONTHREAD *PVBOXSERVICECTRLSESSIONTHREAD;
    137137
    138 /** Flag indicating that this session has been forked from
     138/** Flag indicating that this session has been spawned from
    139139 *  the main executable. */
    140 #define VBOXSERVICECTRLSESSION_FLAG_FORK                 RT_BIT(0)
     140#define VBOXSERVICECTRLSESSION_FLAG_SPAWN                RT_BIT(0)
    141141/** Flag indicating that this session is anonymous, that is,
    142142 *  it will run start guest processes with the same credentials
     
    177177     *  to StartupInfo stuff.
    178178     *  @sa VBOXSERVICECTRLSESSION_FLAG_* flags. */
    179     uint32_t                        uFlags;
     179    uint32_t                        fFlags;
    180180    /** How many processes do we allow keeping around at a time? */
    181181    uint32_t                        uProcsMaxKept;
     
    299299extern int                      GstCntlSessionThreadDestroyAll(PRTLISTANCHOR pList, uint32_t uFlags);
    300300extern int                      GstCntlSessionThreadTerminate(PVBOXSERVICECTRLSESSIONTHREAD pSession);
    301 extern RTEXITCODE               VBoxServiceControlSessionForkInit(int argc, char **argv);
     301extern RTEXITCODE               VBoxServiceControlSessionSpawnInit(int argc, char **argv);
    302302/* Per-session functions. */
    303303extern PVBOXSERVICECTRLPROCESS  GstCntlSessionRetainProcess(PVBOXSERVICECTRLSESSION pSession, uint32_t uPID);
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp

    r57358 r57659  
    14971497                                RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL);
    14981498    /* Did we get the same result? */
    1499     Assert(pProcess->StartupInfo.uNumArgs == uNumArgs);
     1499    Assert(pProcess->StartupInfo.uNumArgs == uNumArgs + 1 /* Take argv[0] into account */);
    15001500
    15011501    /*
     
    16151615                            {
    16161616                                AssertPtr(pProcess->pSession);
    1617                                 bool fNeedsImpersonation = !(pProcess->pSession->uFlags & VBOXSERVICECTRLSESSION_FLAG_FORK);
     1617                                bool fNeedsImpersonation = !(pProcess->pSession->fFlags & VBOXSERVICECTRLSESSION_FLAG_SPAWN);
    16181618
    16191619                                rc = gstcntlProcessCreateProcess(pProcess->StartupInfo.szCmd, papszArgs, hEnv,
     
    19721972        if (RT_SUCCESS(rc))
    19731973        {
    1974             if (   pSession->uFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT
     1974            if (   pSession->fFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT
    19751975                && (   uHandle == OUTPUT_HANDLE_ID_STDOUT
    19761976                    || uHandle == OUTPUT_HANDLE_ID_STDOUT_DEPRECATED)
     
    19841984                AssertRC(rc);
    19851985            }
    1986             else if (   pSession->uFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR
     1986            else if (   pSession->fFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR
    19871987                     && uHandle == OUTPUT_HANDLE_ID_STDERR)
    19881988            {
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp

    r57358 r57659  
    11/* $Id$ */
    22/** @file
    3  * VBoxServiceControlSession - Guest session handling. Also handles
    4  *                             the forked session processes.
     3 * VBoxServiceControlSession - Guest session handling. Also handles the spawned session processes.
    54 */
    65
     
    7574
    7675
    77 /** Generic option indices for session fork arguments. */
     76/** Generic option indices for session spawn arguments. */
    7877enum
    7978{
     
    133132
    134133    char szDir[RTPATH_MAX];
    135     uint32_t uFlags = 0;
     134    uint32_t fFlags = 0;
    136135
    137136    int rc = VbglR3GuestCtrlDirGetRemove(pHostCtx,
     
    139138                                         szDir, sizeof(szDir),
    140139                                         /* Flags of type DIRREMOVE_FLAG_. */
    141                                          &uFlags);
    142     if (RT_SUCCESS(rc))
    143     {
    144         uint32_t uFlagsRemRec = 0;
    145         bool fRecursive = false;
    146 /** @todo r=bird: Unnecessary variable fRecursive.  You can check for
    147  * DIRREMOVE_FLAG_RECURSIVE directly in the flags when deciding which API to
    148  * call. */
    149 
    150         if (!(uFlags & ~DIRREMOVE_FLAG_VALID_MASK))
    151         {
    152             if (uFlags & DIRREMOVE_FLAG_RECURSIVE)
    153             {
    154                 /* Note: DIRREMOVE_FLAG_RECURSIVE must be set explicitly.
    155                  *       Play safe here. */
    156                 fRecursive = true;
    157             }
    158 /** @todo r=bird: Understand how APIs you use work (read docs, check constant,
    159  * check code). If you check the actual values of RTDIRRMREC_F_CONTENT_AND_DIR
    160  * and RTDIRRMREC_F_CONTENT_ONLY, you'd notice that the first one is 0 and the
    161  * second is 1.  This code is a little confused about how it all works, though
    162  * it ends up doing the right thing as if by accident almost. */
    163             if (uFlags & DIRREMOVE_FLAG_CONTENT_AND_DIR)
    164             {
    165                 /* Setting direct value is intentional. */
    166                 uFlagsRemRec = RTDIRRMREC_F_CONTENT_AND_DIR;
    167             }
    168 
    169             if (uFlags & DIRREMOVE_FLAG_CONTENT_ONLY)
    170             {
    171                 /* Setting direct value is intentional. */
    172                 uFlagsRemRec |= RTDIRRMREC_F_CONTENT_ONLY;
    173             }
     140                                         &fFlags);
     141    if (RT_SUCCESS(rc))
     142    {
     143        AssertReturn(!(fFlags & ~DIRREMOVE_FLAG_VALID_MASK), VERR_INVALID_PARAMETER);
     144        if (!(fFlags & ~DIRREMOVE_FLAG_VALID_MASK))
     145        {
     146            if (fFlags & DIRREMOVE_FLAG_RECURSIVE)
     147            {
     148                uint32_t fFlagsRemRec = RTDIRRMREC_F_CONTENT_AND_DIR; /* Set default. */
     149                if (fFlags & DIRREMOVE_FLAG_CONTENT_ONLY)
     150                    fFlagsRemRec |= RTDIRRMREC_F_CONTENT_ONLY;
     151
     152                rc = RTDirRemoveRecursive(szDir, fFlagsRemRec);
     153            }
     154            else /* Only delete directory if not empty. */
     155                rc = RTDirRemove(szDir);
    174156        }
    175157        else
    176158            rc = VERR_NOT_SUPPORTED;
    177159
    178         VBoxServiceVerbose(4, "[Dir %s]: Removing with uFlags=0x%x, fRecursive=%RTbool\n",
    179                            szDir, uFlags, fRecursive);
    180 
    181 /** @todo r=bird: Convoluted code flow. It would be shorter and easier to
    182  * read if you moved this code up and into the flags-are-valid if body. */
    183         if (RT_SUCCESS(rc))
    184         {
    185             /** @todo Add own recursive function (or a new IPRT function w/ callback?) to
    186              *        provide guest-to-host progress reporting. */
    187             if (fRecursive)
    188                 rc = RTDirRemoveRecursive(szDir, uFlagsRemRec);
    189             else
    190                 rc = RTDirRemove(szDir);
    191         }
     160        VBoxServiceVerbose(4, "[Dir %s]: Removing with fFlags=0x%x, rc=%Rrc\n", szDir, fFlags, rc);
    192161
    193162        /* Report back in any case. */
    194163        int rc2 = VbglR3GuestCtrlMsgReply(pHostCtx, rc);
    195164        if (RT_FAILURE(rc2))
    196             VBoxServiceError("[Dir %s]: Failed to report removing status, rc=%Rrc\n",
    197                              szDir, rc2);
     165            VBoxServiceError("[Dir %s]: Failed to report removing status, rc=%Rrc\n", szDir, rc2);
    198166        if (RT_SUCCESS(rc))
    199167            rc = rc2;
     
    201169
    202170#ifdef DEBUG
    203     VBoxServiceVerbose(4, "Removing directory \"%s\" returned rc=%Rrc\n",
    204                        szDir, rc);
     171    VBoxServiceVerbose(4, "Removing directory \"%s\" returned rc=%Rrc\n", szDir, rc);
    205172#endif
    206173    return rc;
     
    246213                rc = VERR_INVALID_PARAMETER;
    247214
    248             if (   RT_SUCCESS(rc)
    249                 && !RTStrPrintf(pFile->szName, sizeof(pFile->szName), "%s", szFile))
    250                 rc = VERR_NO_MEMORY;
    251 
    252215            if (RT_SUCCESS(rc))
    253216            {
     217                RTStrPrintf(pFile->szName, sizeof(pFile->szName), "%s", szFile);
     218
    254219                uint64_t fFlags;
    255220                rc = RTFileModeToFlagsEx(szAccess, szDisposition,
    256221                                         NULL /* pszSharing, not used yet */, &fFlags);
    257                 VBoxServiceVerbose(4, "[File %s]: Opening flags=0x%x, rc=%Rrc\n",
    258                                    pFile->szName, fFlags, rc);
     222                VBoxServiceVerbose(4, "[File %s]: Opening with fFlags=0x%x, rc=%Rrc\n", pFile->szName, fFlags, rc);
     223
    259224                if (RT_SUCCESS(rc))
    260225                    rc = RTFileOpen(&pFile->hFile, pFile->szName, fFlags);
     
    270235                }
    271236                else if (RT_FAILURE(rc))
    272                     VBoxServiceError("[File %s]: Opening failed; rc=%Rrc\n",
    273                                      pFile->szName, rc);
     237                    VBoxServiceError("[File %s]: Opening failed with rc=%Rrc\n", pFile->szName, rc);
    274238            }
    275239
     
    481445
    482446    int rc = VbglR3GuestCtrlFileGetWrite(pHostCtx, &uHandle,
    483                                          pvScratchBuf, cbScratchBuf,
    484                                          &cbToWrite);
     447                                         pvScratchBuf, (uint32_t)cbScratchBuf, &cbToWrite);
    485448    if (RT_SUCCESS(rc))
    486449    {
     
    529492
    530493    int rc = VbglR3GuestCtrlFileGetWriteAt(pHostCtx, &uHandle,
    531                                            pvScratchBuf, cbScratchBuf,
     494                                           pvScratchBuf, (uint32_t)cbScratchBuf,
    532495                                           &cbToWrite, (uint64_t *)&iOffset);
    533496    if (RT_SUCCESS(rc))
     
    867830     */
    868831    int rc = VbglR3GuestCtrlProcGetInput(pHostCtx, &uPID, &uFlags,
    869                                          pvScratchBuf, cbScratchBuf, &cbSize);
     832                                         pvScratchBuf, (uint32_t)cbScratchBuf, &cbSize);
    870833    if (RT_FAILURE(rc))
    871834    {
     
    10371000    /**
    10381001     * Only anonymous sessions (that is, sessions which run with local
    1039      * service privileges) or forked session processes can do certain
     1002     * service privileges) or spawned session processes can do certain
    10401003     * operations.
    10411004     */
    1042     bool fImpersonated = (   pSession->uFlags & VBOXSERVICECTRLSESSION_FLAG_FORK
    1043                           || pSession->uFlags & VBOXSERVICECTRLSESSION_FLAG_ANONYMOUS);
     1005    bool fImpersonated = (   pSession->fFlags & VBOXSERVICECTRLSESSION_FLAG_SPAWN
     1006                          || pSession->fFlags & VBOXSERVICECTRLSESSION_FLAG_ANONYMOUS);
    10441007
    10451008    switch (uMsg)
    10461009    {
    10471010        case HOST_SESSION_CLOSE:
    1048             /* Shutdown (this fork). */
     1011            /* Shutdown (this spawn). */
    10491012            rc = GstCntlSessionClose(pSession);
    10501013            *pfShutdown = true; /* Shutdown in any case. */
     
    11521115
    11531116/**
    1154  * Thread main routine for a forked guest session process.
    1155  * This thread runs in the main executable to control the forked
    1156  * session process.
     1117 * Thread main routine for a spawned guest session process.
     1118 * This thread runs in the main executable to control the spawned session process.
    11571119 *
    11581120 * @return IPRT status code.
     
    13581320
    13591321
    1360 RTEXITCODE gstcntlSessionForkWorker(PVBOXSERVICECTRLSESSION pSession)
     1322RTEXITCODE gstcntlSessionSpawnWorker(PVBOXSERVICECTRLSESSION pSession)
    13611323{
    13621324    AssertPtrReturn(pSession, RTEXITCODE_FAILURE);
     
    16501612
    16511613
    1652 int GstCntlSessionInit(PVBOXSERVICECTRLSESSION pSession, uint32_t uFlags)
     1614int GstCntlSessionInit(PVBOXSERVICECTRLSESSION pSession, uint32_t fFlags)
    16531615{
    16541616    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     
    16571619    RTListInit(&pSession->lstFiles);
    16581620
    1659     pSession->uFlags = uFlags;
     1621    pSession->fFlags = fFlags;
    16601622
    16611623    /* Init critical section for protecting the thread lists. */
     
    18451807            VBoxServiceVerbose(3, "New anonymous guest session ID=%RU32 created, uFlags=%x, using protocol %RU32\n",
    18461808                               pSessionStartupInfo->uSessionID,
    1847                                pSessionStartupInfo->uFlags,
     1809                               pSessionStartupInfo->fFlags,
    18481810                               pSessionStartupInfo->uProtocol);
    18491811        }
    18501812        else
    18511813        {
    1852             VBoxServiceVerbose(3, "Forking new guest session ID=%RU32, szUser=%s, szPassword=%s, szDomain=%s, uFlags=%x, using protocol %RU32\n",
     1814            VBoxServiceVerbose(3, "Spawning new guest session ID=%RU32, szUser=%s, szPassword=%s, szDomain=%s, uFlags=%x, using protocol %RU32\n",
    18531815                               pSessionStartupInfo->uSessionID,
    18541816                               pSessionStartupInfo->szUser,
     
    18591821#endif
    18601822                               pSessionStartupInfo->szDomain,
    1861                                pSessionStartupInfo->uFlags,
     1823                               pSessionStartupInfo->fFlags,
    18621824                               pSessionStartupInfo->uProtocol);
    18631825        }
     
    18731835        if (pszExeName)
    18741836        {
    1875 /** @todo r=bird: A while back we had this variant in the guest props code:
    1876  *  @code
    1877  *      int rc = RTStrPrintf(....);
    1878  *      if (RT_SUCCESS(rc))
    1879  *  @endcode
    1880  *
    1881  *  Here we've got a new variant:
    1882  *  @code
    1883  *      if (!RTStrPrintf(szBuf, sizeof(szBuf),...))
    1884  *         return VERR_BUFFER_OVERFLOW;
    1885  *  @endcode
    1886  *  ... which is just as pointless.
    1887  *
    1888  *  According to the doxygen docs in iprt/string.h, RTStrPrintf returns "The
    1889  *  length of the returned string (in pszBuffer) excluding the terminator".
    1890  *
    1891  *  Which admittedly makes it a real bitch to check for buffer overflows, but is
    1892  *  a great help preventing memory corruption by careless use of the returned
    1893  *  value if it was outside the buffer range (negative error codes or required
    1894  *  buffer size).  We should probably add a new string formatter which API which
    1895  *  returns VERR_BUFFER_OVERFLOW on overflow and optionally a required buffer
    1896  *  size that you can use here...
    1897  *
    1898  *  However in most cases you don't need to because you make things way to
    1899  *  complicated (see the log file name mangling for instance).
    1900  *
    1901  *  Here, you just need to format two or three (#ifdef DEBUG) 32-bit numbers
    1902  *  which are no brainers, while the szUser can be used as is.  The trick is to
    1903  *  pass the and option and the option value separately.
    1904  */
     1837            char szParmSessionID[32];
     1838            RTStrPrintf(szParmSessionID, sizeof(szParmSessionID), "--session-id=%RU32", pSessionThread->StartupInfo.uSessionID);
     1839
     1840            char szParmSessionProto[32];
     1841            RTStrPrintf(szParmSessionProto, sizeof(szParmSessionProto), "--session-proto=%RU32",
     1842                        pSessionThread->StartupInfo.uProtocol);
     1843#ifdef DEBUG
     1844            char szParmThreadId[32];
     1845            RTStrPrintf(szParmThreadId, sizeof(szParmThreadId), "--thread-id=%RU32", s_uCtrlSessionThread);
     1846#endif
    19051847            char szParmUserName[GUESTPROCESS_MAX_USER_LEN + 32];
    1906             if (!fAnonymous)
    1907             {
    1908                 if (!RTStrPrintf(szParmUserName, sizeof(szParmUserName), "--user=%s", pSessionThread->StartupInfo.szUser))
    1909                     rc = VERR_BUFFER_OVERFLOW;
    1910             }
    1911             char szParmSessionID[32];
    1912             if (RT_SUCCESS(rc) && !RTStrPrintf(szParmSessionID, sizeof(szParmSessionID), "--session-id=%RU32",
    1913                                                pSessionThread->StartupInfo.uSessionID))
    1914             {
    1915                 rc = VERR_BUFFER_OVERFLOW;
    1916             }
    1917             char szParmSessionProto[32];
    1918             if (RT_SUCCESS(rc) && !RTStrPrintf(szParmSessionProto, sizeof(szParmSessionProto), "--session-proto=%RU32",
    1919                                                pSessionThread->StartupInfo.uProtocol))
    1920             {
    1921                 rc = VERR_BUFFER_OVERFLOW;
    1922             }
    1923 #ifdef DEBUG
    1924             char szParmThreadId[32];
    1925             if (RT_SUCCESS(rc) && !RTStrPrintf(szParmThreadId, sizeof(szParmThreadId), "--thread-id=%RU32",
    1926                                                s_uCtrlSessionThread))
    1927             {
    1928                 rc = VERR_BUFFER_OVERFLOW;
    1929             }
    1930 #endif
    1931             if (RT_SUCCESS(rc))
    1932             {
    1933                 int iOptIdx = 0; /* Current index in argument vector. */
    1934 
    1935                 char const *papszArgs[16];
    1936                 papszArgs[iOptIdx++] = pszExeName;
    1937                 papszArgs[iOptIdx++] = "guestsession";
    1938                 papszArgs[iOptIdx++] = szParmSessionID;
    1939                 papszArgs[iOptIdx++] = szParmSessionProto;
    1940 #ifdef DEBUG
    1941                 papszArgs[iOptIdx++] = szParmThreadId;
    1942 #endif
    1943                 if (!fAnonymous)
    1944                     papszArgs[iOptIdx++] = szParmUserName;
    1945 
    1946                 /* Add same verbose flags as parent process. */
    1947                 int rc2 = VINF_SUCCESS;
    1948                 char szParmVerbose[32] = { 0 };
    1949                 for (int i = 0; i < g_cVerbosity && RT_SUCCESS(rc2); i++)
     1848
     1849            int iArgIdx = 0; /* Current index in argument vector. */
     1850            char const *papszArgs[16];
     1851
     1852            papszArgs[iArgIdx++] = pszExeName;
     1853            papszArgs[iArgIdx++] = "guestsession";
     1854            papszArgs[iArgIdx++] = szParmSessionID;
     1855            papszArgs[iArgIdx++] = szParmSessionProto;
     1856#ifdef DEBUG
     1857            papszArgs[iArgIdx++] = szParmThreadId;
     1858#endif
     1859            if (!fAnonymous) /* Do we need to pass a user name? */
     1860            {
     1861                RTStrPrintf(szParmUserName, sizeof(szParmUserName), "--user=%s", pSessionThread->StartupInfo.szUser);
     1862                papszArgs[iArgIdx++] = szParmUserName;
     1863            }
     1864
     1865            /* Add same verbose flags as parent process. */
     1866            int rc2 = VINF_SUCCESS;
     1867            char szParmVerbose[32] = { 0 };
     1868            for (int i = 0; i < g_cVerbosity && RT_SUCCESS(rc2); i++)
     1869            {
     1870                if (i == 0)
     1871                    rc2 = RTStrCat(szParmVerbose, sizeof(szParmVerbose), "-");
     1872                if (RT_FAILURE(rc2))
     1873                    break;
     1874                rc2 = RTStrCat(szParmVerbose, sizeof(szParmVerbose), "v");
     1875            }
     1876            if (RT_SUCCESS(rc2))
     1877                papszArgs[iArgIdx++] = szParmVerbose;
     1878
     1879            /* Add log file handling. Each session will have an own
     1880             * log file, naming based on the parent log file. */
     1881            char szParmLogFile[RTPATH_MAX];
     1882            if (   RT_SUCCESS(rc2)
     1883                && strlen(g_szLogFile))
     1884            {
     1885                char *pszLogFile = RTStrDup(g_szLogFile);
     1886                if (pszLogFile)
    19501887                {
    1951                     if (i == 0)
    1952                         rc2 = RTStrCat(szParmVerbose, sizeof(szParmVerbose), "-");
     1888                    char *pszLogSuff = NULL;
     1889                    if (RTPathHasSuffix(pszLogFile))
     1890                        pszLogSuff = RTStrDup(RTPathSuffix(pszLogFile));
     1891                    RTPathStripSuffix(pszLogFile);
     1892                    char *pszLogNewSuffix;
     1893#ifndef DEBUG
     1894                    if (RTStrAPrintf(&pszLogNewSuffix, "-%RU32-%s",
     1895                                     pSessionStartupInfo->uSessionID,
     1896                                     pSessionStartupInfo->szUser) < 0)
     1897                    {
     1898                        rc2 = VERR_NO_MEMORY;
     1899                    }
     1900#else /* DEBUG */
     1901                    /* Include the session thread ID in the log file name. */
     1902                    if (RTStrAPrintf(&pszLogNewSuffix, "-%RU32-%RU32-%s",
     1903                                     pSessionStartupInfo->uSessionID,
     1904                                     s_uCtrlSessionThread,
     1905                                     pSessionStartupInfo->szUser) < 0)
     1906                    {
     1907                        rc2 = VERR_NO_MEMORY;
     1908                    }
     1909#endif /* DEBUG */
     1910                    else
     1911                    {
     1912                        rc2 = RTStrAAppend(&pszLogFile, pszLogNewSuffix);
     1913                        if (RT_SUCCESS(rc2) && pszLogSuff)
     1914                            rc2 = RTStrAAppend(&pszLogFile, pszLogSuff);
     1915                        if (RT_SUCCESS(rc2))
     1916                            RTStrPrintf(szParmLogFile, sizeof(szParmLogFile), "--logfile=%s", pszLogFile);
     1917
     1918                        RTStrFree(pszLogNewSuffix);
     1919                    }
    19531920                    if (RT_FAILURE(rc2))
    1954                         break;
    1955                     rc2 = RTStrCat(szParmVerbose, sizeof(szParmVerbose), "v");
     1921                        VBoxServiceError("Error building session logfile string for session %RU32 (user %s), rc=%Rrc\n",
     1922                                         pSessionStartupInfo->uSessionID, pSessionStartupInfo->szUser, rc2);
     1923                    if (pszLogSuff)
     1924                        RTStrFree(pszLogSuff);
     1925                    RTStrFree(pszLogFile);
    19561926                }
    19571927                if (RT_SUCCESS(rc2))
    1958                     papszArgs[iOptIdx++] = szParmVerbose;
    1959 
    1960                 /* Add log file handling. Each session will have an own
    1961                  * log file, naming based on the parent log file. */
    1962                 char szParmLogFile[RTPATH_MAX];
    1963                 if (   RT_SUCCESS(rc2)
    1964                     && strlen(g_szLogFile))
    1965                 {
    1966                     char *pszLogFile = RTStrDup(g_szLogFile);
    1967                     if (pszLogFile)
    1968                     {
    1969                         char *pszLogSuff = NULL;
    1970                         if (RTPathHasSuffix(pszLogFile))
    1971                             pszLogSuff = RTStrDup(RTPathSuffix(pszLogFile));
    1972                         RTPathStripSuffix(pszLogFile);
    1973                         char *pszLogNewSuffix;
    1974 #ifndef DEBUG
    1975                         if (RTStrAPrintf(&pszLogNewSuffix, "-%RU32-%s",
    1976                                          pSessionStartupInfo->uSessionID,
    1977                                          pSessionStartupInfo->szUser) < 0)
    1978                         {
    1979                             rc2 = VERR_NO_MEMORY;
    1980                         }
    1981 #else /* DEBUG */
    1982                         /* Include the session thread ID in the log file name. */
    1983                         if (RTStrAPrintf(&pszLogNewSuffix, "-%RU32-%RU32-%s",
    1984                                          pSessionStartupInfo->uSessionID,
    1985                                          s_uCtrlSessionThread,
    1986                                          pSessionStartupInfo->szUser) < 0)
    1987                         {
    1988                             rc2 = VERR_NO_MEMORY;
    1989                         }
    1990 #endif /* DEBUG */
    1991                         else
    1992                         {
    1993                             rc2 = RTStrAAppend(&pszLogFile, pszLogNewSuffix);
    1994                             if (RT_SUCCESS(rc2) && pszLogSuff)
    1995                                 rc2 = RTStrAAppend(&pszLogFile, pszLogSuff);
    1996                             if (RT_SUCCESS(rc2))
    1997                             {
    1998                                 if (!RTStrPrintf(szParmLogFile, sizeof(szParmLogFile),
    1999                                                  "--logfile=%s", pszLogFile))
    2000                                 {
    2001                                     rc2 = VERR_BUFFER_OVERFLOW;
    2002                                 }
    2003                             }
    2004                             RTStrFree(pszLogNewSuffix);
    2005                         }
    2006                         if (RT_FAILURE(rc2))
    2007                             VBoxServiceError("Error building session logfile string for session %RU32 (user %s), rc=%Rrc\n",
    2008                                              pSessionStartupInfo->uSessionID, pSessionStartupInfo->szUser, rc2);
    2009                         if (pszLogSuff)
    2010                             RTStrFree(pszLogSuff);
    2011                         RTStrFree(pszLogFile);
    2012                     }
    2013                     if (RT_SUCCESS(rc2))
    2014                         papszArgs[iOptIdx++] = szParmLogFile;
    2015 
    2016                     rc = rc2;
    2017                 }
    2018                 else if (RT_FAILURE(rc2))
    2019                     rc = rc2;
    2020 #ifdef DEBUG
    2021                 VBoxServiceVerbose(4, "Argv building rc=%Rrc, session flags=%x\n",
    2022                                    rc, g_Session.uFlags);
    2023                 char szParmDumpStdOut[32];
    2024                 if (   RT_SUCCESS(rc)
    2025                     && g_Session.uFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT)
    2026                 {
    2027 /** @todo r=bird: This amazing code can be replaced by
    2028  *  @code
    2029  *    papszArgs[iOptIdx++] = "--dump-stdout";
    2030  *  @endcode
    2031  *  which doesn't even need braces.
    2032  */
    2033                     if (!RTStrPrintf(szParmDumpStdOut, sizeof(szParmDumpStdOut), "--dump-stdout"))
    2034                         rc = VERR_BUFFER_OVERFLOW;
    2035                     if (RT_SUCCESS(rc))
    2036                         papszArgs[iOptIdx++] = szParmDumpStdOut;
    2037                 }
    2038                 char szParmDumpStdErr[32];
    2039                 if (   RT_SUCCESS(rc)
    2040                     && g_Session.uFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR)
    2041                 {
    2042                     if (!RTStrPrintf(szParmDumpStdErr, sizeof(szParmDumpStdErr), "--dump-stderr"))
    2043                         rc = VERR_BUFFER_OVERFLOW;
    2044                     if (RT_SUCCESS(rc))
    2045                         papszArgs[iOptIdx++] = szParmDumpStdErr;
    2046                 }
    2047 #endif
    2048                 papszArgs[iOptIdx++] = NULL;
    2049 
    2050                 if (g_cVerbosity > 3)
    2051                 {
    2052                     VBoxServiceVerbose(4, "Forking parameters:\n");
    2053 
    2054                     iOptIdx = 0;
    2055                     while (papszArgs[iOptIdx])
    2056                         VBoxServiceVerbose(4, "\t%s\n", papszArgs[iOptIdx++]);
    2057                 }
    2058 
    2059                 uint32_t uProcFlags = RTPROC_FLAGS_SERVICE
    2060                                     | RTPROC_FLAGS_HIDDEN; /** @todo More flags from startup info? */
    2061 
    2062                 /*
    2063                  * Create the session process' environment block.
    2064                  */
    2065                 RTENV hEnv = NIL_RTENV;
     1928                    papszArgs[iArgIdx++] = szParmLogFile;
     1929
     1930                rc = rc2;
     1931            }
     1932            else if (RT_FAILURE(rc2))
     1933                rc = rc2;
     1934#ifdef DEBUG
     1935            VBoxServiceVerbose(4, "Argv building rc=%Rrc, session flags=%x\n", rc, g_Session.fFlags);
     1936            if (RT_SUCCESS(rc))
     1937            {
     1938                if (g_Session.fFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT)
     1939                    papszArgs[iArgIdx++] = "--dump-stdout";
     1940                if (g_Session.fFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR)
     1941                    papszArgs[iArgIdx++] = "--dump-stderr";
     1942            }
     1943#endif
     1944            papszArgs[iArgIdx++] = NULL;
     1945
     1946            if (g_cVerbosity > 3)
     1947            {
     1948                VBoxServiceVerbose(4, "Spawning parameters:\n");
     1949
     1950                iArgIdx = 0;
     1951                while (papszArgs[iArgIdx])
     1952                    VBoxServiceVerbose(4, "\t%s\n", papszArgs[iArgIdx++]);
     1953            }
     1954
     1955            uint32_t uProcFlags = RTPROC_FLAGS_SERVICE
     1956                                | RTPROC_FLAGS_HIDDEN; /** @todo More flags from startup info? */
     1957
     1958            /*
     1959             * Create the session process' environment block.
     1960             */
     1961            RTENV hEnv = NIL_RTENV;
     1962            if (RT_SUCCESS(rc))
     1963            {
     1964                /** @todo At the moment a session process does not have the ability to use the
     1965                 *        per-session environment variables itself, only the session's guest
     1966                 *        processes do so. Implement that later, also needs tweaking of
     1967                 *        VbglR3GuestCtrlSessionGetOpen(). */
     1968                rc = RTEnvClone(&hEnv, RTENV_DEFAULT);
     1969            }
     1970
     1971#if 0 /* Pipe handling not needed (yet). */
     1972            /* Setup pipes. */
     1973            rc = GstcntlProcessSetupPipe("|", 0 /*STDIN_FILENO*/,
     1974                                         &pSession->StdIn.hChild, &pSession->StdIn.phChild, &pSession->hStdInW);
     1975            if (RT_SUCCESS(rc))
     1976            {
     1977                rc = GstcntlProcessSetupPipe("|", 1 /*STDOUT_FILENO*/,
     1978                                             &pSession->StdOut.hChild, &pSession->StdOut.phChild, &pSession->hStdOutR);
    20661979                if (RT_SUCCESS(rc))
    20671980                {
    2068                     /** @todo At the moment a session process does not have the ability to use the
    2069                      *        per-session environment variables itself, only the session's guest
    2070                      *        processes do so. Implement that later, also needs tweaking of
    2071                      *        VbglR3GuestCtrlSessionGetOpen(). */
    2072                     rc = RTEnvClone(&hEnv, RTENV_DEFAULT);
     1981                    rc = GstcntlProcessSetupPipe("|", 2 /*STDERR_FILENO*/,
     1982                                                 &pSession->StdErr.hChild, &pSession->StdErr.phChild, &pSession->hStdErrR);
     1983                    if (RT_SUCCESS(rc))
     1984                    {
     1985                        rc = RTPollSetCreate(&pSession->hPollSet);
     1986                        if (RT_SUCCESS(rc))
     1987                            rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdInW, RTPOLL_EVT_ERROR,
     1988                                                  VBOXSERVICECTRLPIPEID_STDIN);
     1989                        if (RT_SUCCESS(rc))
     1990                            rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdOutR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR,
     1991                                                  VBOXSERVICECTRLPIPEID_STDOUT);
     1992                        if (RT_SUCCESS(rc))
     1993                            rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdErrR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR,
     1994                                                  VBOXSERVICECTRLPIPEID_STDERR);
     1995                    }
     1996
     1997                    if (RT_SUCCESS(rc))
     1998                        rc = RTProcCreateEx(pszExeName, papszArgs, hEnv, uProcFlags,
     1999                                            pSession->StdIn.phChild, pSession->StdOut.phChild, pSession->StdErr.phChild,
     2000                                            !fAnonymous ? pSession->StartupInfo.szUser : NULL,
     2001                                            !fAnonymous ? pSession->StartupInfo.szPassword : NULL,
     2002                                            &pSession->hProcess);
     2003
     2004                    if (RT_SUCCESS(rc))
     2005                    {
     2006                        /*
     2007                         * Close the child ends of any pipes and redirected files.
     2008                         */
     2009                        int rc2 = RTHandleClose(pSession->StdIn.phChild); AssertRC(rc2);
     2010                        pSession->StdIn.phChild     = NULL;
     2011                        rc2 = RTHandleClose(pSession->StdOut.phChild);    AssertRC(rc2);
     2012                        pSession->StdOut.phChild    = NULL;
     2013                        rc2 = RTHandleClose(pSession->StdErr.phChild);    AssertRC(rc2);
     2014                        pSession->StdErr.phChild    = NULL;
     2015                    }
    20732016                }
    2074 
    2075 #if 0 /* Pipe handling not needed (yet). */
    2076                 /* Setup pipes. */
    2077                 rc = GstcntlProcessSetupPipe("|", 0 /*STDIN_FILENO*/,
    2078                                              &pSession->StdIn.hChild, &pSession->StdIn.phChild, &pSession->hStdInW);
     2017            }
     2018#else
     2019            RTHANDLE hStdIn;
     2020            if (RT_SUCCESS(rc))
     2021                rc = RTFileOpenBitBucket(&hStdIn.u.hFile, RTFILE_O_READ);
     2022            if (RT_SUCCESS(rc))
     2023            {
     2024                hStdIn.enmType = RTHANDLETYPE_FILE;
     2025
     2026                RTHANDLE hStdOutAndErr;
     2027                rc = RTFileOpenBitBucket(&hStdOutAndErr.u.hFile, RTFILE_O_WRITE);
    20792028                if (RT_SUCCESS(rc))
    20802029                {
    2081                     rc = GstcntlProcessSetupPipe("|", 1 /*STDOUT_FILENO*/,
    2082                                                  &pSession->StdOut.hChild, &pSession->StdOut.phChild, &pSession->hStdOutR);
    2083                     if (RT_SUCCESS(rc))
    2084                     {
    2085                         rc = GstcntlProcessSetupPipe("|", 2 /*STDERR_FILENO*/,
    2086                                                      &pSession->StdErr.hChild, &pSession->StdErr.phChild, &pSession->hStdErrR);
    2087                         if (RT_SUCCESS(rc))
    2088                         {
    2089                             rc = RTPollSetCreate(&pSession->hPollSet);
    2090                             if (RT_SUCCESS(rc))
    2091                                 rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdInW, RTPOLL_EVT_ERROR,
    2092                                                       VBOXSERVICECTRLPIPEID_STDIN);
    2093                             if (RT_SUCCESS(rc))
    2094                                 rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdOutR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR,
    2095                                                       VBOXSERVICECTRLPIPEID_STDOUT);
    2096                             if (RT_SUCCESS(rc))
    2097                                 rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdErrR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR,
    2098                                                       VBOXSERVICECTRLPIPEID_STDERR);
    2099                         }
    2100 
    2101                         if (RT_SUCCESS(rc))
    2102                             rc = RTProcCreateEx(pszExeName, papszArgs, hEnv, uProcFlags,
    2103                                                 pSession->StdIn.phChild, pSession->StdOut.phChild, pSession->StdErr.phChild,
    2104                                                 !fAnonymous ? pSession->StartupInfo.szUser : NULL,
    2105                                                 !fAnonymous ? pSession->StartupInfo.szPassword : NULL,
    2106                                                 &pSession->hProcess);
    2107 
    2108                         if (RT_SUCCESS(rc))
    2109                         {
    2110                             /*
    2111                              * Close the child ends of any pipes and redirected files.
    2112                              */
    2113                             int rc2 = RTHandleClose(pSession->StdIn.phChild); AssertRC(rc2);
    2114                             pSession->StdIn.phChild     = NULL;
    2115                             rc2 = RTHandleClose(pSession->StdOut.phChild);    AssertRC(rc2);
    2116                             pSession->StdOut.phChild    = NULL;
    2117                             rc2 = RTHandleClose(pSession->StdErr.phChild);    AssertRC(rc2);
    2118                             pSession->StdErr.phChild    = NULL;
    2119                         }
    2120                     }
     2030                    hStdOutAndErr.enmType = RTHANDLETYPE_FILE;
     2031
     2032                        rc = RTProcCreateEx(pszExeName, papszArgs, hEnv, uProcFlags,
     2033                                        &hStdIn, &hStdOutAndErr, &hStdOutAndErr,
     2034                                        !fAnonymous ? pSessionThread->StartupInfo.szUser : NULL,
     2035                                        !fAnonymous ? pSessionThread->StartupInfo.szPassword : NULL,
     2036                                        &pSessionThread->hProcess);
     2037
     2038                    RTFileClose(hStdOutAndErr.u.hFile);
    21212039                }
    2122 #else
    2123                 RTHANDLE hStdIn;
    2124                 if (RT_SUCCESS(rc))
    2125                     rc = RTFileOpenBitBucket(&hStdIn.u.hFile, RTFILE_O_READ);
    2126                 if (RT_SUCCESS(rc))
    2127                 {
    2128                     hStdIn.enmType = RTHANDLETYPE_FILE;
    2129 
    2130                     RTHANDLE hStdOutAndErr;
    2131                     rc = RTFileOpenBitBucket(&hStdOutAndErr.u.hFile, RTFILE_O_WRITE);
    2132                     if (RT_SUCCESS(rc))
    2133                     {
    2134                         hStdOutAndErr.enmType = RTHANDLETYPE_FILE;
    2135 
    2136                         rc = RTProcCreateEx(pszExeName, papszArgs, hEnv, uProcFlags,
    2137                                             &hStdIn, &hStdOutAndErr, &hStdOutAndErr,
    2138                                             !fAnonymous ? pSessionThread->StartupInfo.szUser : NULL,
    2139                                             !fAnonymous ? pSessionThread->StartupInfo.szPassword : NULL,
    2140                                             &pSessionThread->hProcess);
    2141 
    2142                         RTFileClose(hStdOutAndErr.u.hFile);
    2143                     }
    2144 
    2145                     RTFileClose(hStdIn.u.hFile);
    2146                 }
    2147 #endif
    2148                 if (hEnv != NIL_RTENV)
    2149                     RTEnvDestroy(hEnv);
    2150             }
     2040
     2041                RTFileClose(hStdIn.u.hFile);
     2042            }
     2043#endif
     2044            if (hEnv != NIL_RTENV)
     2045                RTEnvDestroy(hEnv);
    21512046        }
    21522047        else
     
    21982093        rc = VERR_NO_MEMORY;
    21992094
    2200     VBoxServiceVerbose(3, "Forking session thread returned returned rc=%Rrc\n", rc);
     2095    VBoxServiceVerbose(3, "Spawning session thread returned returned rc=%Rrc\n", rc);
    22012096    return rc;
    22022097}
     
    22272122
    22282123    /*
    2229      * The fork should have received the same closing request,
     2124     * The spawned session process should have received the same closing request,
    22302125     * so just wait for the process to close.
    22312126     */
     
    22962191            VBoxServiceError("Cancelling pending waits failed; rc=%Rrc\n", rc);*/
    22972192
    2298 /** @todo r=bird: Why don't you use RTListForEachSafe here?? */
    2299     PVBOXSERVICECTRLSESSIONTHREAD pSessionThread = RTListGetFirst(pList, VBOXSERVICECTRLSESSIONTHREAD, Node);
    2300     while (pSessionThread)
    2301     {
    2302         PVBOXSERVICECTRLSESSIONTHREAD pSessionThreadNext =
    2303             RTListGetNext(pList, pSessionThread, VBOXSERVICECTRLSESSIONTHREAD, Node);
    2304         bool fLast = RTListNodeIsLast(pList, &pSessionThread->Node); /** @todo r=bird: This isn't necessary, pSessionThreadNext will be NULL! */
    2305 
    2306         int rc2 = GstCntlSessionThreadDestroy(pSessionThread, uFlags);
     2193    PVBOXSERVICECTRLSESSIONTHREAD pSessIt;
     2194    PVBOXSERVICECTRLSESSIONTHREAD pSessItNext;
     2195    RTListForEachSafe(pList, pSessIt, pSessItNext, VBOXSERVICECTRLSESSIONTHREAD, Node)
     2196    {
     2197        int rc2 = GstCntlSessionThreadDestroy(pSessIt, uFlags);
    23072198        if (RT_FAILURE(rc2))
    23082199        {
    2309             VBoxServiceError("Closing session thread failed with rc=%Rrc\n", rc2);
     2200            VBoxServiceError("Closing session thread '%s' failed with rc=%Rrc\n", RTThreadGetName(pSessIt->Thread), rc2);
    23102201            if (RT_SUCCESS(rc))
    23112202                rc = rc2;
    23122203            /* Keep going. */
    23132204        }
    2314 
    2315         if (fLast)
    2316             break;
    2317 
    2318         pSessionThread = pSessionThreadNext;
    2319     }
    2320 
    2321     return rc;
    2322 }
    2323 
    2324 /** @todo r=bird: This isn't a fork in the tranditional unix sense, so please
    2325  * don't confuse any unix guys by using the term.
    2326  * GstCntlSessionChildMain would be a good name.  */
    2327 RTEXITCODE VBoxServiceControlSessionForkInit(int argc, char **argv)
     2205    }
     2206
     2207    VBoxServiceVerbose(4, "Destroying guest session threads ended with %Rrc\n", rc);
     2208    return rc;
     2209}
     2210
     2211RTEXITCODE VBoxServiceControlSessionSpawnInit(int argc, char **argv)
    23282212{
    23292213    static const RTGETOPTDEF s_aOptions[] =
     
    23502234                 1 /*iFirst*/, RTGETOPTINIT_FLAGS_OPTS_FIRST);
    23512235
    2352     uint32_t uSessionFlags = VBOXSERVICECTRLSESSION_FLAG_FORK;
     2236    uint32_t uSessionFlags = VBOXSERVICECTRLSESSION_FLAG_SPAWN;
    23532237
    23542238    /* Protocol and session ID must be specified explicitly. */
     
    24272311                              g_szLogFile[0] ? g_szLogFile : "<None>", rc);
    24282312
    2429     RTEXITCODE rcExit = gstcntlSessionForkWorker(&g_Session);
     2313    RTEXITCODE rcExit = gstcntlSessionSpawnWorker(&g_Session);
    24302314
    24312315    VBoxServiceLogDestroy();
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