Changeset 83489 in vbox for trunk/src/VBox/Main/src-client
- Timestamp:
- Mar 30, 2020 4:38:23 PM (5 years ago)
- Location:
- trunk/src/VBox/Main/src-client
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp
r82968 r83489 83 83 /* Start the directory process on the guest. */ 84 84 GuestProcessStartupInfo procInfo; 85 procInfo.mName = Utf8StrFmt(tr(" Reading directory \"%s\""), openInfo.mPath.c_str());85 procInfo.mName = Utf8StrFmt(tr("Opening directory \"%s\""), openInfo.mPath.c_str()); 86 86 procInfo.mTimeoutMS = 5 * 60 * 1000; /* 5 minutes timeout. */ 87 87 procInfo.mFlags = ProcessCreateFlag_WaitForStdOut; … … 100 100 101 101 /* 102 * Start the process asynchronously and keep it around so that we can use102 * Start the process synchronously and keep it around so that we can use 103 103 * it later in subsequent read() calls. 104 * Note: No guest rc available because operation is asynchronous.105 104 */ 106 vrc = mData.mProcessTool.init(mSession, procInfo, true /* Async */, NULL /* Guest rc */); 107 108 /** @todo r=bird: IGuest::directoryOpen need to fail if the directory doesn't 109 * exist like it is documented to do. It seems this async approach or 110 * something is delaying such errors till GuestDirectory::read() is 111 * called, which is clearly messed up. 112 */ 105 vrc = mData.mProcessTool.init(mSession, procInfo, false /* Async */, NULL /* Guest rc */); 106 if (RT_SUCCESS(vrc)) 107 { 108 /* As we need to know if the directory we were about to open exists and and is accessible, 109 * do the first read here in order to return a meaningful status here. */ 110 int rcGuest = VERR_IPE_UNINITIALIZED_STATUS; 111 vrc = i_readInternal(mData.mObjData, &rcGuest); 112 if (RT_FAILURE(vrc)) 113 { 114 /* 115 * We need to actively terminate our process tool in case of an error here, 116 * as this otherwise would be done on (directory) object destruction implicitly. 117 * This in turn then will run into a timeout, as the directory object won't be 118 * around anymore at that time. Ugly, but that's how it is for the moment. 119 */ 120 int vrcTerm = mData.mProcessTool.terminate(30 * RT_MS_1SEC, NULL /* prcGuest */); 121 AssertRC(vrcTerm); 122 123 if (vrc == VERR_GSTCTL_GUEST_ERROR) 124 vrc = rcGuest; 125 } 126 } 113 127 } 114 128 … … 118 132 else 119 133 autoInitSpan.setFailed(); 134 135 LogFlowFuncLeaveRC(vrc); 120 136 return vrc; 121 137 } … … 284 300 285 301 /** 286 * Reads the next directory entry .302 * Reads the next directory entry, internal version. 287 303 * 288 304 * @return VBox status code. Will return VERR_NO_MORE_FILES if no more entries are available. 289 * @param fsObjInfo Where to store the read directory entry.305 * @param objData Where to store the read directory entry as internal object data. 290 306 * @param prcGuest Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned. 291 307 */ 292 int GuestDirectory::i_readInternal( ComObjPtr<GuestFsObjInfo> &fsObjInfo, int *prcGuest)308 int GuestDirectory::i_readInternal(GuestFsObjData &objData, int *prcGuest) 293 309 { 294 310 AssertPtrReturn(prcGuest, VERR_INVALID_POINTER); 295 296 /* Create the FS info object. */297 HRESULT hr = fsObjInfo.createObject();298 if (FAILED(hr))299 return VERR_COM_UNEXPECTED;300 311 301 312 GuestProcessStreamBlock curBlock; … … 314 325 if (curBlock.GetCount()) /* Did we get content? */ 315 326 { 316 GuestFsObjData objData; 317 rc = objData.FromLs(curBlock, true /* fLong */); 318 if (RT_SUCCESS(rc)) 327 if (curBlock.GetString("name")) 319 328 { 320 rc = fsObjInfo->init(objData);329 rc = objData.FromLs(curBlock, true /* fLong */); 321 330 } 322 331 else … … 335 344 } 336 345 346 /** 347 * Reads the next directory entry. 348 * 349 * @return VBox status code. Will return VERR_NO_MORE_FILES if no more entries are available. 350 * @param fsObjInfo Where to store the read directory entry. 351 * @param prcGuest Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned. 352 */ 353 int GuestDirectory::i_read(ComObjPtr<GuestFsObjInfo> &fsObjInfo, int *prcGuest) 354 { 355 AssertPtrReturn(prcGuest, VERR_INVALID_POINTER); 356 357 /* Create the FS info object. */ 358 HRESULT hr = fsObjInfo.createObject(); 359 if (FAILED(hr)) 360 return VERR_COM_UNEXPECTED; 361 362 int rc; 363 364 /* If we have a valid object data cache, read from it. */ 365 if (mData.mObjData.mName.isNotEmpty()) 366 { 367 rc = fsObjInfo->init(mData.mObjData); 368 if (RT_SUCCESS(rc)) 369 { 370 mData.mObjData.mName = ""; /* Mark the object data as being empty (beacon). */ 371 } 372 } 373 else /* Otherwise ask the guest for the next object data (block). */ 374 { 375 376 GuestFsObjData objData; 377 rc = i_readInternal(objData, prcGuest); 378 if (RT_SUCCESS(rc)) 379 rc = fsObjInfo->init(objData); 380 } 381 382 LogFlowThisFunc(("Returning rc=%Rrc\n", rc)); 383 return rc; 384 } 385 337 386 /* static */ 338 387 HRESULT GuestDirectory::i_setErrorExternal(VirtualBoxBase *pInterface, int rcGuest) … … 391 440 ComObjPtr<GuestFsObjInfo> fsObjInfo; 392 441 int rcGuest = VERR_IPE_UNINITIALIZED_STATUS; 393 int vrc = i_read Internal(fsObjInfo, &rcGuest);442 int vrc = i_read(fsObjInfo, &rcGuest); 394 443 if (RT_SUCCESS(vrc)) 395 444 { -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r83419 r83489 1165 1165 } 1166 1166 1167 /* We need to release the write lock first before initializing the directory object below, 1168 * as we're starting a guest process as part of it. This in turn will try to acquire the session's 1169 * write lock. */ 1170 alock.release(); 1171 1167 1172 Console *pConsole = mParent->i_getConsole(); 1168 1173 AssertPtr(pConsole); … … 1170 1175 vrc = pDirectory->init(pConsole, this /* Parent */, idObject, openInfo); 1171 1176 if (RT_FAILURE(vrc)) 1172 return vrc; 1173 1174 /* 1175 * Since this is a synchronous guest call we have to 1176 * register the file object first, releasing the session's 1177 * lock and then proceed with the actual opening command 1178 * -- otherwise the file's opening callback would hang 1179 * because the session's lock still is in place. 1180 */ 1181 try 1182 { 1183 /* Add the created directory to our map. */ 1184 mData.mDirectories[idObject] = pDirectory; 1185 1186 LogFlowFunc(("Added new guest directory \"%s\" (Session: %RU32) (now total %zu directories)\n", 1187 openInfo.mPath.c_str(), mData.mSession.mID, mData.mDirectories.size())); 1188 1189 alock.release(); /* Release lock before firing off event. */ 1190 1191 /** @todo Fire off a VBoxEventType_OnGuestDirectoryRegistered event? */ 1192 } 1193 catch (std::bad_alloc &) 1194 { 1195 vrc = VERR_NO_MEMORY; 1177 { 1178 /* Make sure to acquire the write lock again before unregistering the object. */ 1179 alock.acquire(); 1180 1181 int vrc2 = i_objectUnregister(idObject); 1182 AssertRC(vrc2); 1183 1184 pDirectory.setNull(); 1185 } 1186 else 1187 { 1188 /* Make sure to acquire the write lock again before continuing. */ 1189 alock.acquire(); 1190 1191 try 1192 { 1193 /* Add the created directory to our map. */ 1194 mData.mDirectories[idObject] = pDirectory; 1195 1196 LogFlowFunc(("Added new guest directory \"%s\" (Session: %RU32) (now total %zu directories)\n", 1197 openInfo.mPath.c_str(), mData.mSession.mID, mData.mDirectories.size())); 1198 1199 alock.release(); /* Release lock before firing off event. */ 1200 1201 /** @todo Fire off a VBoxEventType_OnGuestDirectoryRegistered event? */ 1202 } 1203 catch (std::bad_alloc &) 1204 { 1205 vrc = VERR_NO_MEMORY; 1206 } 1196 1207 } 1197 1208 -
trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
r83337 r83489 1110 1110 { 1111 1111 ComObjPtr<GuestFsObjInfo> fsObjInfo; 1112 while (RT_SUCCESS(rc = pDir->i_read Internal(fsObjInfo, &rcGuest)))1112 while (RT_SUCCESS(rc = pDir->i_read(fsObjInfo, &rcGuest))) 1113 1113 { 1114 1114 FsObjType_T enmObjType = FsObjType_Unknown; /* Shut up MSC. */
Note:
See TracChangeset
for help on using the changeset viewer.