Changeset 57659 in vbox
- Timestamp:
- Sep 9, 2015 11:17:17 AM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 102561
- Location:
- trunk/src/VBox/Additions/common/VBoxService
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp
r57416 r57659 866 866 */ 867 867 if (fUserSession) 868 return VBoxServiceControlSession ForkInit(argc, argv);868 return VBoxServiceControlSessionSpawnInit(argc, argv); 869 869 #endif 870 870 -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
r57358 r57659 130 130 else if (!strcmp(argv[*pi], "--control-dump-stdout")) 131 131 { 132 g_Session. uFlags |= VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT;132 g_Session.fFlags |= VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT; 133 133 rc = 0; /* Flag this command as parsed. */ 134 134 } 135 135 else if (!strcmp(argv[*pi], "--control-dump-stderr")) 136 136 { 137 g_Session. uFlags |= VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR;137 g_Session.fFlags |= VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR; 138 138 rc = 0; /* Flag this command as parsed. */ 139 139 } … … 372 372 ssInfo.szPassword, sizeof(ssInfo.szPassword), 373 373 ssInfo.szDomain, sizeof(ssInfo.szDomain), 374 &ssInfo. uFlags, &ssInfo.uSessionID);374 &ssInfo.fFlags, &ssInfo.uSessionID); 375 375 if (RT_SUCCESS(rc)) 376 376 { -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h
r56294 r57659 82 82 /** Session creation flags. 83 83 * @sa VBOXSERVICECTRLSESSIONSTARTUPFLAG_* flags. */ 84 uint32_t uFlags;84 uint32_t fFlags; 85 85 } VBOXSERVICECTRLSESSIONSTARTUPINFO; 86 86 /** Pointer to thread data. */ … … 136 136 typedef VBOXSERVICECTRLSESSIONTHREAD *PVBOXSERVICECTRLSESSIONTHREAD; 137 137 138 /** Flag indicating that this session has been forked from138 /** Flag indicating that this session has been spawned from 139 139 * the main executable. */ 140 #define VBOXSERVICECTRLSESSION_FLAG_ FORKRT_BIT(0)140 #define VBOXSERVICECTRLSESSION_FLAG_SPAWN RT_BIT(0) 141 141 /** Flag indicating that this session is anonymous, that is, 142 142 * it will run start guest processes with the same credentials … … 177 177 * to StartupInfo stuff. 178 178 * @sa VBOXSERVICECTRLSESSION_FLAG_* flags. */ 179 uint32_t uFlags;179 uint32_t fFlags; 180 180 /** How many processes do we allow keeping around at a time? */ 181 181 uint32_t uProcsMaxKept; … … 299 299 extern int GstCntlSessionThreadDestroyAll(PRTLISTANCHOR pList, uint32_t uFlags); 300 300 extern int GstCntlSessionThreadTerminate(PVBOXSERVICECTRLSESSIONTHREAD pSession); 301 extern RTEXITCODE VBoxServiceControlSession ForkInit(int argc, char **argv);301 extern RTEXITCODE VBoxServiceControlSessionSpawnInit(int argc, char **argv); 302 302 /* Per-session functions. */ 303 303 extern PVBOXSERVICECTRLPROCESS GstCntlSessionRetainProcess(PVBOXSERVICECTRLSESSION pSession, uint32_t uPID); -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
r57358 r57659 1497 1497 RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL); 1498 1498 /* Did we get the same result? */ 1499 Assert(pProcess->StartupInfo.uNumArgs == uNumArgs );1499 Assert(pProcess->StartupInfo.uNumArgs == uNumArgs + 1 /* Take argv[0] into account */); 1500 1500 1501 1501 /* … … 1615 1615 { 1616 1616 AssertPtr(pProcess->pSession); 1617 bool fNeedsImpersonation = !(pProcess->pSession-> uFlags & VBOXSERVICECTRLSESSION_FLAG_FORK);1617 bool fNeedsImpersonation = !(pProcess->pSession->fFlags & VBOXSERVICECTRLSESSION_FLAG_SPAWN); 1618 1618 1619 1619 rc = gstcntlProcessCreateProcess(pProcess->StartupInfo.szCmd, papszArgs, hEnv, … … 1972 1972 if (RT_SUCCESS(rc)) 1973 1973 { 1974 if ( pSession-> uFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT1974 if ( pSession->fFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT 1975 1975 && ( uHandle == OUTPUT_HANDLE_ID_STDOUT 1976 1976 || uHandle == OUTPUT_HANDLE_ID_STDOUT_DEPRECATED) … … 1984 1984 AssertRC(rc); 1985 1985 } 1986 else if ( pSession-> uFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR1986 else if ( pSession->fFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR 1987 1987 && uHandle == OUTPUT_HANDLE_ID_STDERR) 1988 1988 { -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
r57358 r57659 1 1 /* $Id$ */ 2 2 /** @file 3 * VBoxServiceControlSession - Guest session handling. Also handles 4 * the forked session processes. 3 * VBoxServiceControlSession - Guest session handling. Also handles the spawned session processes. 5 4 */ 6 5 … … 75 74 76 75 77 /** Generic option indices for session forkarguments. */76 /** Generic option indices for session spawn arguments. */ 78 77 enum 79 78 { … … 133 132 134 133 char szDir[RTPATH_MAX]; 135 uint32_t uFlags = 0;134 uint32_t fFlags = 0; 136 135 137 136 int rc = VbglR3GuestCtrlDirGetRemove(pHostCtx, … … 139 138 szDir, sizeof(szDir), 140 139 /* 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); 174 156 } 175 157 else 176 158 rc = VERR_NOT_SUPPORTED; 177 159 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); 192 161 193 162 /* Report back in any case. */ 194 163 int rc2 = VbglR3GuestCtrlMsgReply(pHostCtx, rc); 195 164 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); 198 166 if (RT_SUCCESS(rc)) 199 167 rc = rc2; … … 201 169 202 170 #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); 205 172 #endif 206 173 return rc; … … 246 213 rc = VERR_INVALID_PARAMETER; 247 214 248 if ( RT_SUCCESS(rc)249 && !RTStrPrintf(pFile->szName, sizeof(pFile->szName), "%s", szFile))250 rc = VERR_NO_MEMORY;251 252 215 if (RT_SUCCESS(rc)) 253 216 { 217 RTStrPrintf(pFile->szName, sizeof(pFile->szName), "%s", szFile); 218 254 219 uint64_t fFlags; 255 220 rc = RTFileModeToFlagsEx(szAccess, szDisposition, 256 221 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 259 224 if (RT_SUCCESS(rc)) 260 225 rc = RTFileOpen(&pFile->hFile, pFile->szName, fFlags); … … 270 235 } 271 236 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); 274 238 } 275 239 … … 481 445 482 446 int rc = VbglR3GuestCtrlFileGetWrite(pHostCtx, &uHandle, 483 pvScratchBuf, cbScratchBuf, 484 &cbToWrite); 447 pvScratchBuf, (uint32_t)cbScratchBuf, &cbToWrite); 485 448 if (RT_SUCCESS(rc)) 486 449 { … … 529 492 530 493 int rc = VbglR3GuestCtrlFileGetWriteAt(pHostCtx, &uHandle, 531 pvScratchBuf, cbScratchBuf,494 pvScratchBuf, (uint32_t)cbScratchBuf, 532 495 &cbToWrite, (uint64_t *)&iOffset); 533 496 if (RT_SUCCESS(rc)) … … 867 830 */ 868 831 int rc = VbglR3GuestCtrlProcGetInput(pHostCtx, &uPID, &uFlags, 869 pvScratchBuf, cbScratchBuf, &cbSize);832 pvScratchBuf, (uint32_t)cbScratchBuf, &cbSize); 870 833 if (RT_FAILURE(rc)) 871 834 { … … 1037 1000 /** 1038 1001 * Only anonymous sessions (that is, sessions which run with local 1039 * service privileges) or forked session processes can do certain1002 * service privileges) or spawned session processes can do certain 1040 1003 * operations. 1041 1004 */ 1042 bool fImpersonated = ( pSession-> uFlags & VBOXSERVICECTRLSESSION_FLAG_FORK1043 || pSession-> uFlags & VBOXSERVICECTRLSESSION_FLAG_ANONYMOUS);1005 bool fImpersonated = ( pSession->fFlags & VBOXSERVICECTRLSESSION_FLAG_SPAWN 1006 || pSession->fFlags & VBOXSERVICECTRLSESSION_FLAG_ANONYMOUS); 1044 1007 1045 1008 switch (uMsg) 1046 1009 { 1047 1010 case HOST_SESSION_CLOSE: 1048 /* Shutdown (this fork). */1011 /* Shutdown (this spawn). */ 1049 1012 rc = GstCntlSessionClose(pSession); 1050 1013 *pfShutdown = true; /* Shutdown in any case. */ … … 1152 1115 1153 1116 /** 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. 1157 1119 * 1158 1120 * @return IPRT status code. … … 1358 1320 1359 1321 1360 RTEXITCODE gstcntlSession ForkWorker(PVBOXSERVICECTRLSESSION pSession)1322 RTEXITCODE gstcntlSessionSpawnWorker(PVBOXSERVICECTRLSESSION pSession) 1361 1323 { 1362 1324 AssertPtrReturn(pSession, RTEXITCODE_FAILURE); … … 1650 1612 1651 1613 1652 int GstCntlSessionInit(PVBOXSERVICECTRLSESSION pSession, uint32_t uFlags)1614 int GstCntlSessionInit(PVBOXSERVICECTRLSESSION pSession, uint32_t fFlags) 1653 1615 { 1654 1616 AssertPtrReturn(pSession, VERR_INVALID_POINTER); … … 1657 1619 RTListInit(&pSession->lstFiles); 1658 1620 1659 pSession-> uFlags = uFlags;1621 pSession->fFlags = fFlags; 1660 1622 1661 1623 /* Init critical section for protecting the thread lists. */ … … 1845 1807 VBoxServiceVerbose(3, "New anonymous guest session ID=%RU32 created, uFlags=%x, using protocol %RU32\n", 1846 1808 pSessionStartupInfo->uSessionID, 1847 pSessionStartupInfo-> uFlags,1809 pSessionStartupInfo->fFlags, 1848 1810 pSessionStartupInfo->uProtocol); 1849 1811 } 1850 1812 else 1851 1813 { 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", 1853 1815 pSessionStartupInfo->uSessionID, 1854 1816 pSessionStartupInfo->szUser, … … 1859 1821 #endif 1860 1822 pSessionStartupInfo->szDomain, 1861 pSessionStartupInfo-> uFlags,1823 pSessionStartupInfo->fFlags, 1862 1824 pSessionStartupInfo->uProtocol); 1863 1825 } … … 1873 1835 if (pszExeName) 1874 1836 { 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 1905 1847 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) 1950 1887 { 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 } 1953 1920 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); 1956 1926 } 1957 1927 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); 2066 1979 if (RT_SUCCESS(rc)) 2067 1980 { 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 } 2073 2016 } 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); 2079 2028 if (RT_SUCCESS(rc)) 2080 2029 { 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); 2121 2039 } 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); 2151 2046 } 2152 2047 else … … 2198 2093 rc = VERR_NO_MEMORY; 2199 2094 2200 VBoxServiceVerbose(3, " Forking session thread returned returned rc=%Rrc\n", rc);2095 VBoxServiceVerbose(3, "Spawning session thread returned returned rc=%Rrc\n", rc); 2201 2096 return rc; 2202 2097 } … … 2227 2122 2228 2123 /* 2229 * The forkshould have received the same closing request,2124 * The spawned session process should have received the same closing request, 2230 2125 * so just wait for the process to close. 2231 2126 */ … … 2296 2191 VBoxServiceError("Cancelling pending waits failed; rc=%Rrc\n", rc);*/ 2297 2192 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); 2307 2198 if (RT_FAILURE(rc2)) 2308 2199 { 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); 2310 2201 if (RT_SUCCESS(rc)) 2311 2202 rc = rc2; 2312 2203 /* Keep going. */ 2313 2204 } 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 2211 RTEXITCODE VBoxServiceControlSessionSpawnInit(int argc, char **argv) 2328 2212 { 2329 2213 static const RTGETOPTDEF s_aOptions[] = … … 2350 2234 1 /*iFirst*/, RTGETOPTINIT_FLAGS_OPTS_FIRST); 2351 2235 2352 uint32_t uSessionFlags = VBOXSERVICECTRLSESSION_FLAG_ FORK;2236 uint32_t uSessionFlags = VBOXSERVICECTRLSESSION_FLAG_SPAWN; 2353 2237 2354 2238 /* Protocol and session ID must be specified explicitly. */ … … 2427 2311 g_szLogFile[0] ? g_szLogFile : "<None>", rc); 2428 2312 2429 RTEXITCODE rcExit = gstcntlSession ForkWorker(&g_Session);2313 RTEXITCODE rcExit = gstcntlSessionSpawnWorker(&g_Session); 2430 2314 2431 2315 VBoxServiceLogDestroy();
Note:
See TracChangeset
for help on using the changeset viewer.