Changeset 28926 in vbox
- Timestamp:
- Apr 30, 2010 10:21:00 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 60889
- Location:
- trunk/src/VBox
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
r28833 r28926 176 176 pData->uPID, uHandleId, 0 /* u32Flags */, 177 177 abBuf, cbRead); 178 if (RT_FAILURE(rc)) 179 { 180 VBoxServiceError("Control: Error while sending real-time output data, rc=%Rrc, cbRead=%u, CID=%u, PID=%u\n", 181 rc, cbRead, pThread->uClientID, pData->uPID); 182 } 183 else 184 { 178 185 #endif 179 rc = VBoxServiceControlExecWritePipeBuffer(&pData->stdOut, abBuf, cbRead); 180 if (RT_SUCCESS(rc)) 181 { 182 /* Make sure we go another poll round in case there was too much data 183 for the buffer to hold. */ 184 fPollEvt &= RTPOLL_EVT_ERROR; 185 } 186 rc = VBoxServiceControlExecWritePipeBuffer(&pData->stdOut, abBuf, cbRead); 187 if (RT_SUCCESS(rc)) 188 { 189 /* Make sure we go another poll round in case there was too much data 190 for the buffer to hold. */ 191 fPollEvt &= RTPOLL_EVT_ERROR; 192 } 193 #if 0 194 } 195 #endif 186 196 } 187 197 else if (RT_FAILURE(rc2)) -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
r28920 r28926 44 44 #endif 45 45 46 #include <signal.h> 47 46 48 #ifdef RT_OS_DARWIN 47 49 # include <CoreFoundation/CFRunLoop.h> … … 55 57 */ 56 58 /** @todo */ 59 60 /** Set by the signal handler. */ 61 static volatile bool g_fExecCanceled = false; 57 62 58 63 void usageGuestControl(void) … … 65 70 " [--verbose] [--wait-for exit,stdout,stderr||]\n" 66 71 "\n"); 72 } 73 74 /** 75 * Signal handler that sets g_fCanceled. 76 * 77 * This can be executed on any thread in the process, on Windows it may even be 78 * a thread dedicated to delivering this signal. Do not doing anything 79 * unnecessary here. 80 */ 81 static void execProcessSignalHandler(int iSignal) 82 { 83 NOREF(iSignal); 84 ASMAtomicWriteBool(&g_fExecCanceled, true); 67 85 } 68 86 … … 305 323 RTPrintf("Waiting for process to exit ...\n"); 306 324 325 /* setup signal handling if cancelable */ 326 ASSERT(progress); 327 bool fCanceledAlready = false; 328 BOOL fCancelable; 329 HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable); 330 if (FAILED(hrc)) 331 fCancelable = FALSE; 332 if (fCancelable) 333 { 334 signal(SIGINT, execProcessSignalHandler); 335 #ifdef SIGBREAK 336 signal(SIGBREAK, execProcessSignalHandler); 337 #endif 338 } 339 307 340 /* Wait for process to exit ... */ 308 ASSERT(progress); 309 rc = progress->WaitForCompletion(have_timeout ? 310 (u32TimeoutMS + 5000) : /* Timeout value + safety counter */ 311 -1 /* Wait forever */); 312 if (FAILED(rc)) 313 { 314 if (u32TimeoutMS) 315 RTPrintf("Process '%s' (PID: %u) did not end within %ums! Wait aborted.\n", 316 Utf8Cmd.raw(), uPID, u32TimeoutMS); 317 break; 318 } 319 else 320 { 321 BOOL completed; 322 CHECK_ERROR_RET(progress, COMGETTER(Completed)(&completed), rc); 323 ASSERT(completed); 324 325 LONG iRc; 341 BOOL fCompleted = false; 342 ULONG cbOutputData = 0; 343 SafeArray<BYTE> aOutputData; 344 while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted)))) 345 { 346 if (cbOutputData <= 0) 347 { 348 if (fCompleted) 349 break; 350 351 if ( have_timeout 352 && RTTimeMilliTS() - u64StartMS > u32TimeoutMS + 5000) 353 { 354 progress->Cancel(); 355 break; 356 } 357 } 358 359 CHECK_ERROR_BREAK(guest, GetProcessOutput(uPID, 0 /* aFlags */, 360 u32TimeoutMS, _64K, ComSafeArrayAsOutParam(aOutputData))); 361 cbOutputData = aOutputData.size(); 362 if (cbOutputData > 0) 363 { 364 /* aOutputData has a platform dependent line ending, standardize on 365 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on 366 * Windows. Otherwise we end up with CR/CR/LF on Windows. */ 367 ULONG cbOutputDataPrint = cbOutputData; 368 for (BYTE *s = aOutputData.raw(), *d = s; 369 s - aOutputData.raw() < (ssize_t)cbOutputData; 370 s++, d++) 371 { 372 if (*s == '\r') 373 { 374 /* skip over CR, adjust destination */ 375 d--; 376 cbOutputDataPrint--; 377 } 378 else if (s != d) 379 *d = *s; 380 } 381 RTStrmWrite(g_pStdOut, aOutputData.raw(), cbOutputDataPrint); 382 } 383 384 /* process async cancelation. */ 385 if (g_fExecCanceled && !fCanceledAlready) 386 { 387 hrc = progress->Cancel(); 388 if (SUCCEEDED(hrc)) 389 fCanceledAlready = true; 390 else 391 g_fExecCanceled = false; 392 } 393 394 progress->WaitForCompletion(100); 395 } 396 397 /* undo signal handling */ 398 if (fCancelable) 399 { 400 signal(SIGINT, SIG_DFL); 401 #ifdef SIGBREAK 402 signal(SIGBREAK, SIG_DFL); 403 #endif 404 } 405 406 /* Not completed yet? -> Timeout */ 407 if (fCompleted) 408 { 409 LONG iRc = false; 326 410 CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc); 327 411 if (FAILED(iRc)) … … 330 414 rc = progress->COMGETTER(ErrorInfo)(execError.asOutParam()); 331 415 com::ErrorInfo info (execError); 332 RTPrintf(" Process error details:\n");416 RTPrintf("\n\nProcess error details:\n"); 333 417 GluePrintErrorInfo(info); 334 418 RTPrintf("\n"); 335 } 336 419 } 420 } 421 else 422 { 423 RTPrintf("Process timed out!\n"); 424 } 425 426 if (verbose) 427 { 337 428 ULONG uRetStatus, uRetExitCode, uRetFlags; 338 429 CHECK_ERROR_BREAK(guest, GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &uRetStatus)); 339 if (verbose) 340 RTPrintf("Exit code=%u (Status=%u, Flags=%u)\n", uRetExitCode, uRetStatus, uRetFlags); 341 342 /* Print output if wanted. */ 343 if ( waitForStdOut 344 || waitForStdErr) 345 { 346 bool bFound = false; 347 while (true) 348 { 349 SafeArray<BYTE> aOutputData; 350 ULONG cbOutputData; 351 CHECK_ERROR_BREAK(guest, GetProcessOutput(uPID, 0 /* aFlags */, 352 u32TimeoutMS, _64K, ComSafeArrayAsOutParam(aOutputData))); 353 cbOutputData = aOutputData.size(); 354 if (cbOutputData == 0) 355 break; 356 357 if (!bFound && verbose) 358 { 359 RTPrintf("Retrieving output data ...\n"); 360 bFound = true; 361 } 362 363 /* aOutputData has a platform dependent line ending, standardize on 364 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on 365 * Windows. Otherwise we end up with CR/CR/LF on Windows. */ 366 ULONG cbOutputDataPrint = cbOutputData; 367 for (BYTE *s = aOutputData.raw(), *d = s; 368 s - aOutputData.raw() < (ssize_t)cbOutputData; 369 s++, d++) 370 { 371 if (*s == '\r') 372 { 373 /* skip over CR, adjust destination */ 374 d--; 375 cbOutputDataPrint--; 376 } 377 else if (s != d) 378 *d = *s; 379 } 380 RTStrmWrite(g_pStdOut, aOutputData.raw(), cbOutputDataPrint); 381 } 382 if (!bFound && verbose) 383 RTPrintf("No output data available\n"); 384 } 430 RTPrintf("Exit code=%u (Status=%u, Flags=%u)\n", uRetExitCode, uRetStatus, uRetFlags); 385 431 } 386 432 } -
trunk/src/VBox/Main/GuestImpl.cpp
r28887 r28926 478 478 /** @todo Copy void* buffer contents! */ 479 479 480 /* Was progress canceled before? */ 481 BOOL fCancelled; 482 it->pProgress->COMGETTER(Canceled)(&fCancelled); 483 480 484 /* Do progress handling. */ 481 485 Utf8Str errMsg; … … 487 491 488 492 case PROC_STS_TEN: /* Terminated normally. */ 489 if (!it->pProgress->getCompleted()) 493 if ( !it->pProgress->getCompleted() 494 && !fCancelled) 495 { 490 496 it->pProgress->notifyComplete(S_OK); 497 } 491 498 break; 492 499 … … 542 549 && errMsg.length()) 543 550 { 544 if (!it->pProgress->getCompleted()) 551 if ( !it->pProgress->getCompleted() 552 && !fCancelled) 545 553 { 546 554 it->pProgress->notifyComplete(E_FAIL /** @todo Find a better rc! */, COM_IIDOF(IGuest), … … 719 727 rc = progress->init(static_cast<IGuest*>(this), 720 728 BstrFmt(tr("Executing process")), 721 FALSE);729 TRUE); 722 730 } 723 731 if (FAILED(rc)) return rc;
Note:
See TracChangeset
for help on using the changeset viewer.