Changeset 28119 in vbox for trunk/src/VBox/Additions/common
- Timestamp:
- Apr 9, 2010 7:54:19 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 59837
- Location:
- trunk/src/VBox/Additions/common/VBoxService
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
r28086 r28119 96 96 static int VBoxServiceControlHandleCmdExec(uint32_t u32ClientId, uint32_t uNumParms) 97 97 { 98 VBOXSERVICECTRLPROCDATA execData; 99 execData.cbEnv = sizeof(execData.szEnv); 98 char szCmd[_1K]; 99 uint32_t uFlags; 100 char szArgs[_1K]; 101 uint32_t uNumArgs; 102 char szEnv[_64K]; 103 uint32_t cbEnv = sizeof(szEnv); 104 uint32_t uNumEnvVars; 105 char szStdIn[_1K]; 106 char szStdOut[_1K]; 107 char szStdErr[_1K]; 108 char szUser[128]; 109 char szPassword[128]; 110 uint32_t uTimeLimitMS; 100 111 101 112 int rc = VbglR3GuestCtrlGetHostCmdExec(u32ClientId, uNumParms, 102 execData.szCmd, sizeof(execData.szCmd), 103 &execData.uFlags, 104 execData.szArgs, sizeof(execData.szArgs), &execData.uNumArgs, 105 execData.szEnv, &execData.cbEnv, &execData.uNumEnvVars, 106 execData.szStdIn, sizeof(execData.szStdIn), 107 execData.szStdOut, sizeof(execData.szStdOut), 108 execData.szStdErr, sizeof(execData.szStdErr), 109 execData.szUser, sizeof(execData.szUser), 110 execData.szPassword, sizeof(execData.szPassword), 111 &execData.uTimeLimitMS); 113 /* Command */ 114 szCmd, sizeof(szCmd), 115 /* Flags */ 116 &uFlags, 117 /* Arguments */ 118 szArgs, sizeof(szArgs), &uNumArgs, 119 /* Environment */ 120 szEnv, &cbEnv, &uNumEnvVars, 121 /* Pipes */ 122 szStdIn, sizeof(szStdIn), 123 szStdOut, sizeof(szStdOut), 124 szStdErr, sizeof(szStdErr), 125 /* Credentials */ 126 szUser, sizeof(szUser), 127 szPassword, sizeof(szPassword), 128 /* Timelimit */ 129 &uTimeLimitMS); 112 130 if (RT_FAILURE(rc)) 113 131 { … … 115 133 } 116 134 else 117 { 118 /* Adjust time limit value. */ 119 execData.uTimeLimitMS = UINT32_MAX ? 120 RT_INDEFINITE_WAIT : execData.uTimeLimitMS; 121 122 /* Prepare argument list. */ 123 char **ppaArg; 124 int iArgs; 125 rc = RTGetOptArgvFromString(&ppaArg, &iArgs, 126 execData.uNumArgs ? execData.szArgs : "", NULL); 127 Assert(execData.uNumArgs == iArgs); 128 if (RT_SUCCESS(rc)) 129 { 130 /* Prepare environment list. */ 131 char **ppaEnv; 132 if (execData.uNumEnvVars) 133 { 134 ppaEnv = (char**)RTMemAlloc(execData.uNumEnvVars * sizeof(char*)); 135 AssertPtr(ppaEnv); 136 137 char *pcCur = execData.szEnv; 138 uint32_t i = 0; 139 uint32_t cbLen = 0; 140 while (cbLen < execData.cbEnv) 141 { 142 if (RTStrAPrintf(&ppaEnv[i++], "%s", pcCur) < 0) 143 { 144 rc = VERR_NO_MEMORY; 145 break; 146 } 147 cbLen += strlen(pcCur) + 1; /* Skip terminating zero. */ 148 pcCur += cbLen; 149 } 150 } 151 152 if (RT_SUCCESS(rc)) 153 { 154 /* Do the actual execution. */ 155 rc = VBoxServiceControlExecProcess(&execData, ppaArg, ppaEnv); 156 if (RT_FAILURE(rc)) 157 VBoxServiceVerbose(3, "Control: Could not execute process \"%s\"! Error: %Rrc\n", 158 execData.szCmd, rc); 159 /* Cleanup. */ 160 if (execData.uNumEnvVars) 161 { 162 for (uint32_t i = 0; i < execData.uNumEnvVars; i++) 163 RTStrFree(ppaEnv[i]); 164 RTMemFree(ppaEnv); 165 } 166 } 167 RTGetOptArgvFree(ppaArg); 168 } 135 { 136 rc = VBoxServiceControlExecProcess(szCmd, uFlags, szArgs, uNumArgs, 137 szEnv, cbEnv, uNumEnvVars, 138 szStdIn, szStdOut, szStdErr, 139 szUser, szPassword, uTimeLimitMS); 169 140 } 170 141 return rc; -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
r28029 r28119 499 499 } 500 500 501 int VBoxServiceControlExecProcess(PVBOXSERVICECTRLPROCDATA pExecData, 502 const char * const *papszArgs, 503 const char * const *papszEnv) 504 { 505 AssertPtr(pExecData); 501 /** Allocates and gives back a thread data struct which then can be used by the worker thread. */ 502 PVBOXSERVICECTRLTHREADDATA VBoxServiceControlExecAllocateThreadData(const char *pszCmd, uint32_t uFlags, 503 const char *pszArgs, uint32_t uNumArgs, 504 const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars, 505 const char *pszStdIn, const char *pszStdOut, const char *pszStdErr, 506 const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS) 507 { 508 PVBOXSERVICECTRLTHREADDATA pData = (PVBOXSERVICECTRLTHREADDATA)RTMemAlloc(sizeof(VBOXSERVICECTRLTHREADDATA)); 509 if (pData == NULL) 510 return NULL; 511 512 pData->pszCmd = RTStrDup(pszCmd); 513 pData->uFlags = uFlags; 514 515 /* Prepare argument list. */ 516 int rc = RTGetOptArgvFromString(&pData->papszArgs, (int*)&pData->uNumArgs, 517 pszArgs ? pszArgs : "", NULL); 518 Assert(uNumArgs == pData->uNumArgs); 519 if (RT_SUCCESS(rc)) 520 { 521 /* Prepare environment list. */ 522 if (uNumEnvVars) 523 { 524 pData->papszEnv = (char**)RTMemAlloc(uNumEnvVars * sizeof(char*)); 525 AssertPtr(pData->papszEnv); 526 pData->uNumEnvVars = uNumEnvVars; 527 528 const char *pcCur = pszEnv; 529 uint32_t i = 0; 530 uint32_t cbLen = 0; 531 while (cbLen < cbEnv) 532 { 533 if (RTStrAPrintf(& pData->papszEnv[i++], "%s", pcCur) < 0) 534 { 535 rc = VERR_NO_MEMORY; 536 break; 537 } 538 cbLen += strlen(pcCur) + 1; /* Skip terminating zero. */ 539 pcCur += cbLen; 540 } 541 } 542 543 pData->pszStdIn = RTStrDup(pszStdIn); 544 pData->pszStdOut = RTStrDup(pszStdOut); 545 pData->pszStdErr = RTStrDup(pszStdErr); 546 pData->pszUser = RTStrDup(pszUser); 547 pData->pszPassword = RTStrDup(pszPassword); 548 pData->uTimeLimitMS = uTimeLimitMS; 549 } 550 551 /* Adjust time limit value. */ 552 pData->uTimeLimitMS = ( (uTimeLimitMS == UINT32_MAX) 553 || (uTimeLimitMS == 0)) ? 554 RT_INDEFINITE_WAIT : uTimeLimitMS; 555 return pData; 556 } 557 558 /** Frees an allocated thread data structure along with all its allocated parameters. */ 559 void VBoxServiceControlExecFreeThreadData(PVBOXSERVICECTRLTHREADDATA pData) 560 { 561 AssertPtr(pData); 562 RTStrFree(pData->pszCmd); 563 if (pData->uNumEnvVars) 564 { 565 for (uint32_t i = 0; i < pData->uNumEnvVars; i++) 566 RTStrFree(pData->papszEnv[i]); 567 RTMemFree(pData->papszEnv); 568 } 569 RTGetOptArgvFree(pData->papszArgs); 570 RTStrFree(pData->pszStdIn); 571 RTStrFree(pData->pszStdOut); 572 RTStrFree(pData->pszStdErr); 573 RTStrFree(pData->pszUser); 574 RTStrFree(pData->pszPassword); 575 576 RTMemFree(pData); 577 } 578 579 DECLCALLBACK(int) VBoxServiceControlExecProcessWorker(PVBOXSERVICECTRLTHREADDATA pData) 580 { 581 AssertPtr(pData); 582 AssertPtr(pData->papszArgs); 583 AssertPtr(pData->papszEnv); 584 585 /* 586 * Tell the control thread that it can continue 587 * spawning services. 588 */ 589 RTThreadUserSignal(RTThreadSelf()); 590 VBoxServiceVerbose(3, "Control: Thread of process \"%s\" started.", pData->pszCmd); 506 591 507 592 /* … … 513 598 { 514 599 size_t i; 515 for (i = 0; i < p ExecData->uNumEnvVars; i++)516 { 517 rc = RTEnvPutEx(hEnv, p apszEnv[i]);600 for (i = 0; i < pData->uNumEnvVars; i++) 601 { 602 rc = RTEnvPutEx(hEnv, pData->papszEnv[i]); 518 603 if (RT_FAILURE(rc)) 519 604 break; … … 559 644 { 560 645 RTPROCESS hProcess; 561 rc = RTProcCreateEx(p ExecData->szCmd, papszArgs, hEnv, 0 /*fFlags*/,646 rc = RTProcCreateEx(pData->pszCmd, pData->papszArgs, hEnv, pData->uFlags, 562 647 phStdIn, phStdOut, phStdErr, 563 648 /*pszUsername, pszPassword,*/ NULL, NULL, … … 565 650 if (RT_SUCCESS(rc)) 566 651 { 652 VBoxServiceVerbose(3, "Control: Process \"%s\" started.\n", pData->pszCmd); 653 /** @todo Dump a bit more info here. */ 654 567 655 /* 568 656 * Close the child ends of any pipes and redirected files. … … 575 663 phStdErr = NULL; 576 664 577 rc = VBoxServiceControlExecProcLoop(hProcess, p ExecData->uTimeLimitMS, hPollSet,665 rc = VBoxServiceControlExecProcLoop(hProcess, pData->uTimeLimitMS, hPollSet, 578 666 hStdInW, hStdOutR, hStdErrR); 579 667 /* … … 604 692 RTEnvDestroy(hEnv); 605 693 } 694 695 VBoxServiceVerbose(3, "Control: Thread of process \"%s\" ended with rc=%Rrc.\n", pData->pszCmd, rc); 696 697 /* 698 * Since we (hopefully) are the one ones that hold the thread data, 699 * destroy them now. 700 */ 701 VBoxServiceControlExecFreeThreadData(pData); 606 702 return rc; 607 703 } 608 704 705 static DECLCALLBACK(int) VBoxServiceControlExecThread(RTTHREAD ThreadSelf, void *pvUser) 706 { 707 PVBOXSERVICECTRLTHREADDATA pData = (PVBOXSERVICECTRLTHREADDATA)pvUser; 708 return VBoxServiceControlExecProcessWorker(pData); 709 } 710 711 int VBoxServiceControlExecProcess(const char *pszCmd, uint32_t uFlags, 712 const char *pszArgs, uint32_t uNumArgs, 713 const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars, 714 const char *pszStdIn, const char *pszStdOut, const char *pszStdErr, 715 const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS) 716 { 717 PVBOXSERVICECTRLTHREADDATA pThreadData = 718 VBoxServiceControlExecAllocateThreadData(pszCmd, uFlags, 719 pszArgs, uNumArgs, 720 pszEnv, cbEnv, uNumEnvVars, 721 pszStdIn, pszStdOut, pszStdErr, 722 pszUser, pszPassword, 723 uTimeLimitMS); 724 int rc = VINF_SUCCESS; 725 if (pThreadData) 726 { 727 rc = RTThreadCreate(NULL, VBoxServiceControlExecThread, 728 (void *)(PVBOXSERVICECTRLTHREADDATA)pThreadData, 0, 729 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "Exec"); 730 if (RT_FAILURE(rc)) 731 { 732 VBoxServiceError("Control: RTThreadCreate failed, rc=%Rrc\n, threadData=%p", 733 rc, pThreadData); 734 VBoxServiceControlExecFreeThreadData(pThreadData); 735 } 736 } 737 else 738 rc = VERR_NO_MEMORY; 739 return rc; 740 } 741 -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
r27972 r28119 126 126 127 127 #ifdef VBOX_WITH_GUEST_CONTROL 128 /* Structure for holding process executiondata. */129 typedef struct _VBoxServiceControlProcessData130 { 131 char szCmd[_1K];132 uint32_t uFlags;133 char szArgs[_1K];134 uint32_t uNumArgs;135 char szEnv[_64K];136 uint32_t cbEnv;137 uint32_t uNumEnvVars;138 char szStdIn[_1K];139 char szStdOut[_1K];140 char szStdErr[_1K];141 char szUser[128];142 char szPassword[128];143 uint32_t uTimeLimitMS;144 } VBOXSERVICECTRLPROCDATA; 145 /** Pointer to execution data. */ 146 typedef VBOXSERVICECTRLPROCDATA *PVBOXSERVICECTRLPROCDATA; 128 /* Structure for holding thread relevant data. */ 129 typedef struct 130 { 131 char *pszCmd; 132 uint32_t uFlags; 133 char **papszArgs; 134 uint32_t uNumArgs; 135 char **papszEnv; 136 uint32_t uNumEnvVars; 137 char *pszStdIn; 138 char *pszStdOut; 139 char *pszStdErr; 140 char *pszUser; 141 char *pszPassword; 142 uint32_t uTimeLimitMS; 143 } VBOXSERVICECTRLTHREADDATA; 144 /** Pointer to thread data. */ 145 typedef VBOXSERVICECTRLTHREADDATA *PVBOXSERVICECTRLTHREADDATA; 146 147 147 /** 148 148 * For buffering process input supplied by the client. 149 149 */ 150 typedef struct _VBoxServiceControlStdInBuf150 typedef struct 151 151 { 152 152 /** The mount of buffered data. */ … … 210 210 211 211 #ifdef VBOX_WITH_GUEST_CONTROL 212 extern int VBoxServiceControlExecProcess(PVBOXSERVICECTRLPROCDATA pExecData, 213 const char * const *papszArgs, 214 const char * const *papszEnv); 212 extern int VBoxServiceControlExecProcess(const char *pszCmd, uint32_t uFlags, 213 const char *pszArgs, uint32_t uNumArgs, 214 const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars, 215 const char *pszStdIn, const char *pszStdOut, const char *pszStdErr, 216 const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS); 215 217 #endif 216 218
Note:
See TracChangeset
for help on using the changeset viewer.