Ignore:
Timestamp:
Mar 21, 2018, 10:37:41 PM (7 years ago)
Author:
bird
Message:

kmkbultin: environment fixes and stats.

Location:
trunk/src/kmk/kmkbuiltin
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/kmkbuiltin/common-env-and-cwd-opt.c

    r3133 r3173  
    3131#include <stdlib.h>
    3232#include <string.h>
     33#include <assert.h>
    3334
    3435#include "kmkbuiltin.h"
     
    4344# define KSUBMIT_ENV_NCMP   strncmp
    4445#endif
     46
     47
     48/**
     49 * Duplicates a read-only enviornment vector.
     50 *
     51 * @returns The duplicate enviornment.
     52 * @param   papszEnv            The read-only vector.
     53 * @param   cEnvVars            The number of variables.
     54 * @param   pcAllocatedEnvVars  The allocated papszEnv size.  This is zero on
     55 *                              input and non-zero on successful return.
     56 * @param   cVerbosity          The verbosity level.
     57 */
     58static char **kBuiltinOptEnvDuplicate(char **papszEnv, unsigned cEnvVars, unsigned *pcAllocatedEnvVars, int cVerbosity)
     59{
     60    unsigned cAllocatedEnvVars = (cEnvVars + 2 + 0xf) * ~(unsigned)0xf;
     61    char    **papszEnvNew      = malloc(cAllocatedEnvVars * sizeof(papszEnvNew[0]));
     62    assert(*pcAllocatedEnvVars == 0);
     63    if (papszEnvNew)
     64    {
     65        unsigned i;
     66        for (i = 0; i < cEnvVars; i++)
     67        {
     68            papszEnvNew[i] = strdup(papszEnv[i]);
     69            if (!papszEnvNew)
     70            {
     71                while (i-- > 0)
     72                    free(papszEnvNew[i]);
     73                free(papszEnvNew);
     74                errx(1, "out of memory");
     75                return NULL;
     76            }
     77        }
     78        papszEnvNew[i] = NULL;
     79        *pcAllocatedEnvVars = cAllocatedEnvVars;
     80    }
     81    else
     82        errx(1, "out of memory");
     83    return papszEnvNew;
     84}
    4585
    4686
     
    136176        unsigned cEnvVars = *pcEnvVars;
    137177        size_t const cchVar = pszEqual - pszValue;
     178
     179        if (!*pcAllocatedEnvVars)
     180        {
     181            papszEnv = kBuiltinOptEnvDuplicate(papszEnv, cEnvVars, pcAllocatedEnvVars, cVerbosity);
     182            if (!papszEnv)
     183                return errx(1, "out of memory!");
     184            *ppapszEnv = papszEnv;
     185        }
     186
    138187        for (iEnvVar = 0; iEnvVar < cEnvVars; iEnvVar++)
    139188        {
     
    180229        unsigned cEnvVars = *pcEnvVars;
    181230        size_t const cchVar = pszEqual - pszValue;
     231
     232        if (!*pcAllocatedEnvVars)
     233        {
     234            papszEnv = kBuiltinOptEnvDuplicate(papszEnv, cEnvVars, pcAllocatedEnvVars, cVerbosity);
     235            if (!papszEnv)
     236                return errx(1, "out of memory!");
     237            *ppapszEnv = papszEnv;
     238        }
     239
    182240        for (iEnvVar = 0; iEnvVar < cEnvVars; iEnvVar++)
    183241        {
     
    257315 *
    258316 * @returns 0 on success, non-zero exit code on error.
    259  * @param   papszEnv            The environment vector.
    260  * @param   pcEnvVars           Pointer to the variable holding the number of
    261  *                              environment variables held by @a papszEnv.
     317 * @param   ppapszEnv           The environment vector pointer.
     318 * @param   pcEnvVars           Pointer to the variable holding the number of
     319 *                              environment variables held by @a papszEnv.
     320 * @param   pcAllocatedEnvVars  Pointer to the size of the vector allocation.
     321 *                              The size is zero when read-only (CRT, GNU make)
     322 *                              environment.
    262323 * @param   cVerbosity          The verbosity level.
    263324 * @param   pszVarToRemove      The name of the variable to remove.
    264325 */
    265 int kBuiltinOptEnvUnset(char **papszEnv, unsigned *pcEnvVars, int cVerbosity, const char *pszVarToRemove)
     326int kBuiltinOptEnvUnset(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars, int cVerbosity, const char *pszVarToRemove)
    266327{
    267328    if (strchr(pszVarToRemove, '=') == NULL)
    268329    {
     330        char       **papszEnv = *ppapszEnv;
    269331        unsigned     cRemoved = 0;
    270332        size_t const cchVar   = strlen(pszVarToRemove);
     
    278340                if (cVerbosity > 0)
    279341                    warnx(!cRemoved ? "removing '%s'" : "removing duplicate '%s'", papszEnv[iEnvVar]);
     342
     343                if (!*pcAllocatedEnvVars)
     344                {
     345                    papszEnv = kBuiltinOptEnvDuplicate(papszEnv, cEnvVars, pcAllocatedEnvVars, cVerbosity);
     346                    if (!papszEnv)
     347                        return errx(1, "out of memory!");
     348                    *ppapszEnv = papszEnv;
     349                }
     350
    280351                free(papszEnv[iEnvVar]);
    281352                cEnvVars--;
     
    296367}
    297368
     369
     370/**
     371 * Handles the --zap-env & --ignore-environment options.
     372 *
     373 * @returns 0 on success, non-zero exit code on error.
     374 * @param   ppapszEnv           The environment vector pointer.
     375 * @param   pcEnvVars           Pointer to the variable holding the number of
     376 *                              environment variables held by @a papszEnv.
     377 * @param   pcAllocatedEnvVars  Pointer to the size of the vector allocation.
     378 *                              The size is zero when read-only (CRT, GNU make)
     379 *                              environment.
     380 * @param   cVerbosity          The verbosity level.
     381 */
     382int kBuiltinOptEnvZap(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars, int cVerbosity)
     383{
     384    if (*pcAllocatedEnvVars > 0)
     385    {
     386        char **papszEnv = *ppapszEnv;
     387        unsigned i = *pcEnvVars;
     388        while (i-- > 0)
     389        {
     390            free(papszEnv[i]);
     391            papszEnv[i] = NULL;
     392        }
     393    }
     394    else
     395    {
     396        char **papszEnv = calloc(4, sizeof(char *));
     397        if (!papszEnv)
     398            return err(1, "out of memory!");
     399        *ppapszEnv = papszEnv;
     400        *pcAllocatedEnvVars = 4;
     401    }
     402    *pcEnvVars = 0;
     403    return 0;
     404}
     405
     406
     407/**
     408 * Cleans up afterwards, if necessary.
     409 *
     410 * @param   ppapszEnv           The environment vector pointer.
     411 * @param   cEnvVars            The number of variables in the vector.
     412 * @param   pcAllocatedEnvVars  Pointer to the size of the vector allocation.
     413 *                              The size is zero when read-only (CRT, GNU make)
     414 *                              environment.
     415 */
     416void kBuiltinOptEnvCleanup(char ***ppapszEnv, unsigned cEnvVars, unsigned *pcAllocatedEnvVars)
     417{
     418    char **papszEnv = *ppapszEnv;
     419    *ppapszEnv = NULL;
     420    if (*pcAllocatedEnvVars > 0)
     421    {
     422        *pcAllocatedEnvVars = 0;
     423        while (cEnvVars-- > 0)
     424        {
     425            free(papszEnv[cEnvVars]);
     426            papszEnv[cEnvVars] = NULL;
     427        }
     428        free(papszEnv);
     429    }
     430}
    298431
    299432
  • trunk/src/kmk/kmkbuiltin/kSubmit.c

    r3156 r3173  
    12501250    int             iArg;
    12511251    unsigned        cAllocatedEnvVars;
    1252     unsigned        iEnvVar;
    12531252    unsigned        cEnvVars;
    1254     char          **papszEnv            = NULL;
     1253    char          **papszEnvVars;
    12551254    const char     *pszExecutable       = NULL;
    12561255    int             iPostCmd            = argc;
     
    12671266    /*
    12681267     * Create default program environment.
     1268     *
     1269     * Note! We only clean up the environment on successful return, assuming
     1270     *       make will stop after that.
    12691271     */
    12701272    if (getcwd_fs(szCwd, cbCwdBuf) != NULL)
     
    12731275        return err(1, "getcwd_fs failed\n");
    12741276
    1275     papszEnv = pChild->environment;
    1276     if (!papszEnv)
    1277         pChild->environment = papszEnv = target_environment(pChild->file);
     1277    /* The environment starts out in read-only mode and will be duplicated if modified. */
     1278    cAllocatedEnvVars = 0;
     1279    papszEnvVars = envp;
    12781280    cEnvVars = 0;
    1279     while (papszEnv[cEnvVars] != NULL)
     1281    while (papszEnvVars[cEnvVars] != NULL)
    12801282        cEnvVars++;
    1281     cAllocatedEnvVars = cEnvVars;
    12821283
    12831284    /*
     
    13871388                    case 'Z':
    13881389                    case 'i': /* GNU env compatibility. */
    1389                         for (iEnvVar = 0; iEnvVar < cEnvVars; iEnvVar++)
    1390                             free(papszEnv[iEnvVar]);
    1391                         papszEnv[0] = NULL;
    1392                         cEnvVars = 0;
    1393                         break;
    1394 
    1395                     case 'E':
    1396                         rcExit = kBuiltinOptEnvSet(&papszEnv, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
    1397                         pChild->environment = papszEnv;
     1390                        rcExit = kBuiltinOptEnvZap(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity);
    13981391                        if (rcExit == 0)
    13991392                            break;
    14001393                        return rcExit;
    14011394
    1402                     case 'A':
    1403                         rcExit = kBuiltinOptEnvAppend(&papszEnv, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
    1404                         pChild->environment = papszEnv;
     1395                    case 'E':
     1396                        rcExit = kBuiltinOptEnvSet(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
    14051397                        if (rcExit == 0)
    14061398                            break;
    14071399                        return rcExit;
    14081400
    1409                     case 'D':
    1410                         rcExit = kBuiltinOptEnvPrepend(&papszEnv, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
    1411                         pChild->environment = papszEnv;
     1401                    case 'A':
     1402                        rcExit = kBuiltinOptEnvAppend(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
    14121403                        if (rcExit == 0)
    14131404                            break;
    14141405                        return rcExit;
    14151406
     1407                    case 'D':
     1408                        rcExit = kBuiltinOptEnvPrepend(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
     1409                        if (rcExit == 0)
     1410                            break;
     1411                        return rcExit;
     1412
    14161413                    case 'U':
    1417                         rcExit = kBuiltinOptEnvUnset(papszEnv, &cEnvVars, cVerbosity, pszValue);
     1414                        rcExit = kBuiltinOptEnvUnset(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
    14181415                        if (rcExit == 0)
    14191416                            break;
     
    14581455                    case 'h':
    14591456                        usage(stdout, argv[0]);
     1457                        kBuiltinOptEnvCleanup(&papszEnvVars, cEnvVars, &cAllocatedEnvVars);
    14601458                        return 0;
    14611459
    14621460                    case 'V':
     1461                        kBuiltinOptEnvCleanup(&papszEnvVars, cEnvVars, &cAllocatedEnvVars);
    14631462                        return kbuild_version(argv[0]);
    14641463                }
     
    14781477    {
    14791478        uint32_t        cbMsg;
    1480         void           *pvMsg   = kSubmitComposeJobMessage(pszExecutable, &argv[iArg], papszEnv, szCwd,
     1479        void           *pvMsg   = kSubmitComposeJobMessage(pszExecutable, &argv[iArg], papszEnvVars, szCwd,
    14811480                                                           fWatcomBrainDamage, fNoPchCaching,
    14821481                                                           &argv[iPostCmd], cPostCmdArgs, &cbMsg);
     
    15051504    }
    15061505
     1506    kBuiltinOptEnvCleanup(&papszEnvVars, cEnvVars, &cAllocatedEnvVars);
    15071507    return rcExit;
    15081508}
  • trunk/src/kmk/kmkbuiltin/redirect.c

    r3164 r3173  
    7474#include "kmkbuiltin.h"
    7575#ifdef KMK
    76 # include "job.h"
    77 # include "variable.h"
    7876# ifdef KBUILD_OS_WINDOWS
    7977#  ifndef CONFIG_NEW_WIN_CHILDREN
     
    11611159                /* Windows is slightly complicated due to handles and winchildren.c. */
    11621160                HANDLE hProcess = INVALID_HANDLE_VALUE;
    1163                 rcExit = kRedirectCreateProcessWindows(pszExecutable, cArgs, papszArgs, papszEnvVars, pszCwd,
    1164                                                        cOrders, paOrders, &hProcess);
     1161                rcExit = kRedirectCreateProcessWindows(pszExecutable, cArgs, papszArgs, papszEnvVars,
     1162                                                       pszSavedCwd ? pszCwd : NULL, cOrders, paOrders, &hProcess);
    11651163                if (rcExit == 0)
    11661164                {
     
    11681166                    if (process_kmk_register_redirect(hProcess, pPidSpawned) == 0)
    11691167#  else
    1170                     if (MkWinChildCreateRedirect((intptr_t)hProcess, pPidSpawned) == 0)
     1168                    if (   pPidSpawned
     1169                        && MkWinChildCreateRedirect((intptr_t)hProcess, pPidSpawned) == 0)
    11711170#  endif
    11721171                    {
     
    11801179                        warn("sub_proc is out of slots, waiting for child...");
    11811180#  else
    1182                         warn("MkWinChildCreateRedirect failed...");
     1181                        if (pPidSpawned)
     1182                            warn("MkWinChildCreateRedirect failed...");
    11831183#  endif
    11841184                        dwTmp = WaitForSingleObject(hProcess, INFINITE);
     
    11961196
    11971197                        CloseHandle(hProcess);
    1198                         *pPidSpawned = 0;
     1198                        if (pPidSpawned)
     1199                            *pPidSpawned = 0;
    11991200                        *pfIsChildExitCode = K_TRUE;
    12001201                    }
     
    12341235# ifdef KBUILD_OS_WINDOWS
    12351236                HANDLE hProcess = INVALID_HANDLE_VALUE;
    1236                 rcExit = kRedirectCreateProcessWindows(pszExecutable, cArgs, papszArgs, papszEnvVars, pszCwd,
    1237                                                        cOrders, paOrders, &hProcess);
     1237                rcExit = kRedirectCreateProcessWindows(pszExecutable, cArgs, papszArgs, papszEnvVars,
     1238                                                       pszSavedCwd ? pszCwd : NULL, cOrders, paOrders, &hProcess);
    12381239                if (rcExit == 0)
    12391240                {
     
    13481349    char          **papszEnvVars       = NULL;
    13491350    unsigned        cAllocatedEnvVars;
    1350     unsigned        iEnvVar;
    13511351    unsigned        cEnvVars;
    13521352    int             fWatcomBrainDamage = 0;
     
    13781378        return err(9, "getcwd failed");
    13791379
    1380 #if defined(KMK)
    1381     /* We get it from kmk and just count it:  */
    1382     papszEnvVars = pChild->environment;
    1383     if (!papszEnvVars)
    1384         pChild->environment = papszEnvVars = target_environment(pChild->file);
     1380    /* We start out with a read-only enviornment from kmk or the crt, and will
     1381       duplicate it if we make changes to it. */
     1382    cAllocatedEnvVars = 0;
     1383    papszEnvVars = envp;
    13851384    cEnvVars = 0;
    13861385    while (papszEnvVars[cEnvVars] != NULL)
    13871386        cEnvVars++;
    1388     cAllocatedEnvVars = cEnvVars;
    1389 #else
    1390     /* We make a copy and we manage ourselves: */
    1391     cEnvVars = 0;
    1392     while (envp[cEnvVars] != NULL)
    1393         cEnvVars++;
    1394 
    1395     cAllocatedEnvVars = cEnvVars + 4;
    1396     papszEnvVars = malloc((cAllocatedEnvVars + 1) * sizeof(papszEnvVars));
    1397     if (!papszEnvVars)
    1398         return errx(9, "out of memory!");
    1399 
    1400     iEnvVar = cEnvVars;
    1401     papszEnvVars[iEnvVar] = NULL;
    1402     while (iEnvVar-- > 0)
    1403     {
    1404         papszEnvVars[iEnvVar] = strdup(envp[iEnvVar]);
    1405         if (!papszEnvVars[iEnvVar])
    1406         {
    1407             while (iEnvVar-- > 0)
    1408                 free(papszEnvVars[iEnvVar]);
    1409             free(papszEnvVars);
    1410             return errx(9, "out of memory!");
    1411         }
    1412     }
    1413 #endif
    14141387
    14151388#ifdef USE_POSIX_SPAWN
     
    15781551                {
    15791552                    if (pchEqual[1] != '\0')
    1580                     {
    15811553                        rcExit = kBuiltinOptEnvSet(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
    1582 #ifdef KMK
    1583                         pChild->environment = papszEnvVars;
    1584 #endif
    1585                     }
    15861554                    else
    15871555                    {
     
    15901558                        {
    15911559                            pszCopy[pchEqual - pszValue] = '\0';
    1592                             rcExit = kBuiltinOptEnvUnset(papszEnvVars, &cEnvVars, cVerbosity, pszCopy);
     1560                            rcExit = kBuiltinOptEnvUnset(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszCopy);
    15931561                            free(pszCopy);
    15941562                        }
     
    16331601                else
    16341602#endif
    1635                     rcExit = kBuiltinOptEnvUnset(papszEnvVars, &cEnvVars, cVerbosity, pszValue);
     1603                    rcExit = kBuiltinOptEnvUnset(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
    16361604                continue;
    16371605            }
     
    16431611                || chOpt == 'i' /* GNU env compatibility. */ )
    16441612            {
    1645                 for (iEnvVar = 0; iEnvVar < cEnvVars; iEnvVar++)
    1646                     free(papszEnvVars[iEnvVar]);
    1647                 papszEnvVars[0] = NULL;
    1648                 cEnvVars = 0;
     1613                rcExit = kBuiltinOptEnvZap(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity);
    16491614                continue;
    16501615            }
     
    19981963     * Cleanup.
    19991964     */
     1965    kBuiltinOptEnvCleanup(&papszEnvVars, cEnvVars, &cAllocatedEnvVars);
    20001966    if (pszSavedCwd)
    20011967        free(pszSavedCwd);
     
    20041970    posix_spawn_file_actions_destroy(&FileActions);
    20051971#endif
    2006 #ifndef KMK
    2007     iEnvVar = cEnvVars;
    2008     while (iEnvVar-- > 0)
    2009         free(papszEnvVars[iEnvVar]);
    2010     free(papszEnvVars);
    2011 #endif
    20121972#ifdef KBUILD_OS_OS2
    20131973    for (ulLibPath = 0; ulLibPath < K_ELEMENTS(apszSavedLibPaths); ulLibPath++)
Note: See TracChangeset for help on using the changeset viewer.