Changeset 33064 in vbox for trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
- Timestamp:
- Oct 12, 2010 1:20:50 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
r32852 r33064 47 47 extern RTLISTNODE g_GuestControlExecThreads; 48 48 49 49 50 /** 50 51 * Handle an error event on standard input. 51 52 * 53 * @returns IPRT status code. 52 54 * @param hPollSet The polling set. 53 55 * @param fPollEvt The event mask returned by RTPollNoResume. … … 55 57 * @param pStdInBuf The standard input buffer. 56 58 */ 57 static void VBoxServiceControlExecProcHandleStdInErrorEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phStdInW, 58 PVBOXSERVICECTRLSTDINBUF pStdInBuf) 59 { 60 int rc2; 61 if (pStdInBuf->off < pStdInBuf->cb) 62 { 63 rc2 = RTPollSetRemove(hPollSet, 4 /*TXSEXECHNDID_STDIN_WRITABLE*/); 59 static int VBoxServiceControlExecProcHandleStdInErrorEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phStdInW, 60 PVBOXSERVICECTRLEXECPIPEBUF pStdInBuf) 61 { 62 int rc = RTCritSectEnter(&pStdInBuf->CritSect); 63 if (RT_SUCCESS(rc)) 64 { 65 int rc2; 66 /* If no data is to be processed anymore, remove the writable pipe from 67 * the poll set. */ 68 if (pStdInBuf->cbProcessed <= pStdInBuf->cbSize) 69 { 70 rc2 = RTPollSetRemove(hPollSet, VBOXSERVICECTRLPIPEID_STDIN_WRITABLE); 71 AssertRC(rc2); 72 73 rc2 = RTPipeClose(*phStdInW); 74 AssertRC(rc2); 75 *phStdInW = NIL_RTPIPE; 76 77 /* Mark the stdin buffer as dead; we're not using it anymore. */ 78 pStdInBuf->fAlive = false; 79 } 80 81 rc2 = RTPollSetRemove(hPollSet, VBOXSERVICECTRLPIPEID_STDIN_ERROR); 64 82 AssertRC(rc2); 65 } 66 67 rc2 = RTPollSetRemove(hPollSet, 0 /*TXSEXECHNDID_STDIN*/); 68 AssertRC(rc2); 69 70 rc2 = RTPipeClose(*phStdInW); 71 AssertRC(rc2); 72 *phStdInW = NIL_RTPIPE; 73 74 RTMemFree(pStdInBuf->pch); 75 pStdInBuf->pch = NULL; 76 pStdInBuf->off = 0; 77 pStdInBuf->cb = 0; 78 pStdInBuf->cbAllocated = 0; 79 pStdInBuf->fBitBucket = true; 83 84 rc2 = RTCritSectLeave(&pStdInBuf->CritSect); 85 if (RT_SUCCESS(rc)) 86 rc = rc2; 87 } 88 return rc; 80 89 } 81 90 … … 88 97 * @param hStdInW The standard input pipe. 89 98 */ 90 static int VBoxServiceControlExecProcWriteStdIn(PVBOXSERVICECTRL STDINBUF pStdInBuf, RTPIPE hStdInW)91 { 92 size_t cbToWrite = pStdInBuf->cb - pStdInBuf->off;93 size_t cbWritten; 94 int rc = RTPipeWrite(hStdInW, &pStdInBuf->pch[pStdInBuf->off], cbToWrite, &cbWritten);99 static int VBoxServiceControlExecProcWriteStdIn(PVBOXSERVICECTRLEXECPIPEBUF pStdInBuf, RTPIPE hStdInW, size_t *pcbWritten) 100 { 101 AssertPtrReturn(pcbWritten, VERR_INVALID_PARAMETER); 102 103 int rc = RTCritSectEnter(&pStdInBuf->CritSect); 95 104 if (RT_SUCCESS(rc)) 96 105 { 97 Assert(cbWritten == cbToWrite); 98 pStdInBuf->off += cbWritten; 106 size_t cbToWrite = pStdInBuf->cbSize - pStdInBuf->cbProcessed; 107 int rc = VINF_SUCCESS; 108 if (cbToWrite && pStdInBuf->fAlive) 109 { 110 rc = RTPipeWrite(hStdInW, &pStdInBuf->pbData[pStdInBuf->cbProcessed], cbToWrite, pcbWritten); 111 if (RT_SUCCESS(rc)) 112 { 113 Assert(*pcbWritten <= cbToWrite); 114 pStdInBuf->cbProcessed += *pcbWritten; 115 } 116 else 117 *pcbWritten = 0; 118 } 119 else 120 rc = VERR_BAD_PIPE; 121 int rc2 = RTCritSectLeave(&pStdInBuf->CritSect); 122 if (RT_SUCCESS(rc)) 123 rc = rc2; 99 124 } 100 125 return rc; … … 106 131 * child process. 107 132 * 133 * @returns IPRT status code. 108 134 * @param hPollSet The polling set. 109 135 * @param fPollEvt The event mask returned by RTPollNoResume. … … 111 137 * @param pStdInBuf The standard input buffer. 112 138 */ 113 static void VBoxServiceControlExecProcHandleStdInWritableEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phStdInW, 114 PVBOXSERVICECTRLSTDINBUF pStdInBuf) 115 { 116 int rc; 139 static int VBoxServiceControlExecProcHandleStdInWritableEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phStdInW, 140 PVBOXSERVICECTRLEXECPIPEBUF pStdInBuf) 141 { 142 VBoxServiceVerbose(4, "ControlExec: HandleStdInWritableEvent: fPollEvt=%#x\n", fPollEvt); 143 144 int rc = VINF_SUCCESS; 117 145 if (!(fPollEvt & RTPOLL_EVT_ERROR)) 118 146 { 119 rc = VBoxServiceControlExecProcWriteStdIn(pStdInBuf, *phStdInW); 120 if (RT_FAILURE(rc) && rc != VERR_BAD_PIPE) 121 { 122 /** @todo do we need to do something about this error condition? */ 147 size_t cbWritten; 148 rc = VBoxServiceControlExecProcWriteStdIn(pStdInBuf, *phStdInW, &cbWritten); 149 if ( RT_FAILURE(rc) 150 && rc != VERR_BAD_PIPE) 151 { 152 /** @todo Do we need to do something about this error condition? */ 123 153 AssertRC(rc); 124 154 } 125 155 126 if (pStdInBuf->off < pStdInBuf->cb) 127 { 128 rc = RTPollSetRemove(hPollSet, 4 /*TXSEXECHNDID_STDIN_WRITABLE*/); 156 /* No more data to write to stdin? Then remove stdin from poll set. */ 157 if ( cbWritten <= 0 158 || rc == VERR_BAD_PIPE) 159 { 160 rc = RTPollSetRemove(hPollSet, VBOXSERVICECTRLPIPEID_STDIN_WRITABLE); 129 161 AssertRC(rc); 130 162 } 131 163 } 132 164 else 133 VBoxServiceControlExecProcHandleStdInErrorEvent(hPollSet, fPollEvt, phStdInW, pStdInBuf); 165 rc = VBoxServiceControlExecProcHandleStdInErrorEvent(hPollSet, fPollEvt, phStdInW, pStdInBuf); 166 return rc; 167 } 168 169 170 static int VBoxServiceControlExecProcHandleInputEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phStdInW, 171 uint32_t uHandleId, PVBOXSERVICECTRLEXECPIPEBUF pStdInBuf) 172 { 173 VBoxServiceVerbose(4, "ControlExec: HandleInputEvent: fPollEvt=%#x\n", fPollEvt); 174 175 int rc = VINF_SUCCESS; 176 if (fPollEvt & RTPOLL_EVT_ERROR) 177 rc = VBoxServiceControlExecProcHandleStdInErrorEvent(hPollSet, fPollEvt, phStdInW, pStdInBuf); 178 return rc; 134 179 } 135 180 … … 146 191 * @param pu32Crc The current CRC-32 of the stream. (In/Out) 147 192 * @param uHandleId The handle ID. 148 * @param pszOpcode The opcode for the data upload.149 193 * 150 194 * @todo Put the last 4 parameters into a struct! 151 195 */ 152 static int VBoxServiceControlExecProcHandleOutputEvent(PVBOXSERVICECTRLTHREAD pThread, 153 RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phPipeR, 154 uint32_t *puCrc32 , uint32_t uHandleId) 155 { 156 Log(("VBoxServiceControlExecProcHandleOutputEvent: fPollEvt=%#x\n", fPollEvt)); 196 static int VBoxServiceControlExecProcHandleOutputEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phPipeR, 197 uint32_t uHandleId, PVBOXSERVICECTRLEXECPIPEBUF pStdOutBuf) 198 { 199 VBoxServiceVerbose(4, "ControlExec: HandleOutputEvent: fPollEvt=%#x\n", fPollEvt); 157 200 158 201 /* … … 163 206 uint8_t abBuf[_64K]; 164 207 165 AssertPtr(pThread);166 PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;167 AssertPtr(pData);168 169 208 int rc2 = RTPipeRead(*phPipeR, abBuf, sizeof(abBuf), &cbRead); 170 209 if (RT_SUCCESS(rc2) && cbRead) … … 183 222 { 184 223 #endif 185 rc = VBoxServiceControlExecWritePipeBuffer( &pData->stdOut, abBuf, cbRead);224 rc = VBoxServiceControlExecWritePipeBuffer(pStdOutBuf, abBuf, cbRead); 186 225 if (RT_SUCCESS(rc)) 187 226 { … … 229 268 */ 230 269 static int VBoxServiceControlExecProcHandleTransportEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, uint32_t idPollHnd, 231 PRTPIPE phStdInW, PVBOXSERVICECTRLSTDINBUF pStdInBuf) 232 { 233 234 int rc = RTPollSetAddPipe(hPollSet, *phStdInW, RTPOLL_EVT_WRITE, 4 /*TXSEXECHNDID_STDIN_WRITABLE*/); 235 236 return rc; 270 PRTPIPE phStdInW, PVBOXSERVICECTRLEXECPIPEBUF pStdInBuf) 271 { 272 return 0; //RTPollSetAddPipe(hPollSet, *phStdInW, RTPOLL_EVT_WRITE, 4 /*TXSEXECHNDID_STDIN_WRITABLE*/); 237 273 } 238 274 … … 244 280 int rc; 245 281 int rc2; 246 VBOXSERVICECTRLSTDINBUF StdInBuf = { 0, 0, NULL, 0, hStdInW == NIL_RTPIPE, RTCrc32Start() };247 uint32_t uStdOutCrc32 = RTCrc32Start();248 uint32_t uStdErrCrc32 = uStdOutCrc32;249 282 uint64_t const MsStart = RTTimeMilliTS(); 250 283 RTPROCSTATUS ProcessStatus = { 254, RTPROCEXITREASON_ABEND }; … … 253 286 uint64_t MsProcessKilled = UINT64_MAX; 254 287 RTMSINTERVAL const cMsPollBase = hStdInW != NIL_RTPIPE 255 ? 100 /* need to poll for input*/256 : 1000; /* need only poll for process exit and aborts*/288 ? 100 /* Need to poll for input. */ 289 : 1000; /* Need only poll for process exit and aborts. */ 257 290 RTMSINTERVAL cMsPollCur = 0; 258 291 … … 290 323 continue; 291 324 292 cMsPollCur = 0; /* no rest until we've checked everything. */325 cMsPollCur = 0; /* No rest until we've checked everything. */ 293 326 294 327 if (RT_SUCCESS(rc2)) 295 328 { 329 VBoxServiceVerbose(4, "ControlExec: RTPollNoResume idPollHnd=%u\n", idPollHnd); 296 330 switch (idPollHnd) 297 331 { 298 case 0 /* TXSEXECHNDID_STDIN */: 299 VBoxServiceControlExecProcHandleStdInErrorEvent(hPollSet, fPollEvt, &hStdInW, &StdInBuf); 332 case VBOXSERVICECTRLPIPEID_STDIN_ERROR: 333 rc = VBoxServiceControlExecProcHandleInputEvent(hPollSet, fPollEvt, &hStdInW, 334 VBOXSERVICECTRLPIPEID_STDIN_ERROR, &pData->stdIn); 300 335 break; 301 336 302 case 1 /* TXSEXECHNDID_STDOUT */:303 rc = VBoxServiceControlExecProcHandle OutputEvent(pThread, hPollSet, fPollEvt, &hStdOutR, &uStdOutCrc32, 1 /* TXSEXECHNDID_STDOUT */);337 case VBOXSERVICECTRLPIPEID_STDIN_WRITABLE: 338 rc = VBoxServiceControlExecProcHandleStdInWritableEvent(hPollSet, fPollEvt, &hStdInW, &pData->stdIn); 304 339 break; 305 340 306 case 2 /*TXSEXECHNDID_STDERR */: 307 rc = VBoxServiceControlExecProcHandleOutputEvent(pThread, hPollSet, fPollEvt, &hStdErrR, &uStdErrCrc32, 2 /*TXSEXECHNDID_STDERR */); 341 case VBOXSERVICECTRLPIPEID_STDOUT: 342 rc = VBoxServiceControlExecProcHandleOutputEvent(hPollSet, fPollEvt, &hStdOutR, 343 VBOXSERVICECTRLPIPEID_STDOUT, &pData->stdOut); 308 344 break; 309 345 310 case 4 /* TXSEXECHNDID_STDIN_WRITABLE */: 311 VBoxServiceControlExecProcHandleStdInWritableEvent(hPollSet, fPollEvt, &hStdInW, &StdInBuf); 346 case VBOXSERVICECTRLPIPEID_STDERR: 347 rc = VBoxServiceControlExecProcHandleOutputEvent(hPollSet, fPollEvt, &hStdErrR, 348 VBOXSERVICECTRLPIPEID_STDERR, &pData->stdOut); 312 349 break; 313 350 314 351 default: 315 rc = VBoxServiceControlExecProcHandleTransportEvent(hPollSet, fPollEvt, idPollHnd, &hStdInW, &StdInBuf);352 //rc = VBoxServiceControlExecProcHandleTransportEvent(hPollSet, fPollEvt, idPollHnd, &hStdInW, &pData->stdIn); 316 353 break; 317 354 } 318 355 if (RT_FAILURE(rc) || rc == VINF_EOF) 319 break; /* abort command, or client dead or something*/356 break; /* Abort command, or client dead or something. */ 320 357 continue; 321 358 } 322 323 /*324 * Check for incoming data.325 */326 359 327 360 /* … … 501 534 else 502 535 VBoxServiceError("ControlExec: Process loop failed with rc=%Rrc\n", rc); 503 RTMemFree(StdInBuf.pch);504 536 return rc; 505 537 } … … 510 542 * 511 543 * @returns IPRT status code. No client replies made. 512 * @param pszHowTo How to set up this standard handle.513 544 * @param fd Which standard handle it is (0 == stdin, 1 == 514 545 * stdout, 2 == stderr). … … 560 591 AssertPtr(pBuf); 561 592 593 /** @todo Add allocation size as function parameter! */ 562 594 pBuf->pbData = (uint8_t*)RTMemAlloc(_64K); /* Start with a 64k buffer. */ 563 595 AssertReturn(pBuf->pbData, VERR_NO_MEMORY); 596 pBuf->cbAllocated = _64K; 564 597 pBuf->cbSize = 0; 565 pBuf->cb Offset= 0;566 pBuf-> cbRead = 0;598 pBuf->cbProcessed = 0; 599 pBuf->fAlive = true; 567 600 568 601 return RTCritSectInit(&pBuf->CritSect); … … 576 609 RTMemFree(pBuf->pbData); 577 610 pBuf->pbData = NULL; 611 pBuf->cbAllocated = 0; 578 612 pBuf->cbSize = 0; 579 pBuf->cb Offset= 0;580 pBuf->cbRead = 0;581 }613 pBuf->cbProcessed = 0; 614 } 615 pBuf->fAlive = false; 582 616 return RTCritSectDelete(&pBuf->CritSect); 583 617 } … … 592 626 if (RT_SUCCESS(rc)) 593 627 { 594 Assert(pBuf->cb Offset >= pBuf->cbRead);595 if (*pcbToRead > pBuf->cb Offset - pBuf->cbRead)596 *pcbToRead = pBuf->cb Offset - pBuf->cbRead;628 Assert(pBuf->cbSize >= pBuf->cbProcessed); 629 if (*pcbToRead > pBuf->cbSize - pBuf->cbProcessed) 630 *pcbToRead = pBuf->cbSize - pBuf->cbProcessed; 597 631 598 632 if (*pcbToRead > cbBuffer) … … 601 635 if (*pcbToRead > 0) 602 636 { 603 memcpy(pbBuffer, pBuf->pbData + pBuf->cb Read, *pcbToRead);604 pBuf->cb Read += *pcbToRead;637 memcpy(pbBuffer, pBuf->pbData + pBuf->cbProcessed, *pcbToRead); 638 pBuf->cbProcessed += *pcbToRead; 605 639 } 606 640 else … … 622 656 if (RT_SUCCESS(rc)) 623 657 { 624 /** @todo Use RTMemCache or RTMemObj here? */ 625 uint8_t *pNewBuf; 626 while (pBuf->cbSize - pBuf->cbOffset < cbData) 627 { 628 pNewBuf = (uint8_t*)RTMemRealloc(pBuf->pbData, pBuf->cbSize + _4K); 629 if (pNewBuf == NULL) 630 break; 631 pBuf->cbSize += _4K; 632 pBuf->pbData = pNewBuf; 633 } 634 635 rc = VINF_SUCCESS; 636 if (pBuf->pbData) 637 { 638 memcpy(pBuf->pbData + pBuf->cbOffset, pbData, cbData); 639 pBuf->cbOffset += cbData; 640 /** @todo Add offset clamping! */ 641 } 642 else 643 rc = VERR_NO_MEMORY; 658 if (pBuf->fAlive) 659 { 660 /** @todo Buffer size limit! 4MB */ 661 662 /* Resize buffer if not enough space for storing the read in data left. */ 663 uint8_t *pNewBuf; 664 while (pBuf->cbAllocated - pBuf->cbSize < cbData) 665 { 666 pNewBuf = (uint8_t*)RTMemRealloc(pBuf->pbData, pBuf->cbAllocated + _4K); 667 if (pNewBuf == NULL) 668 break; 669 pBuf->cbAllocated += _4K; 670 pBuf->pbData = pNewBuf; 671 } 672 673 rc = VINF_SUCCESS; 674 if (pBuf->pbData) 675 { 676 memcpy(pBuf->pbData + pBuf->cbSize, pbData, cbData); 677 pBuf->cbSize += cbData; 678 /** @todo Add offset clamping! */ 679 } 680 else 681 rc = VERR_NO_MEMORY; 682 } 644 683 int rc2 = RTCritSectLeave(&pBuf->CritSect); 645 684 if (RT_SUCCESS(rc)) … … 731 770 if (RT_SUCCESS(rc)) 732 771 rc = VBoxServiceControlExecInitPipeBuffer(&pData->stdErr); 772 if (RT_SUCCESS(rc)) 773 rc = VBoxServiceControlExecInitPipeBuffer(&pData->stdIn); 733 774 } 734 775 … … 763 804 VBoxServiceControlExecDestroyPipeBuffer(&pData->stdOut); 764 805 VBoxServiceControlExecDestroyPipeBuffer(&pData->stdErr); 806 VBoxServiceControlExecDestroyPipeBuffer(&pData->stdIn); 765 807 766 808 RTMemFree(pData); … … 852 894 RTHANDLE hStdIn; 853 895 PRTHANDLE phStdIn; 854 RTPIPE hStdInW; 855 rc = VBoxServiceControlExecSetupPipe(0 /* stdin */, &hStdIn, &phStdIn, &hStdInW); 896 rc = VBoxServiceControlExecSetupPipe(0 /*STDIN_FILENO*/, &hStdIn, &phStdIn, &pData->pipeStdInW); 856 897 if (RT_SUCCESS(rc)) 857 898 { … … 859 900 PRTHANDLE phStdOut; 860 901 RTPIPE hStdOutR; 861 rc = VBoxServiceControlExecSetupPipe(1 /* stdout*/, &hStdOut, &phStdOut, &hStdOutR);902 rc = VBoxServiceControlExecSetupPipe(1 /*STDOUT_FILENO*/, &hStdOut, &phStdOut, &hStdOutR); 862 903 if (RT_SUCCESS(rc)) 863 904 { … … 865 906 PRTHANDLE phStdErr; 866 907 RTPIPE hStdErrR; 867 rc = VBoxServiceControlExecSetupPipe(2 /* stderr*/, &hStdErr, &phStdErr, &hStdErrR);908 rc = VBoxServiceControlExecSetupPipe(2 /*STDERR_FILENO*/, &hStdErr, &phStdErr, &hStdErrR); 868 909 if (RT_SUCCESS(rc)) 869 910 { … … 876 917 if (RT_SUCCESS(rc)) 877 918 { 878 rc = RTPollSetAddPipe(hPollSet, hStdInW, RTPOLL_EVT_ERROR, 0 /* TXSEXECHNDID_STDIN */);919 rc = RTPollSetAddPipe(hPollSet, pData->pipeStdInW, RTPOLL_EVT_ERROR, VBOXSERVICECTRLPIPEID_STDIN_ERROR); 879 920 if (RT_SUCCESS(rc)) 880 rc = RTPollSetAddPipe(hPollSet, hStdOutR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 1 /* TXSEXECHNDID_STDOUT */);921 rc = RTPollSetAddPipe(hPollSet, hStdOutR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, VBOXSERVICECTRLPIPEID_STDOUT); 881 922 if (RT_SUCCESS(rc)) 882 rc = RTPollSetAddPipe(hPollSet, hStdErrR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 2 /* TXSEXECHNDID_TESTPIPE */); 923 rc = RTPollSetAddPipe(hPollSet, hStdErrR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, VBOXSERVICECTRLPIPEID_STDERR); 924 if (RT_SUCCESS(rc)) 925 rc = RTPollSetAddPipe(hPollSet, pData->pipeStdInW, RTPOLL_EVT_WRITE, VBOXSERVICECTRLPIPEID_STDIN_WRITABLE); 883 926 if (RT_SUCCESS(rc)) 884 927 { … … 915 958 rc = VBoxServiceControlExecProcLoop(pThread, 916 959 hProcess, pData->uTimeLimitMS, hPollSet, 917 hStdInW, hStdOutR, hStdErrR);960 pData->pipeStdInW, hStdOutR, hStdErrR); 918 961 919 962 /* … … 924 967 */ 925 968 if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, 0 /* stdin */, NULL))) 926 hStdInW = NIL_RTPIPE;969 pData->pipeStdInW = NIL_RTPIPE; 927 970 if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, 1 /* stdout */, NULL))) 928 971 hStdOutR = NIL_RTPIPE; … … 943 986 } 944 987 } 988 RTPollSetDestroy(hPollSet); 945 989 } 946 990 RTPipeClose(hStdErrR); … … 950 994 RTHandleClose(phStdOut); 951 995 } 952 RTPipeClose( hStdInW);996 RTPipeClose(pData->pipeStdInW); 953 997 RTHandleClose(phStdIn); 954 998 } … … 968 1012 RTThreadUserSignal(RTThreadSelf()); 969 1013 return rc; 1014 } 1015 1016 PVBOXSERVICECTRLTHREAD VBoxServiceControlExecFindProcess(uint32_t uPID) 1017 { 1018 PVBOXSERVICECTRLTHREAD pNode; 1019 bool fFound = false; 1020 RTListForEach(&g_GuestControlExecThreads, pNode, VBOXSERVICECTRLTHREAD, Node) 1021 { 1022 if ( pNode->fStarted 1023 && pNode->enmType == VBoxServiceCtrlThreadDataExec) 1024 { 1025 PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData; 1026 if (pData && pData->uPID == uPID) 1027 { 1028 return pNode; 1029 } 1030 } 1031 } 1032 return NULL; 970 1033 } 971 1034 … … 1033 1096 } 1034 1097 1098 1099 /** 1100 * 1101 * 1102 * @return int 1103 * 1104 * @param u32ClientId 1105 * @param uNumParms 1106 */ 1107 int VBoxServiceControlExecHandleCmdStartProcess(uint32_t u32ClientId, uint32_t uNumParms) 1108 { 1109 uint32_t uContextID; 1110 char szCmd[_1K]; 1111 uint32_t uFlags; 1112 char szArgs[_1K]; 1113 uint32_t uNumArgs; 1114 char szEnv[_64K]; 1115 uint32_t cbEnv = sizeof(szEnv); 1116 uint32_t uNumEnvVars; 1117 char szUser[128]; 1118 char szPassword[128]; 1119 uint32_t uTimeLimitMS; 1120 1121 #if 0 /* for valgrind */ 1122 RT_ZERO(szCmd); 1123 RT_ZERO(szArgs); 1124 RT_ZERO(szEnv); 1125 RT_ZERO(szUser); 1126 RT_ZERO(szPassword); 1127 #endif 1128 1129 if (uNumParms != 11) 1130 return VERR_INVALID_PARAMETER; 1131 1132 int rc = VbglR3GuestCtrlExecGetHostCmd(u32ClientId, 1133 uNumParms, 1134 &uContextID, 1135 /* Command */ 1136 szCmd, sizeof(szCmd), 1137 /* Flags */ 1138 &uFlags, 1139 /* Arguments */ 1140 szArgs, sizeof(szArgs), &uNumArgs, 1141 /* Environment */ 1142 szEnv, &cbEnv, &uNumEnvVars, 1143 /* Credentials */ 1144 szUser, sizeof(szUser), 1145 szPassword, sizeof(szPassword), 1146 /* Timelimit */ 1147 &uTimeLimitMS); 1148 if (RT_FAILURE(rc)) 1149 { 1150 VBoxServiceError("ControlExec: Failed to retrieve exec start command! Error: %Rrc\n", rc); 1151 } 1152 else 1153 { 1154 rc = VBoxServiceControlExecProcess(uContextID, szCmd, uFlags, szArgs, uNumArgs, 1155 szEnv, cbEnv, uNumEnvVars, 1156 szUser, szPassword, uTimeLimitMS); 1157 } 1158 1159 VBoxServiceVerbose(3, "ControlExec: VBoxServiceControlExecHandleCmdStartProcess returned with %Rrc\n", rc); 1160 return rc; 1161 } 1162 1163 1164 /** 1165 * Handles input for the started process by copying the received data into its 1166 * stdin pipe. 1167 * 1168 * @return int 1169 * 1170 * @param u32ClientId 1171 * @param uNumParms 1172 */ 1173 int VBoxServiceControlExecHandleCmdSetInput(uint32_t u32ClientId, uint32_t uNumParms) 1174 { 1175 uint32_t uContextID; 1176 uint32_t uPID; 1177 uint32_t uFlags; 1178 uint8_t aBuffer[_64K]; 1179 uint32_t cbSize; 1180 1181 if (uNumParms != 5) 1182 return VERR_INVALID_PARAMETER; 1183 1184 int rc = VbglR3GuestCtrlExecGetHostCmdInput(u32ClientId, uNumParms, 1185 &uContextID, &uPID, &uFlags, 1186 aBuffer, sizeof(aBuffer), &cbSize); 1187 if (RT_FAILURE(rc)) 1188 { 1189 VBoxServiceError("ControlExec: Failed to retrieve exec input command! Error: %Rrc\n", rc); 1190 } 1191 else 1192 { 1193 PVBOXSERVICECTRLTHREAD pNode = VBoxServiceControlExecFindProcess(uPID); 1194 if (pNode) 1195 { 1196 PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData; 1197 AssertPtr(pData); 1198 rc = VBoxServiceControlExecWritePipeBuffer(&pData->stdIn, aBuffer, cbSize); 1199 if (RT_SUCCESS(rc)) 1200 { 1201 size_t cbWritten; 1202 rc = VBoxServiceControlExecProcWriteStdIn(&pData->stdIn, pData->pipeStdInW, &cbWritten); 1203 if (RT_SUCCESS(rc)) 1204 rc = VbglR3GuestCtrlExecReportStatusIn(u32ClientId, uContextID, uPID, 0 /* Flags */, 1205 cbWritten); 1206 } 1207 } 1208 else 1209 rc = VERR_NOT_FOUND; /* PID not found! */ 1210 } 1211 VBoxServiceVerbose(3, "ControlExec: VBoxServiceControlExecHandleCmdSetInput returned with %Rrc\n", rc); 1212 return rc; 1213 } 1214 1215 1216 /** 1217 * 1218 * 1219 * @return int 1220 * 1221 * @param u32ClientId 1222 * @param uNumParms 1223 */ 1224 int VBoxServiceControlExecHandleCmdGetOutput(uint32_t u32ClientId, uint32_t uNumParms) 1225 { 1226 uint32_t uContextID; 1227 uint32_t uPID; 1228 uint32_t uHandleID; 1229 uint32_t uFlags; 1230 1231 int rc = VbglR3GuestCtrlExecGetHostCmdOutput(u32ClientId, uNumParms, 1232 &uContextID, &uPID, &uHandleID, &uFlags); 1233 if (RT_FAILURE(rc)) 1234 { 1235 VBoxServiceError("ControlExec: Failed to retrieve exec output command! Error: %Rrc\n", rc); 1236 } 1237 else 1238 { 1239 PVBOXSERVICECTRLTHREAD pNode = VBoxServiceControlExecFindProcess(uPID); 1240 if (pNode) 1241 { 1242 PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData; 1243 AssertPtr(pData); 1244 1245 const uint32_t cbSize = _4K; 1246 uint32_t cbRead = cbSize; 1247 uint8_t *pBuf = (uint8_t*)RTMemAlloc(cbSize); 1248 if (pBuf) 1249 { 1250 rc = VBoxServiceControlExecReadPipeBufferContent(&pData->stdOut, pBuf, cbSize, &cbRead); 1251 if (RT_SUCCESS(rc)) 1252 { 1253 /* cbRead now contains actual size. */ 1254 rc = VbglR3GuestCtrlExecSendOut(u32ClientId, uContextID, uPID, 0 /* handle ID */, 0 /* flags */, 1255 pBuf, cbRead); 1256 } 1257 RTMemFree(pBuf); 1258 } 1259 else 1260 rc = VERR_NO_MEMORY; 1261 } 1262 else 1263 rc = VERR_NOT_FOUND; /* PID not found! */ 1264 } 1265 VBoxServiceVerbose(3, "ControlExec: VBoxServiceControlExecHandleCmdGetOutput returned with %Rrc\n", rc); 1266 return rc; 1267 } 1268
Note:
See TracChangeset
for help on using the changeset viewer.