Changeset 55562 in vbox for trunk/src/VBox/Runtime/generic
- Timestamp:
- Apr 30, 2015 3:15:15 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/generic/env-generic.cpp
r50644 r55562 89 89 /** Magic value . */ 90 90 uint32_t u32Magic; 91 /** Set if this is a record of environment changes, putenv style. */ 92 bool fPutEnvBlock; 91 93 /** Number of variables in the array. 92 94 * This does not include the terminating NULL entry. */ … … 96 98 * with the C library), so that c <= cCapacity - 1. */ 97 99 size_t cAllocated; 98 /** Array of environment variables. */ 100 /** Array of environment variables. 101 * These are always in "NAME=VALUE" form, where the value can be empty. If 102 * fPutEnvBlock is set though, there will be "NAME" entries too for variables 103 * that need to be removed when merged with another environment block. */ 99 104 char **papszEnv; 100 105 /** Array of environment variables in the process CP. … … 132 137 * @param fCaseSensitive Whether the environment block is case sensitive or 133 138 * not. 139 * @param fPutEnvBlock Indicates whether this is a special environment 140 * block that will be used to record change another 141 * block. We will keep unsets in putenv format, i.e. 142 * just the variable name without any equal sign. 134 143 */ 135 static int rtEnvCreate(PRTENVINTERNAL *ppIntEnv, size_t cAllocated, bool fCaseSensitive )144 static int rtEnvCreate(PRTENVINTERNAL *ppIntEnv, size_t cAllocated, bool fCaseSensitive, bool fPutEnvBlock) 136 145 { 137 146 /* … … 145 154 */ 146 155 pIntEnv->u32Magic = RTENV_MAGIC; 156 pIntEnv->fPutEnvBlock = fPutEnvBlock; 147 157 pIntEnv->pfnCompare = fCaseSensitive ? RTStrNCmp : RTStrNICmp; 148 158 pIntEnv->papszEnvOtherCP = NULL; … … 166 176 { 167 177 AssertPtrReturn(pEnv, VERR_INVALID_POINTER); 168 return rtEnvCreate(pEnv, RTENV_GROW_SIZE, false /*fCaseSensitive*/ );178 return rtEnvCreate(pEnv, RTENV_GROW_SIZE, false /*fCaseSensitive*/, false /*fPutEnvBlock*/); 169 179 } 170 180 RT_EXPORT_SYMBOL(RTEnvCreate); … … 221 231 */ 222 232 bool fCaseSensitive = true; 233 bool fPutEnvBlock = false; 223 234 size_t cVars; 224 235 const char * const *papszEnv; … … 263 274 RTENV_LOCK(pIntEnvToClone); 264 275 276 fPutEnvBlock = pIntEnvToClone->fPutEnvBlock; 265 277 papszEnv = pIntEnvToClone->papszEnv; 266 278 cVars = pIntEnvToClone->cVars; … … 271 283 */ 272 284 PRTENVINTERNAL pIntEnv; 273 int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive );285 int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive, fPutEnvBlock); 274 286 if (RT_SUCCESS(rc)) 275 287 { … … 288 300 #endif 289 301 if (RT_SUCCESS(rc2)) 302 { 303 /* Make sure it contains an '='. */ 290 304 iDst++; 305 if (strchr(pIntEnv->papszEnv[iDst - 1], '=')) 306 continue; 307 rc2 = RTStrAAppend(&pIntEnv->papszEnv[iDst - 1], "="); 308 if (RT_SUCCESS(rc2)) 309 continue; 310 } 291 311 else if (rc2 == VERR_NO_TRANSLATION) 312 { 292 313 rc = VWRN_ENV_NOT_FULLY_TRANSLATED; 293 else 294 { 295 pIntEnv->cVars = iDst; 296 RTEnvDestroy(pIntEnv); 297 return rc2; 298 } 314 continue; 315 } 316 317 /* failed fatally. */ 318 pIntEnv->cVars = iDst; 319 RTEnvDestroy(pIntEnv); 320 return rc2; 299 321 } 300 322 pIntEnv->cVars = iDst; … … 361 383 AssertReturn(*pszVar, VERR_INVALID_PARAMETER); 362 384 AssertPtrReturn(pszValue, VERR_INVALID_POINTER); 385 AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME); 363 386 364 387 int rc; … … 415 438 for (iVar = 0; iVar < pIntEnv->cVars; iVar++) 416 439 if ( !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar) 417 && pIntEnv->papszEnv[iVar][cchVar] == '=') 440 && ( pIntEnv->papszEnv[iVar][cchVar] == '=' 441 || pIntEnv->papszEnv[iVar][cchVar] == '\0') ) 418 442 break; 419 443 if (iVar < pIntEnv->cVars) … … 470 494 AssertPtrReturn(pszVar, VERR_INVALID_POINTER); 471 495 AssertReturn(*pszVar, VERR_INVALID_PARAMETER); 496 AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME); 472 497 473 498 int rc; … … 507 532 for (iVar = 0; iVar < pIntEnv->cVars; iVar++) 508 533 if ( !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar) 509 && pIntEnv->papszEnv[iVar][cchVar] == '=') 510 { 511 RTMemFree(pIntEnv->papszEnv[iVar]); 512 pIntEnv->cVars--; 513 if (pIntEnv->cVars > 0) 514 pIntEnv->papszEnv[iVar] = pIntEnv->papszEnv[pIntEnv->cVars]; 515 pIntEnv->papszEnv[pIntEnv->cVars] = NULL; 534 && ( pIntEnv->papszEnv[iVar][cchVar] == '=' 535 || pIntEnv->papszEnv[iVar][cchVar] == '\0') ) 536 { 537 if (!pIntEnv->fPutEnvBlock) 538 { 539 RTMemFree(pIntEnv->papszEnv[iVar]); 540 pIntEnv->cVars--; 541 if (pIntEnv->cVars > 0) 542 pIntEnv->papszEnv[iVar] = pIntEnv->papszEnv[pIntEnv->cVars]; 543 pIntEnv->papszEnv[pIntEnv->cVars] = NULL; 544 } 545 else 546 { 547 /* Record this unset by keeping the variable without any equal sign. */ 548 pIntEnv->papszEnv[iVar][cchVar] = '\0'; 549 } 516 550 rc = VINF_SUCCESS; 517 551 /* no break, there could be more. */ … … 532 566 AssertPtrNullReturn(pcchActual, VERR_INVALID_POINTER); 533 567 AssertReturn(pcchActual || (pszValue && cbValue), VERR_INVALID_PARAMETER); 568 AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME); 534 569 535 570 if (pcchActual) … … 592 627 size_t iVar; 593 628 for (iVar = 0; iVar < pIntEnv->cVars; iVar++) 594 if ( !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar) 595 && pIntEnv->papszEnv[iVar][cchVar] == '=') 596 { 597 rc = VINF_SUCCESS; 598 const char *pszValueOrg = pIntEnv->papszEnv[iVar] + cchVar + 1; 599 size_t cch = strlen(pszValueOrg); 600 if (pcchActual) 601 *pcchActual = cch; 602 if (pszValue && cbValue) 603 { 604 if (cch < cbValue) 605 memcpy(pszValue, pszValueOrg, cch + 1); 606 else 607 rc = VERR_BUFFER_OVERFLOW; 608 } 609 break; 629 if (!pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)) 630 { 631 if (pIntEnv->papszEnv[iVar][cchVar] == '=') 632 { 633 rc = VINF_SUCCESS; 634 const char *pszValueOrg = pIntEnv->papszEnv[iVar] + cchVar + 1; 635 size_t cch = strlen(pszValueOrg); 636 if (pcchActual) 637 *pcchActual = cch; 638 if (pszValue && cbValue) 639 { 640 if (cch < cbValue) 641 memcpy(pszValue, pszValueOrg, cch + 1); 642 else 643 rc = VERR_BUFFER_OVERFLOW; 644 } 645 break; 646 } 647 if (pIntEnv->papszEnv[iVar][cchVar] == '\0') 648 { 649 Assert(pIntEnv->fPutEnvBlock); 650 rc = VERR_ENV_VAR_UNSET; 651 break; 652 } 610 653 } 611 654 … … 654 697 const size_t cchVar = strlen(pszVar); 655 698 for (size_t iVar = 0; iVar < pIntEnv->cVars; iVar++) 656 if ( !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar) 657 && pIntEnv->papszEnv[iVar][cchVar] == '=') 658 { 659 fExists = true; 660 break; 699 if (!pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)) 700 { 701 if (pIntEnv->papszEnv[iVar][cchVar] == '=') 702 { 703 fExists = true; 704 break; 705 } 706 if (pIntEnv->papszEnv[iVar][cchVar] == '\0') 707 break; 661 708 } 662 709 … … 740 787 * @param pvUser Ignored. 741 788 */ 742 DECLCALLBACK(int) rtEnvSortCompare(const void *pvElement1, const void *pvElement2, void *pvUser)789 static DECLCALLBACK(int) rtEnvSortCompare(const void *pvElement1, const void *pvElement2, void *pvUser) 743 790 { 744 791 NOREF(pvUser); … … 863 910 864 911 865 RTDECL( uint32_t) RTEnvGetByIndexEx(RTENV hEnv, uint32_t iVar, char *pszVar, size_t cbVar, char *pszValue, size_t cbValue)912 RTDECL(int) RTEnvGetByIndexEx(RTENV hEnv, uint32_t iVar, char *pszVar, size_t cbVar, char *pszValue, size_t cbValue) 866 913 { 867 914 PRTENVINTERNAL pIntEnv = hEnv; … … 882 929 bool fHasEqual = pszSrcValue != NULL; 883 930 if (pszSrcValue) 931 { 884 932 pszSrcValue++; 933 rc = VINF_SUCCESS; 934 } 885 935 else 936 { 886 937 pszSrcValue = strchr(pszSrcVar, '\0'); 887 rc = VINF_SUCCESS; 938 rc = VINF_ENV_VAR_UNSET; 939 } 888 940 if (cbVar) 889 rc = RTStrCopyEx(pszVar, cbVar, pszSrcVar, pszSrcValue - pszSrcVar - fHasEqual); 941 { 942 int rc2 = RTStrCopyEx(pszVar, cbVar, pszSrcVar, pszSrcValue - pszSrcVar - fHasEqual); 943 if (RT_FAILURE(rc2)) 944 rc = rc2; 945 } 890 946 if (cbValue) 891 947 { … … 904 960 RT_EXPORT_SYMBOL(RTEnvGetByIndexEx); 905 961 962 963 RTDECL(const char *) RTEnvGetByIndexRawEx(RTENV hEnv, uint32_t iVar) 964 { 965 PRTENVINTERNAL pIntEnv = hEnv; 966 AssertPtrReturn(pIntEnv, NULL); 967 AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, NULL); 968 969 RTENV_LOCK(pIntEnv); 970 971 const char *pszRet; 972 if (iVar < pIntEnv->cVars) 973 pszRet = pIntEnv->papszEnv[iVar]; 974 else 975 pszRet = NULL; 976 977 RTENV_UNLOCK(pIntEnv); 978 979 return pszRet; 980 } 981 RT_EXPORT_SYMBOL(RTEnvGetByIndexRawEx); 982 983 984 RTDECL(int) RTEnvCreateChangeRecord(PRTENV phEnv) 985 { 986 AssertPtrReturn(phEnv, VERR_INVALID_POINTER); 987 return rtEnvCreate(phEnv, RTENV_GROW_SIZE, false /*fCaseSensitive*/, true /*fPutEnvBlock*/); 988 } 989 RT_EXPORT_SYMBOL(RTEnvCreateChangeRecord); 990 991 992 RTDECL(bool) RTEnvIsChangeRecord(RTENV hEnv) 993 { 994 if (hEnv == RTENV_DEFAULT) 995 return false; 996 997 PRTENVINTERNAL pIntEnv = hEnv; 998 AssertPtrReturn(pIntEnv, false); 999 AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, false); 1000 return pIntEnv->fPutEnvBlock; 1001 } 1002 RT_EXPORT_SYMBOL(RTEnvIsChangeRecord); 1003 1004 1005 RTDECL(int) RTEnvApplyChanges(RTENV hEnvDst, RTENV hEnvChanges) 1006 { 1007 PRTENVINTERNAL pIntEnvChanges = hEnvChanges; 1008 AssertPtrReturn(pIntEnvChanges, VERR_INVALID_HANDLE); 1009 AssertReturn(pIntEnvChanges->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE); 1010 1011 /** @todo lock validator trouble ahead here! */ 1012 RTENV_LOCK(pIntEnvChanges); 1013 1014 int rc = VINF_SUCCESS; 1015 for (uint32_t iChange = 0; iChange < pIntEnvChanges->cVars && RT_SUCCESS(rc); iChange++) 1016 rc = RTEnvPutEx(hEnvDst, pIntEnvChanges->papszEnv[iChange]); 1017 1018 RTENV_UNLOCK(pIntEnvChanges); 1019 1020 return rc; 1021 } 1022 RT_EXPORT_SYMBOL(RTEnvApplyChanges); 1023
Note:
See TracChangeset
for help on using the changeset viewer.