Changeset 96820 in vbox for trunk/src/VBox/Runtime/r3/posix/process-creation-posix.cpp
- Timestamp:
- Sep 21, 2022 10:26:43 PM (2 years ago)
- svn:sync-xref-src-repo-rev:
- 153714
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/process-creation-posix.cpp
r96609 r96820 1479 1479 /* 1480 1480 * LC_ALL overrides everything else. The LC_* environment variables are often set 1481 * to the empty string so move on the next variable if that is the case. 1481 * to the empty string so move on the next variable if that is the case (that's 1482 * what setlocale in glibc does). 1482 1483 */ 1483 1484 const char *pszVar; 1484 1485 int rc = RTEnvGetEx(hEnvToUse, pszVar = "LC_ALL", szEncoding, sizeof(szEncoding), NULL); 1485 if (rc == VERR_ENV_VAR_NOT_FOUND || (RT_SUCCESS(rc) && !*szEncoding))1486 if (rc == VERR_ENV_VAR_NOT_FOUND || (RT_SUCCESS(rc) && szEncoding[0] == '\0')) 1486 1487 rc = RTEnvGetEx(hEnvToUse, pszVar = "LC_CTYPE", szEncoding, sizeof(szEncoding), NULL); 1487 if (rc == VERR_ENV_VAR_NOT_FOUND || (RT_SUCCESS(rc) && !*szEncoding))1488 if (rc == VERR_ENV_VAR_NOT_FOUND || (RT_SUCCESS(rc) && szEncoding[0] == '\0')) 1488 1489 rc = RTEnvGetEx(hEnvToUse, pszVar = "LANG", szEncoding, sizeof(szEncoding), NULL); 1489 if (RT_SUCCESS(rc) && *szEncoding)1490 if (RT_SUCCESS(rc) && szEncoding[0] != '\0') 1490 1491 { 1491 1492 /* … … 1497 1498 * e.g.: 1498 1499 * en_US.UTF-8/POSIX/el_GR.UTF-8/el_CY.UTF-8/en_GB.UTF-8/es_ES.UTF-8 1499 * N.B. On Solaris there is also a leading slash. 1500 * On Linux the composite locale format is made up of key-value pairs of category 1501 * names and locales of the form 'name=value' with each element separated by a 1502 * semicolon in the same order as above with following additional categories 1503 * included as well: 1500 * 1501 * On Solaris there is also a leading slash. 1502 * 1503 * On Linux and OS/2 the composite locale format is made up of key-value pairs 1504 * of category names and locales of the form 'name=value' with each element 1505 * separated by a semicolon in the same order as above with following additional 1506 * categories included as well: 1504 1507 * LC_PAPER/LC_NAME/LC_ADDRESS/LC_TELEPHONE/LC_MEASUREMENT/LC_IDENTIFICATION 1505 1508 * e.g. … … 1509 1512 * LC_IDENTIFICATION=fr_LU.utf8 1510 1513 */ 1511 #if !defined(RT_OS_LINUX) 1512 # if defined(RT_OS_SOLARIS) 1513 if (RTPATH_IS_SLASH(*szEncoding)) 1514 (void) memmove(szEncoding, szEncoding + 1, strlen(szEncoding)); 1515 # endif 1516 char *pszSlash = strchr(szEncoding, '/'); 1514 char *pszEncodingStart = szEncoding; 1515 #if !defined(RT_OS_LINUX) && !defined(RT_OS_OS2) 1516 if (*pszEncodingStart == '/') 1517 pszEncodingStart++; 1518 char *pszSlash = strchr(pszEncodingStart, '/'); 1517 1519 if (pszSlash) 1518 *pszSlash = '\0'; 1520 *pszSlash = '\0'; /* This ASSUMES the first one is LC_CTYPE! */ 1519 1521 #else 1520 char *pszSemicolon = strchr(szEncoding, ';'); 1521 if (pszSemicolon) 1522 { 1523 *pszSemicolon = '\0'; 1524 size_t cchPrefix = strlen("LC_CTYPE="); 1525 if (!RTStrNCmp(szEncoding, "LC_CTYPE=", cchPrefix)) 1526 (void) memmove(szEncoding, szEncoding + cchPrefix, strlen(szEncoding)); 1527 } 1528 #endif 1522 char *pszCType = strstr(pszEncodingStart, "LC_CTYPE="); 1523 if (pszCType) 1524 { 1525 pszEncodingStart = pszCType + sizeof("LC_CTYPE=") - 1; 1526 1527 char *pszSemiColon = strchr(pszEncodingStart, ';'); 1528 if (pszSemiColon) 1529 *pszSemiColon = '\0'; 1530 } 1531 #endif 1532 1529 1533 /* 1530 1534 * Use newlocale and nl_langinfo_l to determine the default codeset for the locale … … 1532 1536 * ancient days on Linux and for quite a long time on macOS, Solaris, and *BSD but 1533 1537 * to ensure their availability check that LC_CTYPE_MASK is defined. 1538 * 1539 * Note! The macOS nl_langinfo(3)/nl_langinfo_l(3) routines return a pointer to an 1540 * empty string for "short" locale names like en_NZ, it_IT, el_GR, etc. so use 1541 * UTF-8 in those cases as it is the default for short name locales on macOS 1542 * (see also rtStrGetLocaleCodeset). 1534 1543 */ 1535 1544 #ifdef LC_CTYPE_MASK 1536 locale_t hLocale = newlocale(LC_CTYPE_MASK, szEncoding, (locale_t)0);1545 locale_t hLocale = newlocale(LC_CTYPE_MASK, pszEncodingStart, (locale_t)0); 1537 1546 if (hLocale != (locale_t)0) 1538 1547 { 1539 1548 const char *pszCodeset = nl_langinfo_l(CODESET, hLocale); 1549 Log2Func(("nl_langinfo_l(CODESET, %s=%s) -> %s\n", pszVar, pszEncodingStart, pszCodeset)); 1550 if (!pszCodeset || *pszCodeset == '\0') 1540 1551 # ifdef RT_OS_DARWIN 1541 /* 1542 * The macOS nl_langinfo(3)/nl_langinfo_l(3) routines return a pointer to an 1543 * empty string for "short" locale names like en_NZ, it_IT, el_GR, etc. so 1544 * fallback to UTF-8 in those cases which is the default for short name locales 1545 * on macOS anyhow. 1546 */ 1547 if (pszCodeset && !*pszCodeset) 1548 pszCodeset = "UTF-8"; 1552 pszEncoding = "UTF-8"; 1553 # else 1554 pszEncoding = "ASCII"; 1549 1555 # endif 1550 Log2Func(("nl_langinfo_l(CODESET, %s=%s) -> %s\n", pszVar, szEncoding, pszCodeset));1551 Assert(pszCodeset && *pszCodeset != '\0');1552 1553 rc = RTStrCopy(szEncoding, sizeof(szEncoding), pszCodeset);1554 AssertRC(rc); /* cannot possibly overflow */1556 else 1557 { 1558 rc = RTStrCopy(szEncoding, sizeof(szEncoding), pszCodeset); 1559 AssertRC(rc); /* cannot possibly overflow */ 1560 } 1555 1561 1556 1562 freelocale(hLocale); … … 1560 1566 #endif 1561 1567 { 1562 /* This is mostly wrong, but I cannot think of anything better now: */ 1563 pszEncoding = rtStrGetLocaleCodeset(); 1564 LogFunc(("No newlocale or it failed (on '%s=%s', errno=%d), falling back on %s that we're using...\n", 1565 pszVar, szEncoding, errno, pszEncoding)); 1568 /* If there is something that ought to be a character set encoding, try use it: */ 1569 const char *pszDot = strchr(pszEncodingStart, '.'); 1570 if (pszDot) 1571 pszDot = RTStrStripL(pszDot + 1); 1572 if (pszDot && *pszDot != '\0') 1573 { 1574 pszEncoding = pszDot; 1575 Log2Func(("%s=%s -> %s (simple)\n", pszVar, szEncoding, pszEncoding)); 1576 } 1577 else 1578 { 1579 /* This is mostly wrong, but I cannot think of anything better now: */ 1580 pszEncoding = rtStrGetLocaleCodeset(); 1581 LogFunc(("No newlocale or it failed (on '%s=%s', errno=%d), falling back on %s that we're using...\n", 1582 pszVar, pszEncodingStart, errno, pszEncoding)); 1583 } 1566 1584 } 1567 1585 RT_NOREF_PV(pszVar);
Note:
See TracChangeset
for help on using the changeset viewer.