VirtualBox

Changeset 2667 in kBuild for trunk/src


Ignore:
Timestamp:
Nov 25, 2012 7:52:26 PM (12 years ago)
Author:
bird
Message:

kmk_redirect: Quote arguments on windows and support single quotation input args. Fixes #114.

Location:
trunk/src/kmk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/Makefile.kmk

    r2636 r2667  
    379379kmk_redirect_SOURCES = \
    380380        kmkbuiltin/redirect.c
     381kmk_redirect_SOURCES.win = \
     382        ../lib/startuphacks-win.c
    381383
    382384kmk_rmdir_TEMPLATE = BIN-KMK
  • trunk/src/kmk/kmkbuiltin/redirect.c

    r2413 r2667  
    55
    66/*
    7  * Copyright (c) 2007-2010 knut st. osmundsen <[email protected]>
     7 * Copyright (c) 2007-2012 knut st. osmundsen <[email protected]>
    88 *
    99 * This file is part of kBuild.
     
    4848# endif
    4949#endif
     50
     51
     52#if defined(_MSC_VER)
     53/**
     54 * Replaces arguments in need of quoting.
     55 *
     56 * This will "leak" the original and/or the replacement string, depending on
     57 * how you look at it.
     58 *
     59 * For details on how MSC parses the command line, see "Parsing C Command-Line
     60 * Arguments": http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
     61 *
     62 * @param   argc        The argument count.
     63 * @param   argv        The argument vector.
     64 */
     65static void quoteArguments(int argc, char **argv)
     66{
     67    int i;
     68    for (i = 0; i < argc; i++)
     69    {
     70        const char *pszOrg    = argv[i];
     71        size_t      cchOrg    = strlen(pszOrg);
     72        const char *pszQuotes = (const char *)memchr(pszOrg, '"', cchOrg);
     73        if (   pszQuotes
     74            || cchOrg == 0
     75            || memchr(pszOrg, '&', cchOrg)
     76            || memchr(pszOrg, '>', cchOrg)
     77            || memchr(pszOrg, '<', cchOrg)
     78            || memchr(pszOrg, '|', cchOrg)
     79            || memchr(pszOrg, '%', cchOrg)
     80            )
     81        {
     82            char   ch;
     83            int    fComplicated = pszQuotes || (cchOrg > 0 && pszOrg[cchOrg - 1] == '\\');
     84            size_t cchNew       = fComplicated ? cchOrg * 2 + 2 : cchOrg + 2;
     85            char  *pszNew       = (char *)malloc(cchNew + 1);
     86
     87            argv[i] = pszNew;
     88
     89            *pszNew++ = '"';
     90            if (fComplicated)
     91            {
     92                while ((ch = *pszOrg++) != '\0')
     93                {
     94                    if (ch == '"')
     95                    {
     96                        *pszNew++ = '\\';
     97                        *pszNew++ = '"';
     98                    }
     99                    else if (ch == '\\')
     100                    {
     101                        /* Backslashes are a bit complicated, they depends on
     102                           whether a quotation mark follows them or not.  They
     103                           only require escaping if one does. */
     104                        unsigned cSlashes = 1;
     105                        while ((ch = *pszOrg) == '\\')
     106                        {
     107                            pszOrg++;
     108                            cSlashes++;
     109                        }
     110                        if (ch == '"' || ch == '\0') /* We put a " at the EOS. */
     111                        {
     112                            while (cSlashes-- > 0)
     113                            {
     114                                *pszNew++ = '\\';
     115                                *pszNew++ = '\\';
     116                            }
     117                        }
     118                        else
     119                            while (cSlashes-- > 0)
     120                                *pszNew++ = '\\';
     121                    }
     122                    else
     123                        *pszNew++ = ch;
     124                }
     125            }
     126            else
     127            {
     128                memcpy(pszNew, pszOrg, cchOrg);
     129                pszNew += cchOrg;
     130            }
     131            *pszNew++ = '"';
     132            *pszNew = '\0';
     133        }
     134    }
     135
     136    /*for (i = 0; i < argc; i++) printf("argv[%u]=%s;;\n", i, argv[i]); */
     137}
     138#endif /* _MSC_VER */
    50139
    51140
     
    87176            "effect, so be careful where you put it.\n"
    88177            "\n"
    89             "This command is really just a quick hack to avoid invoking the shell\n"
     178            "This command was originally just a quick hack to avoid invoking the shell\n"
    90179            "on Windows (cygwin) where forking is very expensive and has exhibited\n"
    91             "stability issues on SMP machines. This tool may be retired when kBuild\n"
    92             "starts using the kmk_kash shell.\n"
     180            "stability issues on SMP machines.  It has since grown into something like\n"
     181            "/usr/bin/env on steroids.\n"
    93182            ,
    94183            argv0, argv0, argv0);
     
    154243            {
    155244                printf("kmk_redirect - kBuild version %d.%d.%d (r%u)\n"
    156                        "Copyright (C) 2007-2009 knut st. osmundsen\n",
     245                       "Copyright (C) 2007-2012 knut st. osmundsen\n",
    157246                       KBUILD_VERSION_MAJOR, KBUILD_VERSION_MINOR, KBUILD_VERSION_PATCH,
    158247                       KBUILD_SVN_REV);
     
    558647    }
    559648
    560     /** @todo
    561      * We'll have to find the '--' in the commandline and pass that
    562      * on to CreateProcess or spawn. Otherwise, the argument qouting
    563      * is gonna be messed up.
    564      */
     649    /* MSC is a PITA since it refuses to quote the arguments... */
     650    quoteArguments(argc - i, &argv[i]);
    565651    rc = _spawnvp(_P_WAIT, argv[i], &argv[i]);
    566652    if (rc == -1 && pStdErr)
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