- Timestamp:
- Mar 23, 2018 12:41:55 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/w32/winchildren.c
r3179 r3182 607 607 608 608 /** 609 * Closes standard handles that need closing before destruction. 610 * 611 * @param pChild The child (WINCHILDTYPE_PROCESS). 612 */ 613 static void mkWinChildcareWorkerCloseStandardHandles(PWINCHILD pChild) 614 { 615 if ( pChild->u.Process.fCloseStdOut 616 && pChild->u.Process.hStdOut != INVALID_HANDLE_VALUE) 617 { 618 CloseHandle(pChild->u.Process.hStdOut); 619 pChild->u.Process.hStdOut = INVALID_HANDLE_VALUE; 620 pChild->u.Process.fCloseStdOut = FALSE; 621 } 622 if ( pChild->u.Process.fCloseStdErr 623 && pChild->u.Process.hStdErr != INVALID_HANDLE_VALUE) 624 { 625 CloseHandle(pChild->u.Process.hStdErr); 626 pChild->u.Process.hStdErr = INVALID_HANDLE_VALUE; 627 pChild->u.Process.fCloseStdErr = FALSE; 628 } 629 } 630 631 632 /** 609 633 * Does the actual process creation given. 610 634 * … … 766 790 * Close unnecessary handles. 767 791 */ 768 if ( pChild->u.Process.fCloseStdOut 769 && pChild->u.Process.hStdOut != INVALID_HANDLE_VALUE) 770 { 771 CloseHandle(pChild->u.Process.hStdOut); 772 pChild->u.Process.hStdOut = INVALID_HANDLE_VALUE; 773 pChild->u.Process.fCloseStdOut = FALSE; 774 } 775 if ( pChild->u.Process.fCloseStdErr 776 && pChild->u.Process.hStdErr != INVALID_HANDLE_VALUE) 777 { 778 CloseHandle(pChild->u.Process.hStdErr); 779 pChild->u.Process.hStdErr = INVALID_HANDLE_VALUE; 780 pChild->u.Process.fCloseStdErr = FALSE; 781 } 782 792 mkWinChildcareWorkerCloseStandardHandles(pChild); 783 793 CloseHandle(ProcInfo.hThread); 784 794 return 0; … … 1019 1029 static int mkWinChildcareWorkerConvertCommandlineWithShell(const WCHAR *pwszShell, char **papszArgs, WCHAR **ppwszCommandLine) 1020 1030 { 1021 return -2; 1031 fprintf(stderr, "%s: not found!\n", papszArgs[0]); 1032 return ERROR_FILE_NOT_FOUND; 1022 1033 } 1023 1034 … … 1025 1036 * Searches the environment block for the PATH variable. 1026 1037 * 1027 * @returns Pointer to the path in the block or "." .1038 * @returns Pointer to the path in the block or "." in pwszPathFallback. 1028 1039 * @param pwszzEnv The UTF-16 environment block to search. 1029 */ 1030 static const WCHAR *mkWinChildcareWorkerFindPathValue(const WCHAR *pwszzEnv) 1040 * @param pwszPathFallback Fallback. 1041 */ 1042 static const WCHAR *mkWinChildcareWorkerFindPathValue(const WCHAR *pwszzEnv, WCHAR pwszPathFallback[4]) 1031 1043 { 1032 1044 while (*pwszzEnv) … … 1040 1052 break; 1041 1053 } 1042 return L"."; 1054 pwszPathFallback[0] = L'.'; 1055 pwszPathFallback[1] = L'\0'; 1056 return pwszPathFallback; 1043 1057 } 1044 1058 … … 1088 1102 * @returns 0 on success, windows error code on failure. 1089 1103 * @param pszArg0 The first argument. 1090 * @param pwsz Path The path ifmkWinChildcareWorkerConvertEnvironment1091 * found it.1104 * @param pwszSearchPath In case mkWinChildcareWorkerConvertEnvironment 1105 * had a chance of locating the search path already. 1092 1106 * @param pwszzEnv The environment block, in case we need to look for 1093 1107 * the path. … … 1097 1111 * @param pfNeedShell Where to return shell vs direct execution indicator. 1098 1112 */ 1099 static int mkWinChildcareWorkerFindImage(char const *pszArg0, WCHAR const *pwszPath, WCHAR const *pwszzEnv,1113 static int mkWinChildcareWorkerFindImage(char const *pszArg0, WCHAR *pwszSearchPath, WCHAR const *pwszzEnv, 1100 1114 const char *pszShell, WCHAR **ppwszImagePath, BOOL *pfNeedShell) 1101 1115 { … … 1211 1225 else 1212 1226 { 1213 BOOL fSearchedCwd = FALSE; 1214 if (!pwszPath) 1215 pwszPath = mkWinChildcareWorkerFindPathValue(pwszzEnv); 1227 BOOL fSearchedCwd = FALSE; 1228 WCHAR wszPathFallback[4]; 1229 if (!pwszSearchPath) 1230 pwszSearchPath = (WCHAR *)mkWinChildcareWorkerFindPathValue(pwszzEnv, wszPathFallback); 1231 1216 1232 for (;;) 1217 1233 { … … 1225 1241 size_t cwcComponent = 0; 1226 1242 WCHAR wc; 1227 while ((wc = pwsz Path[cwcComponent]) != L'\0')1243 while ((wc = pwszSearchPath[cwcComponent]) != L'\0') 1228 1244 { 1229 1245 if (wc != ';' && wc != ':') … … 1231 1247 else if (wc == ';') 1232 1248 break; 1233 else if (cwcComponent != pwszPath[cwcComponent] != L'"' ? 1 : 2)1249 else if (cwcComponent != (pwszSearchPath[cwcComponent] != L'"' ? 1 : 2)) 1234 1250 break; 1235 1251 cwcComponent++; … … 1239 1255 /* Trim leading spaces and double quotes. */ 1240 1256 while ( cwcComponent > 0 1241 && ((wc = *pwsz Path) == L'"' || wc == L' ' || wc == L'\t'))1257 && ((wc = *pwszSearchPath) == L'"' || wc == L' ' || wc == L'\t')) 1242 1258 { 1243 pwsz Path++;1259 pwszSearchPath++; 1244 1260 cwcComponent--; 1245 1261 } … … 1248 1264 /* Trim trailing spaces & double quotes. */ 1249 1265 while ( cwcComponent > 0 1250 && ((wc = pwsz Path[cwcComponent - 1]) == L'"' || wc == L' ' || wc == L'\t'))1266 && ((wc = pwszSearchPath[cwcComponent - 1]) == L'"' || wc == L' ' || wc == L'\t')) 1251 1267 cwcComponent--; 1252 1268 … … 1262 1278 /* Copy the component into wszPathBuf, maybe abspath'ing it. */ 1263 1279 DWORD cwcAbsPath = 0; 1264 if ( *pwsz Path != L'\\'1265 && (pwsz Path[1] != ':' || pwszPath[2] != L'\\') )1280 if ( *pwszSearchPath != L'\\' 1281 && (pwszSearchPath[1] != ':' || pwszSearchPath[2] != L'\\') ) 1266 1282 { 1267 WCHAR const wcSaved = pwszPath[cwcCombined]; 1268 *(WCHAR *)&pwszPath[cwcCombined] = '\0'; /* Pointing to our converted buffer, so this is okay for now. */ 1269 cwcAbsPath = GetFullPathNameW(pwszPath, MKWINCHILD_MAX_PATH, wszPathBuf, NULL); 1270 *(WCHAR *)&pwszPath[cwcCombined] = wcSaved; 1283 /* To save an extra buffer + copying, we'll temporarily modify the PATH 1284 value in our converted UTF-16 environment block. */ 1285 WCHAR const wcSaved = pwszSearchPath[cwcComponent]; 1286 pwszSearchPath[cwcComponent] = L'\0'; 1287 cwcAbsPath = GetFullPathNameW(pwszSearchPath, MKWINCHILD_MAX_PATH, wszPathBuf, NULL); 1288 pwszSearchPath[cwcComponent] = wcSaved; 1271 1289 if (cwcAbsPath > 0 && cwcAbsPath + 1 + cwcArg0 <= MKWINCHILD_MAX_PATH) 1272 1290 cwcCombined = cwcAbsPath + 1 + cwcArg0; … … 1276 1294 if (cwcAbsPath == 0) 1277 1295 { 1278 memcpy(wszPathBuf, pwsz Path, cwcComponent);1296 memcpy(wszPathBuf, pwszSearchPath, cwcComponent * sizeof(WCHAR)); 1279 1297 cwcAbsPath = cwcComponent; 1280 1298 } … … 1338 1356 */ 1339 1357 if (wcEnd != '\0') 1340 pwsz Path += cwcSkip + 1;1358 pwszSearchPath += cwcSkip + 1; 1341 1359 else if (fSearchedCwd) 1342 1360 break; … … 1344 1362 { 1345 1363 fSearchedCwd = TRUE; 1346 pwszPath = L"."; 1364 wszPathFallback[0] = L'.'; 1365 wszPathFallback[1] = L'\0'; 1366 pwszSearchPath = wszPathFallback; 1347 1367 } 1348 1368 } … … 1354 1374 */ 1355 1375 *pfNeedShell = TRUE; 1356 cwc = MultiByteToWideChar(CP_ACP, 0 /*fFlags*/, pszShell, strlen(pszShell), wszPathBuf, MKWINCHILD_MAX_PATH); 1357 if (cwc > 0) 1358 return mkWinChildDuplicateUtf16String(wszPathBuf, cwc, ppwszImagePath); 1359 dwErr = GetLastError(); 1376 if (pszShell) 1377 { 1378 cwc = MultiByteToWideChar(CP_ACP, 0 /*fFlags*/, pszShell, strlen(pszShell) + 1, wszPathBuf, MKWINCHILD_MAX_PATH); 1379 if (cwc > 0) 1380 return mkWinChildDuplicateUtf16String(wszPathBuf, cwc, ppwszImagePath); 1381 dwErr = GetLastError(); 1382 fprintf(stderr, _("MultiByteToWideChar failed to convert shell (%s): %u\n"), pszShell, dwErr); 1383 } 1384 else 1385 { 1386 fprintf(stderr, "%s: not found!\n", pszArg0); 1387 dwErr = ERROR_FILE_NOT_FOUND; 1388 } 1360 1389 } 1361 1390 else … … 1376 1405 * @param ppwszEnv Where to return the pointer to the environment 1377 1406 * block. 1378 * @param ppwsz Path Where to return the pointer to the path value within1379 * the environment block. This will not be set if1380 * cbEnvStrings is non-zero, more efficient to let1407 * @param ppwszSearchPath Where to return the pointer to the path value 1408 * within the environment block. This will not be set 1409 * if cbEnvStrings is non-zero, more efficient to let 1381 1410 * mkWinChildcareWorkerFindImage() search when needed. 1382 1411 */ 1383 1412 static int mkWinChildcareWorkerConvertEnvironment(char **papszEnv, size_t cbEnvStrings, 1384 WCHAR **ppwszEnv, WCHAR const **ppwsz Path)1413 WCHAR **ppwszEnv, WCHAR const **ppwszSearchPath) 1385 1414 { 1386 1415 DWORD dwErr; … … 1389 1418 WCHAR *pwszzDst; 1390 1419 1391 *ppwsz Path = NULL;1420 *ppwszSearchPath = NULL; 1392 1421 1393 1422 /* … … 1519 1548 1520 1549 if (offPathValue != ~(size_t)0) 1521 *ppwsz Path = &pwszzDst[offPathValue];1550 *ppwszSearchPath = &pwszzDst[offPathValue]; 1522 1551 *ppwszEnv = pwszzDst; 1523 1552 return 0; … … 1535 1564 static void mkWinChildcareWorkerThreadHandleProcess(PWINCHILDCAREWORKER pWorker, PWINCHILD pChild) 1536 1565 { 1537 WCHAR const *pwszPath= NULL;1538 WCHAR 1539 WCHAR 1540 WCHAR 1541 BOOL 1542 int 1566 WCHAR *pwszSearchPath = NULL; 1567 WCHAR *pwszzEnvironment = NULL; 1568 WCHAR *pwszCommandLine = NULL; 1569 WCHAR *pwszImageName = NULL; 1570 BOOL fNeedShell = FALSE; 1571 int rc; 1543 1572 1544 1573 /* … … 1548 1577 rc = mkWinChildcareWorkerConvertEnvironment(pChild->u.Process.papszEnv ? pChild->u.Process.papszEnv : environ, 1549 1578 pChild->u.Process.cbEnvStrings, 1550 &pwszzEnvironment, &pwsz Path);1579 &pwszzEnvironment, &pwszSearchPath); 1551 1580 /* 1552 1581 * Find the executable and maybe checking if it's a shell script, then … … 1554 1583 */ 1555 1584 if (rc == 0) 1556 rc = mkWinChildcareWorkerFindImage(pChild->u.Process.papszArgs[0], pwsz zEnvironment, pwszPath,1585 rc = mkWinChildcareWorkerFindImage(pChild->u.Process.papszArgs[0], pwszSearchPath, pwszzEnvironment, 1557 1586 pChild->u.Process.pszShell, &pwszImageName, &fNeedShell); 1558 1587 if (rc == 0) … … 1587 1616 free(pwszImageName); 1588 1617 free(pwszzEnvironment); 1618 1619 /* In case we failed, we must make sure the child end of pipes 1620 used by $(shell no_such_command.exe) are closed, otherwise 1621 the main thread will be stuck reading the parent end. */ 1622 mkWinChildcareWorkerCloseStandardHandles(pChild); 1589 1623 } 1590 1624 … … 1954 1988 pChild->u.Process.hProcess = NULL; 1955 1989 } 1956 if ( pChild->u.Process.fCloseStdOut 1957 && pChild->u.Process.hStdOut != INVALID_HANDLE_VALUE) 1958 { 1959 CloseHandle(pChild->u.Process.hStdOut); 1960 pChild->u.Process.hStdOut = INVALID_HANDLE_VALUE; 1961 pChild->u.Process.fCloseStdOut = FALSE; 1962 } 1963 if ( pChild->u.Process.fCloseStdErr 1964 && pChild->u.Process.hStdErr != INVALID_HANDLE_VALUE) 1965 { 1966 CloseHandle(pChild->u.Process.hStdErr); 1967 pChild->u.Process.hStdErr = INVALID_HANDLE_VALUE; 1968 pChild->u.Process.fCloseStdErr = FALSE; 1969 } 1990 mkWinChildcareWorkerCloseStandardHandles(pChild); 1970 1991 break; 1971 1992 }
Note:
See TracChangeset
for help on using the changeset viewer.