VirtualBox

Changeset 3182 in kBuild for trunk


Ignore:
Timestamp:
Mar 23, 2018 12:41:55 AM (7 years ago)
Author:
bird
Message:

kmk/winchildren: PATH searching fixes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/w32/winchildren.c

    r3179 r3182  
    607607
    608608/**
     609 * Closes standard handles that need closing before destruction.
     610 *
     611 * @param   pChild          The child (WINCHILDTYPE_PROCESS).
     612 */
     613static 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/**
    609633 * Does the actual process creation given.
    610634 *
     
    766790     * Close unnecessary handles.
    767791     */
    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);
    783793    CloseHandle(ProcInfo.hThread);
    784794    return 0;
     
    10191029static int mkWinChildcareWorkerConvertCommandlineWithShell(const WCHAR *pwszShell, char **papszArgs, WCHAR **ppwszCommandLine)
    10201030{
    1021     return -2;
     1031    fprintf(stderr, "%s: not found!\n", papszArgs[0]);
     1032    return ERROR_FILE_NOT_FOUND;
    10221033}
    10231034
     
    10251036 * Searches the environment block for the PATH variable.
    10261037 *
    1027  * @returns Pointer to the path in the block or ".".
     1038 * @returns Pointer to the path in the block or "." in pwszPathFallback.
    10281039 * @param   pwszzEnv            The UTF-16 environment block to search.
    1029  */
    1030 static const WCHAR *mkWinChildcareWorkerFindPathValue(const WCHAR *pwszzEnv)
     1040 * @param   pwszPathFallback    Fallback.
     1041 */
     1042static const WCHAR *mkWinChildcareWorkerFindPathValue(const WCHAR *pwszzEnv, WCHAR pwszPathFallback[4])
    10311043{
    10321044    while (*pwszzEnv)
     
    10401052            break;
    10411053    }
    1042     return L".";
     1054    pwszPathFallback[0] = L'.';
     1055    pwszPathFallback[1] = L'\0';
     1056    return pwszPathFallback;
    10431057}
    10441058
     
    10881102 * @returns 0 on success, windows error code on failure.
    10891103 * @param   pszArg0         The first argument.
    1090  * @param   pwszPath        The path if mkWinChildcareWorkerConvertEnvironment
    1091  *                          found it.
     1104 * @param   pwszSearchPath  In case mkWinChildcareWorkerConvertEnvironment
     1105 *                          had a chance of locating the search path already.
    10921106 * @param   pwszzEnv        The environment block, in case we need to look for
    10931107 *                          the path.
     
    10971111 * @param   pfNeedShell     Where to return shell vs direct execution indicator.
    10981112 */
    1099 static int mkWinChildcareWorkerFindImage(char const *pszArg0, WCHAR const *pwszPath, WCHAR const *pwszzEnv,
     1113static int mkWinChildcareWorkerFindImage(char const *pszArg0, WCHAR *pwszSearchPath, WCHAR const *pwszzEnv,
    11001114                                         const char *pszShell, WCHAR **ppwszImagePath, BOOL *pfNeedShell)
    11011115{
     
    12111225        else
    12121226        {
    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
    12161232            for (;;)
    12171233            {
     
    12251241                size_t cwcComponent = 0;
    12261242                WCHAR  wc;
    1227                 while ((wc = pwszPath[cwcComponent]) != L'\0')
     1243                while ((wc = pwszSearchPath[cwcComponent]) != L'\0')
    12281244                {
    12291245                    if (wc != ';' && wc != ':')
     
    12311247                    else if (wc == ';')
    12321248                        break;
    1233                     else if (cwcComponent != pwszPath[cwcComponent] != L'"' ? 1 : 2)
     1249                    else if (cwcComponent != (pwszSearchPath[cwcComponent] != L'"' ? 1 : 2))
    12341250                        break;
    12351251                   cwcComponent++;
     
    12391255                /* Trim leading spaces and double quotes. */
    12401256                while (   cwcComponent > 0
    1241                        && ((wc = *pwszPath) == L'"' || wc == L' ' || wc == L'\t'))
     1257                       && ((wc = *pwszSearchPath) == L'"' || wc == L' ' || wc == L'\t'))
    12421258                {
    1243                     pwszPath++;
     1259                    pwszSearchPath++;
    12441260                    cwcComponent--;
    12451261                }
     
    12481264                /* Trim trailing spaces & double quotes. */
    12491265                while (   cwcComponent > 0
    1250                        && ((wc = pwszPath[cwcComponent - 1]) == L'"' || wc == L' ' || wc == L'\t'))
     1266                       && ((wc = pwszSearchPath[cwcComponent - 1]) == L'"' || wc == L' ' || wc == L'\t'))
    12511267                    cwcComponent--;
    12521268
     
    12621278                    /* Copy the component into wszPathBuf, maybe abspath'ing it. */
    12631279                    DWORD  cwcAbsPath = 0;
    1264                     if (   *pwszPath != L'\\'
    1265                         && (pwszPath[1] != ':' || pwszPath[2] != L'\\') )
     1280                    if (   *pwszSearchPath != L'\\'
     1281                        && (pwszSearchPath[1] != ':' || pwszSearchPath[2] != L'\\') )
    12661282                    {
    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;
    12711289                        if (cwcAbsPath > 0 && cwcAbsPath + 1 + cwcArg0 <= MKWINCHILD_MAX_PATH)
    12721290                            cwcCombined = cwcAbsPath + 1 + cwcArg0;
     
    12761294                    if (cwcAbsPath == 0)
    12771295                    {
    1278                         memcpy(wszPathBuf, pwszPath, cwcComponent);
     1296                        memcpy(wszPathBuf, pwszSearchPath, cwcComponent * sizeof(WCHAR));
    12791297                        cwcAbsPath = cwcComponent;
    12801298                    }
     
    13381356                 */
    13391357                if (wcEnd != '\0')
    1340                     pwszPath += cwcSkip + 1;
     1358                    pwszSearchPath += cwcSkip + 1;
    13411359                else if (fSearchedCwd)
    13421360                    break;
     
    13441362                {
    13451363                    fSearchedCwd = TRUE;
    1346                     pwszPath = L".";
     1364                    wszPathFallback[0] = L'.';
     1365                    wszPathFallback[1] = L'\0';
     1366                    pwszSearchPath = wszPathFallback;
    13471367                }
    13481368            }
     
    13541374         */
    13551375        *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        }
    13601389    }
    13611390    else
     
    13761405 * @param   ppwszEnv        Where to return the pointer to the environment
    13771406 *                          block.
    1378  * @param   ppwszPath       Where to return the pointer to the path value within
    1379  *                          the environment block.  This will not be set if
    1380  *                          cbEnvStrings is non-zero, more efficient to let
     1407 * @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
    13811410 *                          mkWinChildcareWorkerFindImage() search when needed.
    13821411 */
    13831412static int mkWinChildcareWorkerConvertEnvironment(char **papszEnv, size_t cbEnvStrings,
    1384                                                   WCHAR **ppwszEnv, WCHAR const **ppwszPath)
     1413                                                  WCHAR **ppwszEnv, WCHAR const **ppwszSearchPath)
    13851414{
    13861415    DWORD  dwErr;
     
    13891418    WCHAR *pwszzDst;
    13901419
    1391     *ppwszPath = NULL;
     1420    *ppwszSearchPath = NULL;
    13921421
    13931422    /*
     
    15191548
    15201549        if (offPathValue != ~(size_t)0)
    1521             *ppwszPath = &pwszzDst[offPathValue];
     1550            *ppwszSearchPath = &pwszzDst[offPathValue];
    15221551        *ppwszEnv = pwszzDst;
    15231552        return 0;
     
    15351564static void mkWinChildcareWorkerThreadHandleProcess(PWINCHILDCAREWORKER pWorker, PWINCHILD pChild)
    15361565{
    1537     WCHAR const            *pwszPath         = NULL;
    1538     WCHAR                  *pwszzEnvironment = NULL;
    1539     WCHAR                  *pwszCommandLine  = NULL;
    1540     WCHAR                  *pwszImageName    = NULL;
    1541     BOOL                    fNeedShell       = FALSE;
    1542     int                     rc;
     1566    WCHAR  *pwszSearchPath   = NULL;
     1567    WCHAR  *pwszzEnvironment = NULL;
     1568    WCHAR  *pwszCommandLine  = NULL;
     1569    WCHAR  *pwszImageName    = NULL;
     1570    BOOL    fNeedShell       = FALSE;
     1571    int     rc;
    15431572
    15441573    /*
     
    15481577    rc = mkWinChildcareWorkerConvertEnvironment(pChild->u.Process.papszEnv ? pChild->u.Process.papszEnv : environ,
    15491578                                                pChild->u.Process.cbEnvStrings,
    1550                                                 &pwszzEnvironment, &pwszPath);
     1579                                                &pwszzEnvironment, &pwszSearchPath);
    15511580    /*
    15521581     * Find the executable and maybe checking if it's a shell script, then
     
    15541583     */
    15551584    if (rc == 0)
    1556         rc = mkWinChildcareWorkerFindImage(pChild->u.Process.papszArgs[0], pwszzEnvironment, pwszPath,
     1585        rc = mkWinChildcareWorkerFindImage(pChild->u.Process.papszArgs[0], pwszSearchPath, pwszzEnvironment,
    15571586                                           pChild->u.Process.pszShell, &pwszImageName, &fNeedShell);
    15581587    if (rc == 0)
     
    15871616    free(pwszImageName);
    15881617    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);
    15891623}
    15901624
     
    19541988                pChild->u.Process.hProcess = NULL;
    19551989            }
    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);
    19701991            break;
    19711992        }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette