VirtualBox

Changeset 2844 in kBuild


Ignore:
Timestamp:
Aug 29, 2016 4:31:33 PM (9 years ago)
Author:
bird
Message:

kSubmit/kWorker: updates

Location:
trunk/src
Files:
1 added
9 edited
1 moved

Legend:

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

    r2838 r2844  
    5555kWorkerLib_SOURCES = \
    5656        crc32.c \
    57         md5.c
     57        md5.c \
     58       kbuild_version.c
    5859kWorkerLib_SOURCES.win = \
    5960        nt_fullpath.c \
     
    6465       nt/ntstat.c \
    6566       nt/ntunlink.c
     67kbuild_version.c_DEFS = KBUILD_SVN_REV=$(KBUILD_SVN_REV)
    6668
    6769#
  • trunk/src/kWorker/kWorker.c

    r2838 r2844  
    3939#include <ctype.h>
    4040
    41 #include <nt/ntstat.h>
     41#include "nt/ntstat.h"
     42#include "kbuild_version.h"
    4243/* lib/nt_fullpath.c */
    4344extern void nt_fullpath(const char *pszPath, char *pszFull, size_t cchFull);
     45
    4446#include <Windows.h>
    4547#include <winternl.h>
     48
    4649
    4750
     
    425428
    426429    /** The command line.   */
    427     const char *pszCmdLine;
     430    char      *pszCmdLine;
    428431    /** The UTF-16 command line. */
    429432    wchar_t    *pwszCmdLine;
     
    554557static int          g_cVerbose = 2;
    555558
     559/** Whether we should restart the worker. */
     560static KBOOL        g_fRestart = K_FALSE;
     561
    556562/* Further down. */
    557563extern KWREPLACEMENTFUNCTION const g_aSandboxReplacements[];
     
    659665    DWORD const dwSavedErr = GetLastError();
    660666
    661     fprintf(stderr, "error: ");
     667    fprintf(stderr, "kWorker: error: ");
    662668    vfprintf(stderr, pszFormat, va);
    663669
     
    47134719
    47144720
    4715 static int kwSandboxInit(PKWSANDBOX pSandbox, PKWTOOL pTool, const char *pszCmdLine)
     4721static int kwSandboxInit(PKWSANDBOX pSandbox, PKWTOOL pTool,
     4722                         KU32 cArgs, const char **papszArgs, KU32 cbArgs,
     4723                         KU32 cEnvVars, const char **papszEnvVars)
    47164724{
    47174725    PPEB pPeb = kwSandboxGetProcessEnvironmentBlock();
     4726    char *psz;
    47184727    wchar_t *pwcPool;
    47194728    KSIZE cbStrings;
    47204729    KSIZE cwc;
    4721     int i;
     4730    KU32 i;
    47224731
    47234732    /* Simple stuff. */
     
    47264735    g_Sandbox.idMainThread  = GetCurrentThreadId();
    47274736    g_Sandbox.TibMainThread = *(PNT_TIB)NtCurrentTeb();
    4728     g_Sandbox.pszCmdLine    = pszCmdLine;
    47294737    g_Sandbox.pgmptr        = (char *)pTool->pszPath;
    47304738    g_Sandbox.wpgmptr       = (wchar_t *)pTool->pwszPath;
     4739    g_Sandbox.cArgs         = cArgs;
     4740    g_Sandbox.papszArgs     = (char **)papszArgs;
    47314741
    47324742    /*
    4733      * Convert the command line to argc and argv.
     4743     * Create a command line from the given argv.
     4744     * ASSUME that it's correctly quoted by quote_argv.c already.
    47344745     */
    4735     cbStrings = parse_args(pszCmdLine, &pSandbox->cArgs, NULL /*papszArgs*/, NULL /*pchPool*/);
    4736     pSandbox->papszArgs = (char **)kHlpAlloc(sizeof(char *) * (pSandbox->cArgs + 2) + cbStrings);
    4737     if (!pSandbox->papszArgs)
     4746    pSandbox->pszCmdLine = psz = (char *)kHlpAlloc(cbArgs + 1);
     4747    if (!psz)
    47384748        return KERR_NO_MEMORY;
    4739     parse_args(pSandbox->pszCmdLine, &pSandbox->cArgs, pSandbox->papszArgs, (char *)&pSandbox->papszArgs[pSandbox->cArgs + 2]);
    4740     pSandbox->papszArgs[pSandbox->cArgs + 0] = NULL;
    4741     pSandbox->papszArgs[pSandbox->cArgs + 1] = NULL;
     4749    psz = kHlpStrPCopy(psz, papszArgs[0]);
     4750    for (i = 1; i < cArgs; i++)
     4751    {
     4752        *psz++ = ' ';
     4753        psz = kHlpStrPCopy(psz, papszArgs[i]);
     4754    }
     4755    kHlpAssert((KSIZE)(&psz[1] - pSandbox->pszCmdLine) == cbArgs);
     4756    psz[0] = '\0';
     4757    psz[1] = '\0';
    47424758
    47434759    /*
     
    47454761     * We assume each ANSI char requires a surrogate pair in the UTF-16 variant.
    47464762     */
    4747     pSandbox->papwszArgs = (wchar_t **)kHlpAlloc(sizeof(wchar_t *) * (pSandbox->cArgs + 2) + cbStrings * 2 * sizeof(wchar_t));
     4763    pSandbox->papwszArgs = (wchar_t **)kHlpAlloc(sizeof(wchar_t *) * (pSandbox->cArgs + 2) + cbArgs * 2 * sizeof(wchar_t));
    47484764    if (!pSandbox->papwszArgs)
    47494765        return KERR_NO_MEMORY;
    47504766    pwcPool = (wchar_t *)&pSandbox->papwszArgs[pSandbox->cArgs + 2];
    4751     for (i = 0; i < pSandbox->cArgs; i++)
     4767    for (i = 0; i < cArgs; i++)
    47524768    {
    47534769        *pwcPool++ = pSandbox->papszArgs[i][-1]; /* flags */
     
    47624778     * Convert the commandline string to UTF-16, same pessimistic approach as above.
    47634779     */
    4764     cbStrings = (kHlpStrLen(pSandbox->pszCmdLine) + 1) * 2 * sizeof(wchar_t);
     4780    cbStrings = (cbArgs + 1) * 2 * sizeof(wchar_t);
    47654781    pSandbox->pwszCmdLine = kHlpAlloc(cbStrings);
    47664782    if (!pSandbox->pwszCmdLine)
     
    48094825
    48104826
    4811 static int kwSandboxExec(PKWTOOL pTool, const char *pszCmdLine, int *prcExitCode)
    4812 {
     4827static int kwSandboxExec(PKWTOOL pTool, KU32 cArgs, const char **papszArgs, KU32 cbArgs,
     4828                         KU32 cEnvVars, const char **papszEnvVars)
     4829{
     4830    int rcExit = 42;
    48134831    int rc;
    4814 
    4815     *prcExitCode            = 256;
    48164832
    48174833    /*
    48184834     * Initialize the sandbox environment.
    48194835     */
    4820     rc = kwSandboxInit(&g_Sandbox, pTool, pszCmdLine);
     4836    rc = kwSandboxInit(&g_Sandbox, pTool, cArgs, papszArgs, cbArgs, cEnvVars, papszEnvVars);
    48214837    if (rc == 0)
    48224838    {
     
    48354851            if (rc == 0)
    48364852            {
    4837                 int rcExitCode;
    48384853                int (*pfnWin64Entrypoint)(void *pvPeb, void *, void *, void *);
    48394854                *(KUPTR *)&pfnWin64Entrypoint = uAddrMain;
     
    48484863# error "Port me!"
    48494864#endif
    4850                         rcExitCode = pfnWin64Entrypoint(kwSandboxGetProcessEnvironmentBlock(), NULL, NULL, NULL);
     4865                        rcExit = pfnWin64Entrypoint(kwSandboxGetProcessEnvironmentBlock(), NULL, NULL, NULL);
    48514866                    }
    48524867                    else
    4853                         rcExitCode = g_Sandbox.rcExitCode;
     4868                        rcExit = g_Sandbox.rcExitCode;
    48544869                }
    48554870                __except (EXCEPTION_EXECUTE_HANDLER)
    48564871                {
    4857                     rcExitCode = 512;
     4872                    rcExit = 512;
    48584873                }
    4859                 *prcExitCode = rcExitCode;
    48604874
    48614875                /*
     
    48644878                *(PNT_TIB)NtCurrentTeb() = g_Sandbox.TibMainThread;
    48654879            }
    4866         }
     4880            else
     4881                rcExit = 42 + 5;
     4882        }
     4883        else
     4884            rcExit = 42 + 4;
    48674885
    48684886        kwSandboxCleanup(&g_Sandbox);
    48694887    }
    4870 
    4871     return rc;
    4872 }
    4873 
    4874 
     4888    else
     4889        rcExit = 42 + 3;
     4890
     4891    return rcExit;
     4892}
     4893
     4894
     4895#if 0
    48754896static int kwExecCmdLine(const char *pszExe, const char *pszCmdLine)
    48764897{
     
    49094930    return rc;
    49104931}
     4932#endif
     4933
     4934
     4935/**
     4936 * Part 2 of the "JOB" command handler.
     4937 *
     4938 * @returns The exit code of the job.
     4939 * @param   pszExecutable   The executable to execute.
     4940 * @param   pszCwd          The current working directory of the job.
     4941 * @param   cArgs           The number of arguments.
     4942 * @param   papszArgs       The argument vector.
     4943 * @param   cbArgs          The size of the argument strings and terminators.
     4944 * @param   cEnvVars        The number of environment variables.
     4945 * @param   papszEnvVars    The enviornment vector.
     4946 */
     4947static int kSubmitHandleJobUnpacked(const char *pszExecutable, const char *pszCwd,
     4948                                    KU32 cArgs, const char **papszArgs, KU32 cbArgs,
     4949                                    KU32 cEnvVars, const char **papszEnvVars)
     4950{
     4951    int rcExit;
     4952    PKWTOOL pTool;
     4953
     4954    /*
     4955     * Lookup the tool.
     4956     */
     4957    pTool = kwToolLookup(pszExecutable);
     4958    if (pTool)
     4959    {
     4960        /*
     4961         * Change the directory if we're going to execute the job inside
     4962         * this process.  Then invoke the tool type specific handler.
     4963         */
     4964        switch (pTool->enmType)
     4965        {
     4966            case KWTOOLTYPE_SANDBOXED:
     4967            case KWTOOLTYPE_WATCOM:
     4968                /** @todo cache this   */
     4969                if (SetCurrentDirectoryA(pszCwd))
     4970                {
     4971                    if (pTool->enmType == KWTOOLTYPE_SANDBOXED)
     4972                    {
     4973                        KW_LOG(("Sandboxing tool %s\n", pTool->pszPath));
     4974                        rcExit = kwSandboxExec(pTool, cArgs, papszArgs, cbArgs, cEnvVars, papszEnvVars);
     4975                    }
     4976                    else
     4977                    {
     4978                        kwErrPrintf("TODO: Watcom style tool %s\n", pTool->pszPath);
     4979                        rcExit = 42 + 2;
     4980                    }
     4981                }
     4982                else
     4983                {
     4984                    kwErrPrintf("SetCurrentDirectory failed with %u on '%s'\n", GetLastError(), pszCwd);
     4985                    rcExit = 42 + 1;
     4986                }
     4987                break;
     4988
     4989            case KWTOOLTYPE_EXEC:
     4990                kwErrPrintf("TODO: Direct exec tool %s\n", pTool->pszPath);
     4991                rcExit = 42 + 2;
     4992                break;
     4993
     4994            default:
     4995                kHlpAssertFailed();
     4996                kwErrPrintf("Internal tool type corruption!!\n");
     4997                rcExit = 42 + 2;
     4998                g_fRestart = K_TRUE;
     4999                break;
     5000        }
     5001    }
     5002    else
     5003        rcExit = 42 + 1;
     5004    return rcExit;
     5005}
     5006
     5007
     5008/**
     5009 * Handles a "JOB" command.
     5010 *
     5011 * @returns The exit code of the job.
     5012 * @param   pszMsg              Points to the "JOB" command part of the message.
     5013 * @param   cbMsg               Number of message bytes at @a pszMsg.  There are
     5014 *                              4 more zero bytes after the message body to
     5015 *                              simplify parsing.
     5016 */
     5017static int kSubmitHandleJob(const char *pszMsg, KSIZE cbMsg)
     5018{
     5019    int rcExit = 42;
     5020
     5021    /*
     5022     * Unpack the message.
     5023     */
     5024    const char     *pszExecutable;
     5025    size_t          cbTmp;
     5026
     5027    pszMsg += sizeof("JOB");
     5028    cbMsg  -= sizeof("JOB");
     5029
     5030    /* Executable name. */
     5031    pszExecutable = pszMsg;
     5032    cbTmp = strlen(pszMsg) + 1;
     5033    pszMsg += cbTmp;
     5034    if (   cbTmp < cbMsg
     5035        && cbTmp > 2)
     5036    {
     5037        const char *pszCwd;
     5038        cbMsg -= cbTmp;
     5039
     5040        /* Current working directory. */
     5041        pszCwd = pszMsg;
     5042        cbTmp = strlen(pszMsg) + 1;
     5043        pszMsg += cbTmp;
     5044        if (   cbTmp + sizeof(KU32) < cbMsg
     5045            && cbTmp >= 2)
     5046        {
     5047            KU32    cArgs;
     5048            cbMsg  -= cbTmp;
     5049
     5050            /* Argument count. */
     5051            kHlpMemCopy(&cArgs, pszMsg, sizeof(cArgs));
     5052            pszMsg += sizeof(cArgs);
     5053            cbMsg  -= sizeof(cArgs);
     5054
     5055            if (cArgs > 0 && cArgs < 4096)
     5056            {
     5057                /* The argument vector. */
     5058                char const **papszArgs = kHlpAlloc((cArgs + 1) * sizeof(papszArgs[0]));
     5059                if (papszArgs)
     5060                {
     5061                    KU32 cbArgs;
     5062                    KU32 i;
     5063                    for (i = 0; i < cArgs; i++)
     5064                    {
     5065                        papszArgs[i] = pszMsg + 1; /* First byte is expansion flags for MSC & EMX. */
     5066                        cbTmp = 1 + strlen(pszMsg + 1) + 1;
     5067                        pszMsg += cbTmp;
     5068                        if (cbTmp < cbMsg)
     5069                            cbMsg -= cbTmp;
     5070                        else
     5071                        {
     5072                            cbMsg = 0;
     5073                            break;
     5074                        }
     5075
     5076                    }
     5077                    papszArgs[cArgs] = 0;
     5078                    cbArgs = (KU32)(pszMsg - papszArgs[0]) - cArgs + 1;
     5079
     5080                    /* Environment variable count. */
     5081                    if (sizeof(KU32) < cbMsg)
     5082                    {
     5083                        KU32    cEnvVars;
     5084                        kHlpMemCopy(&cEnvVars, pszMsg, sizeof(cEnvVars));
     5085                        pszMsg += sizeof(cEnvVars);
     5086                        cbMsg  -= sizeof(cEnvVars);
     5087
     5088                        if (cEnvVars >= 0 && cEnvVars < 4096)
     5089                        {
     5090                            /* The argument vector. */
     5091                            char const **papszEnvVars = kHlpAlloc((cEnvVars + 1) * sizeof(papszEnvVars[0]));
     5092                            if (papszEnvVars)
     5093                            {
     5094                                KU32 i;
     5095                                for (i = 0; i < cEnvVars; i++)
     5096                                {
     5097                                    papszEnvVars[i] = pszMsg;
     5098                                    cbTmp = strlen(pszMsg) + 1;
     5099                                    pszMsg += cbTmp;
     5100                                    if (cbTmp < cbMsg)
     5101                                        cbMsg -= cbTmp;
     5102                                    else
     5103                                    {
     5104                                        if (   cbTmp == cbMsg
     5105                                            && i + 1 == cEnvVars)
     5106                                            cbMsg = 0;
     5107                                        else
     5108                                            cbMsg = KSIZE_MAX;
     5109                                        break;
     5110                                    }
     5111                                }
     5112                                papszEnvVars[cEnvVars] = 0;
     5113                                if (cbMsg != KSIZE_MAX)
     5114                                {
     5115                                    if (cbMsg == 0)
     5116                                    {
     5117                                        /*
     5118                                         * The next step.
     5119                                         */
     5120                                        rcExit = kSubmitHandleJobUnpacked(pszExecutable, pszCwd,
     5121                                                                          cArgs, papszArgs, cbArgs,
     5122                                                                          cEnvVars, papszEnvVars);
     5123                                    }
     5124                                    else
     5125                                        kwErrPrintf("Message has %u bytes unknown trailing bytes\n", cbMsg);
     5126                                }
     5127                                else
     5128                                    kwErrPrintf("Detected bogus message unpacking environment variables!\n");
     5129                                kHlpFree((void *)papszEnvVars);
     5130                            }
     5131                            else
     5132                                kwErrPrintf("Error allocating papszEnvVars for %u variables\n", cEnvVars);
     5133                        }
     5134                        else
     5135                            kwErrPrintf("Bogus environment variable count: %u (%#x)\n", cEnvVars, cEnvVars);
     5136                    }
     5137                    else
     5138                        kwErrPrintf("Detected bogus message unpacking arguments and environment variable count!\n");
     5139                    kHlpFree((void *)papszArgs);
     5140                }
     5141                else
     5142                    kwErrPrintf("Error allocating argv for %u arguments\n", cArgs);
     5143            }
     5144            else
     5145                kwErrPrintf("Bogus argument count: %u (%#x)\n", cArgs, cArgs);
     5146        }
     5147        else
     5148            kwErrPrintf("Detected bogus message unpacking CWD path and argument count!\n");
     5149    }
     5150    else
     5151        kwErrPrintf("Detected bogus message unpacking executable path!\n");
     5152    return rcExit;
     5153}
     5154
     5155
     5156/**
     5157 * Wrapper around WriteFile / write that writes the whole @a cbToWrite.
     5158 *
     5159 * @retval  0 on success.
     5160 * @retval  -1 on error (fully bitched).
     5161 *
     5162 * @param   hPipe               The pipe handle.
     5163 * @param   pvBuf               The buffer to write out out.
     5164 * @param   cbToWrite           The number of bytes to write.
     5165 */
     5166static int kSubmitWriteIt(HANDLE hPipe, const void *pvBuf, KU32 cbToWrite)
     5167{
     5168    KU8 const  *pbBuf  = (KU8 const *)pvBuf;
     5169    KU32        cbLeft = cbToWrite;
     5170    for (;;)
     5171    {
     5172        DWORD cbActuallyWritten = 0;
     5173        if (WriteFile(hPipe, pbBuf, cbLeft, &cbActuallyWritten, NULL /*pOverlapped*/))
     5174        {
     5175            cbLeft -= cbActuallyWritten;
     5176            if (!cbLeft)
     5177                return 0;
     5178            pbBuf  += cbActuallyWritten;
     5179        }
     5180        else
     5181        {
     5182            DWORD dwErr = GetLastError();
     5183            if (cbLeft == cbToWrite)
     5184                kwErrPrintf("WriteFile failed: %u\n", dwErr);
     5185            else
     5186                kwErrPrintf("WriteFile failed %u byte(s) in: %u\n", cbToWrite - cbLeft, dwErr);
     5187            return -1;
     5188        }
     5189    }
     5190}
     5191
     5192
     5193/**
     5194 * Wrapper around ReadFile / read that reads the whole @a cbToRead.
     5195 *
     5196 * @retval  0 on success.
     5197 * @retval  1 on shut down (fShutdownOkay must be K_TRUE).
     5198 * @retval  -1 on error (fully bitched).
     5199 * @param   hPipe               The pipe handle.
     5200 * @param   pvBuf               The buffer to read into.
     5201 * @param   cbToRead            The number of bytes to read.
     5202 * @param   fShutdownOkay       Whether connection shutdown while reading the
     5203 *                              first byte is okay or not.
     5204 */
     5205static int kSubmitReadIt(HANDLE hPipe, void *pvBuf, KU32 cbToRead, KBOOL fMayShutdown)
     5206{
     5207    KU8 *pbBuf  = (KU8 *)pvBuf;
     5208    KU32 cbLeft = cbToRead;
     5209    for (;;)
     5210    {
     5211        DWORD cbActuallyRead = 0;
     5212        if (ReadFile(hPipe, pbBuf, cbLeft, &cbActuallyRead, NULL /*pOverlapped*/))
     5213        {
     5214            cbLeft -= cbActuallyRead;
     5215            if (!cbLeft)
     5216                return 0;
     5217            pbBuf  += cbActuallyRead;
     5218        }
     5219        else
     5220        {
     5221            DWORD dwErr = GetLastError();
     5222            if (cbLeft == cbToRead)
     5223            {
     5224                if (   fMayShutdown
     5225                    && dwErr == ERROR_BROKEN_PIPE)
     5226                    return 1;
     5227                kwErrPrintf("ReadFile failed: %u\n", dwErr);
     5228            }
     5229            else
     5230                kwErrPrintf("ReadFile failed %u byte(s) in: %u\n", cbToRead - cbLeft, dwErr);
     5231            return -1;
     5232        }
     5233    }
     5234}
    49115235
    49125236
    49135237int main(int argc, char **argv)
    49145238{
     5239#if 1
     5240    KSIZE   cbMsgBuf = 0;
     5241    KU8    *pbMsgBuf = NULL;
     5242    int     i;
     5243    HANDLE  hPipe = INVALID_HANDLE_VALUE;
     5244
     5245    /*
     5246     * Parse arguments.
     5247     */
     5248    for (i = 1; i < argc; i++)
     5249    {
     5250        if (strcmp(argv[i], "--pipe") == 0)
     5251        {
     5252            i++;
     5253            if (i < argc)
     5254            {
     5255                char *pszEnd = NULL;
     5256                unsigned __int64 u64Value = _strtoui64(argv[i], &pszEnd, 16);
     5257                if (   *argv[i]
     5258                    && pszEnd != NULL
     5259                    && *pszEnd == '\0'
     5260                    && u64Value != 0
     5261                    && u64Value != (uintptr_t)INVALID_HANDLE_VALUE
     5262                    && (uintptr_t)u64Value == u64Value)
     5263                    hPipe = (HANDLE)(uintptr_t)u64Value;
     5264                else
     5265                {
     5266                    kwErrPrintf("Invalid --pipe argument: %s\n", argv[i]);
     5267                    return 2;
     5268                }
     5269            }
     5270            else
     5271            {
     5272                kwErrPrintf("--pipe takes an argument!\n");
     5273                return 2;
     5274            }
     5275        }
     5276        else if (   strcmp(argv[i], "--help") == 0
     5277                 || strcmp(argv[i], "-h") == 0
     5278                 || strcmp(argv[i], "-?") == 0)
     5279        {
     5280            printf("usage: kWorker --pipe <pipe-handle>\n"
     5281                   "usage: kWorker <--help|-h>\n"
     5282                   "usage: kWorker <--version|-V>\n"
     5283                   "\n"
     5284                   "This is an internal kmk program that is used via the builtin_kSubmit.\n");
     5285            return 0;
     5286        }
     5287        else if (   strcmp(argv[i], "--version") == 0
     5288                 || strcmp(argv[i], "-V") == 0)
     5289            return kbuild_version(argv[0]);
     5290        else
     5291        {
     5292            kwErrPrintf("Unknown argument '%s'\n", argv[i]);
     5293            return 2;
     5294        }
     5295    }
     5296
     5297    if (hPipe == INVALID_HANDLE_VALUE)
     5298    {
     5299        kwErrPrintf("Missing --pipe <pipe-handle> argument!\n");
     5300        return 2;
     5301    }
     5302
     5303    /*
     5304     * Serve the pipe.
     5305     */
     5306    for (;;)
     5307    {
     5308        KU32 cbMsg = 0;
     5309        int rc = kSubmitReadIt(hPipe, &cbMsg, sizeof(cbMsg), K_TRUE /*fShutdownOkay*/);
     5310        if (rc == 0)
     5311        {
     5312            /* Make sure the message length is within sane bounds.  */
     5313            if (   cbMsg > 4
     5314                && cbMsg <= 256*1024*1024)
     5315            {
     5316                /* Reallocate the message buffer if necessary.  We add 4 zero bytes.  */
     5317                if (cbMsg + 4 <= cbMsgBuf)
     5318                { /* likely */ }
     5319                else
     5320                {
     5321                    cbMsgBuf = K_ALIGN_Z(cbMsg + 4, 2048);
     5322                    pbMsgBuf = kHlpRealloc(pbMsgBuf, cbMsgBuf);
     5323                    if (!pbMsgBuf)
     5324                    {
     5325                        kwErrPrintf("Failed to allocate %u bytes for a message buffer!\n", cbMsgBuf);
     5326                        return 1;
     5327                    }
     5328                }
     5329
     5330                /* Read the whole message into the buffer, making sure there is are a 4 zero bytes following it. */
     5331                *(KU32 *)pbMsgBuf = cbMsg;
     5332                rc = kSubmitReadIt(hPipe, &pbMsgBuf[sizeof(cbMsg)], cbMsg - sizeof(cbMsg), K_FALSE /*fShutdownOkay*/);
     5333                if (rc == 0)
     5334                {
     5335                    const char *psz;
     5336
     5337                    pbMsgBuf[cbMsg]     = '\0';
     5338                    pbMsgBuf[cbMsg + 1] = '\0';
     5339                    pbMsgBuf[cbMsg + 2] = '\0';
     5340                    pbMsgBuf[cbMsg + 3] = '\0';
     5341
     5342                    /* The first string after the header is the command. */
     5343                    psz = (const char *)&pbMsgBuf[sizeof(cbMsg)];
     5344                    if (strcmp(psz, "JOB") == 0)
     5345                    {
     5346                        struct
     5347                        {
     5348                            KI32 rcExitCode;
     5349                            KU8  bExiting;
     5350                            KU8  abZero[3];
     5351                        } Reply;
     5352                        Reply.rcExitCode = kSubmitHandleJob(psz, cbMsg - sizeof(cbMsg));
     5353                        Reply.bExiting   = g_fRestart;
     5354                        Reply.abZero[0]  = 0;
     5355                        Reply.abZero[1]  = 0;
     5356                        Reply.abZero[2]  = 0;
     5357                        rc = kSubmitWriteIt(hPipe, &Reply, sizeof(Reply));
     5358                        if (   rc == 0
     5359                            && !g_fRestart)
     5360                            continue;
     5361                    }
     5362                    else
     5363                    {
     5364                        kwErrPrintf("Unknown command: '%s'\n", psz);
     5365                        rc = -1;
     5366                    }
     5367                }
     5368            }
     5369            else
     5370            {
     5371                kwErrPrintf("Bogus message length: %u (%#x)\n", cbMsg, cbMsg);
     5372                rc = -1;
     5373            }
     5374        }
     5375        return rc > 0 ? 0 : 1;
     5376    }
     5377
     5378#else
    49155379    int rc = 0;
    49165380    int i;
    49175381    argv[2] = "\"E:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/bin/amd64/cl.exe\" -c -c -TP -nologo -Zi -Zi -Zl -GR- -EHsc -GF -Zc:wchar_t- -Oy- -MT -W4 -Wall -wd4065 -wd4996 -wd4127 -wd4706 -wd4201 -wd4214 -wd4510 -wd4512 -wd4610 -wd4514 -wd4820 -wd4365 -wd4987 -wd4710 -wd4061 -wd4986 -wd4191 -wd4574 -wd4917 -wd4711 -wd4611 -wd4571 -wd4324 -wd4505 -wd4263 -wd4264 -wd4738 -wd4242 -wd4244 -WX -RTCsu -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/include -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/atlmfc/include -IE:/vbox/svn/trunk/tools/win.x86/sdk/v7.1/Include -IE:/vbox/svn/trunk/include -IE:/vbox/svn/trunk/out/win.amd64/debug -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/include -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/atlmfc/include -DVBOX -DVBOX_WITH_64_BITS_GUESTS -DVBOX_WITH_REM -DVBOX_WITH_RAW_MODE -DDEBUG -DDEBUG_bird -DDEBUG_USERNAME=bird -DRT_OS_WINDOWS -D__WIN__ -DRT_ARCH_AMD64 -D__AMD64__ -D__WIN64__ -DVBOX_WITH_DEBUGGER -DRT_LOCK_STRICT -DRT_LOCK_STRICT_ORDER -DIN_RING3 -DLOG_DISABLED -DIN_BLD_PROG -D_CRT_SECURE_NO_DEPRECATE -FdE:/vbox/svn/trunk/out/win.amd64/debug/obj/VBoxBs2Linker/VBoxBs2Linker-obj.pdb -FD -FoE:/vbox/svn/trunk/out/win.amd64/debug/obj/VBoxBs2Linker/VBoxBs2Linker.obj E:\\vbox\\svn\\trunk\\src\\VBox\\ValidationKit\\bootsectors\\VBoxBs2Linker.cpp";
    4918 #if 0
     5382# if 0
    49195383    rc = kwExecCmdLine(argv[1], argv[2]);
    49205384    rc = kwExecCmdLine(argv[1], argv[2]);
    49215385    K_NOREF(i);
    4922 #else
     5386# else
    49235387// Skylake (W10/amd64, only stdandard MS defender):
    49245388//     cmd 1:  48    /1024 = 0x0 (0.046875)        [for /l %i in (1,1,1024) do ...]
     
    49365400    for (i = 0; i < 1024 && rc == 0; i++)
    49375401        rc = kwExecCmdLine(argv[1], argv[2]);
     5402# endif
     5403    return rc;
     5404
    49385405#endif
    4939     return rc;
    4940 }
    4941 
     5406}
     5407
  • trunk/src/kmk/Makefile.kmk

    r2843 r2844  
    8888        kmkbuiltin/setmode.c \
    8989        kmkbuiltin/strmode.c \
    90         kmkbuiltin/kbuild_version.c \
    9190        kmkbuiltin/kbuild_protection.c \
    9291        getopt.c \
  • trunk/src/kmk/job.c

    r2843 r2844  
    13181318      assert (*p2);
    13191319      set_command_state (child->file, cs_running);
     1320      child->deleted = 0;
    13201321      child->pid = 0;
    13211322      if (p2 != argv)
    1322         rc = kmk_builtin_command (*p2, &argv_spawn, &child->pid, child);
     1323        rc = kmk_builtin_command (*p2, child, &argv_spawn, &child->pid);
    13231324      else
    13241325        {
     
    13261327          while (argv[argc])
    13271328            argc++;
    1328           rc = kmk_builtin_command_parsed (argc, argv, &argv_spawn, &child->pid, child);
     1329          rc = kmk_builtin_command_parsed (argc, argv, child, &argv_spawn, &child->pid);
    13291330        }
    13301331
     
    13341335# endif
    13351336
    1336       /* synchronous command execution? */
    1337       if (!rc && !argv_spawn)
    1338         goto next_command;
    1339 
    1340       /* spawned a child? */
    1341       if (!rc && child->pid)
     1337      if (!rc)
    13421338        {
    1343           ++job_counter;
    1344           return;
     1339          /* spawned a child? */
     1340          if (child->pid)
     1341            {
     1342              ++job_counter;
     1343              return;
     1344            }
     1345
     1346          /* synchronous command execution? */
     1347          if (!argv_spawn)
     1348            goto next_command;
    13451349        }
    13461350
  • trunk/src/kmk/kmkbuiltin.h

    r2843 r2844  
    3535#endif
    3636
     37#include "kbuild_version.h"
     38
    3739int kmk_builtin_command(const char *pszCmd, struct child *pChild, char ***ppapszArgvToSpawn, pid_t *pPidSpawned);
    3840int kmk_builtin_command_parsed(int argc, char **argv, struct child *pChild, char ***ppapszArgvToSpawn, pid_t *pPidSpawned);
     
    6971extern char *kmk_builtin_func_printf(char *o, char **argv, const char *funcname);
    7072
    71 extern int kbuild_version(const char *);
    72 
    7373#endif
    7474
  • trunk/src/kmk/kmkbuiltin/kSubmit.c

    r2843 r2844  
    5252#ifdef KBUILD_OS_WINDOWS
    5353# include "sub_proc.h"
     54# include "quote_argv.h"
    5455#endif
    5556
     
    366367                if (pWorker->OverlappedRead.hEvent != NULL)
    367368                {
    368                     char        szHandleArg[16];
     369                    char        szHandleArg[32];
    369370                    const char *apszArgs[4] = { szExecutable, "--pipe", szHandleArg, NULL };
    370371                    _snprintf(szHandleArg, sizeof(szHandleArg), "%p", hWorkerPipe);
     
    557558                                      const char *pszCwd, uint32_t *pcbMsg)
    558559{
    559     size_t   i;
    560560    size_t   cbTmp;
     561    uint32_t i;
    561562    uint32_t cbMsg;
     563    uint32_t cArgs;
     564    uint32_t cEnvVars;
    562565    uint8_t *pbMsg;
    563566    uint8_t *pbCursor;
     567
     568    /*
     569     * Adjust input.
     570     */
     571    if (!pszExecutable)
     572        pszExecutable = papszArgs[0];
    564573
    565574    /*
     
    569578    cbMsg += sizeof("JOB");
    570579    cbMsg += strlen(pszExecutable) + 1;
    571 
     580    cbMsg += strlen(pszCwd) + 1;
     581
     582    cbMsg += sizeof(cArgs);
    572583    for (i = 0; papszArgs[i] != NULL; i++)
    573         cbMsg += strlen(papszArgs[i]) + 1;
    574     cbMsg += 1;
    575 
     584        cbMsg += 1 + strlen(papszArgs[i]) + 1;
     585    cArgs  = i;
     586
     587    cbMsg += sizeof(cArgs);
    576588    for (i = 0; papszEnvVars[i] != NULL; i++)
    577589        cbMsg += strlen(papszEnvVars[i]) + 1;
    578     cbMsg += 1;
    579 
    580     cbMsg += strlen(pszCwd) + 1;
     590    cEnvVars = i;
     591
    581592
    582593    /*
     
    594605    pbCursor += cbTmp;
    595606
     607    cbTmp = strlen(pszCwd) + 1;
     608    memcpy(pbCursor, pszCwd, cbTmp);
     609    pbCursor += cbTmp;
     610
     611    memcpy(pbCursor, &cArgs, sizeof(cArgs));
     612    pbCursor += sizeof(cArgs);
    596613    for (i = 0; papszArgs[i] != NULL; i++)
    597614    {
     615        *pbCursor++ = 0; /* Argument expansion flags (MSC, EMX). */
    598616        cbTmp = strlen(papszArgs[i]) + 1;
    599617        memcpy(pbCursor, papszArgs[i], cbTmp);
    600618        pbCursor += cbTmp;
    601619    }
    602     *pbCursor++ = '\0';
    603 
     620    assert(i == cArgs);
     621
     622    memcpy(pbCursor, &cEnvVars, sizeof(cEnvVars));
     623    pbCursor += sizeof(cEnvVars);
    604624    for (i = 0; papszEnvVars[i] != NULL; i++)
    605625    {
     
    608628        pbCursor += cbTmp;
    609629    }
    610     *pbCursor++ = '\0';
    611 
    612     cbTmp = strlen(pszCwd) + 1;
    613     memcpy(pbCursor, pszCwd, cbTmp);
    614     pbCursor += cbTmp;
     630    assert(i == cEnvVars);
    615631
    616632    assert(pbCursor - pbMsg == (size_t)cbMsg);
     
    780796/**
    781797 * Used by
    782  * @returns 0 if we got the whole result, -1 if I/O is pending, windows last
     798 * @returns 0 if we got the whole result, -1 if I/O is pending, and windows last
    783799 *          error on ReadFile failure.
    784800 * @param   pWorker             The worker instance.
     
    806822            DWORD dwErr = GetLastError();
    807823            if (dwErr == ERROR_IO_PENDING)
    808                 return 1;
    809             return kSubmitWinReadFailed(pWorker, GetLastError());
     824                return -1;
     825            return kSubmitWinReadFailed(pWorker, dwErr);
    810826        }
    811827
     
    849865    if (rc == -1)
    850866    {
    851         if (process_kmk_register_submit(pWorker->OverlappedRead.hEvent, (intptr_t)pWorker) == 0)
     867        if (process_kmk_register_submit(pWorker->OverlappedRead.hEvent, (intptr_t)pWorker, pPidSpawned) == 0)
    852868        { /* likely */ }
    853869        else
     
    873889     */
    874890    pWorker->pBusyWith = pChild;
     891#ifndef KBUILD_OS_WINDOWS
    875892    *pPidSpawned = pWorker->pid;
     893#endif
    876894
    877895    kSubmitListUnlink(&g_IdleList, pWorker);
     
    977995        PWORKERINSTANCE apWorkers[MAXIMUM_WAIT_OBJECTS];
    978996        HANDLE          ahHandles[MAXIMUM_WAIT_OBJECTS];
    979         DWORD           cHandles;
     997        DWORD           cHandles = 0;
    980998
    981999        for (pWorker = g_IdleList.pHead; pWorker != NULL; pWorker = pWorker->pNext)
     
    13291347
    13301348    papszEnv = pChild->environment;
    1331     if (papszEnv)
     1349    if (!papszEnv)
    13321350        pChild->environment = papszEnv = target_environment(pChild->file);
    13331351    cEnvVars = 0;
     
    14951513        if (pWorker)
    14961514        {
     1515#ifdef KBUILD_OS_WINDOWS
     1516            /* Quote the argv elements, but first we need unquoted pszExecute. */
     1517            char *pszFreeExec = NULL;
     1518            if (!pszExecutable)
     1519                pszExecutable = pszFreeExec = xstrdup(argv[0]);
     1520            quote_argv(argc, argv, fWatcomBrainDamage, 1 /*fFreeOrLeak*/);
     1521#endif
     1522
    14971523            rcExit = kSubmitSendJobMessage(pWorker, pvMsg, cbMsg, 0 /*fNoRespawning*/, cVerbosity);
    14981524            if (rcExit == 0)
     
    15021528                if (atexit(kSubmitAtExitCallback) == 0)
    15031529                    g_fAtExitRegistered = 1;
     1530
     1531#ifdef KBUILD_OS_WINDOWS
     1532            free(pszFreeExec);
     1533#endif
    15041534        }
    15051535        else
  • trunk/src/kmk/w32/include/sub_proc.h

    r2843 r2844  
    4949EXTERN_DECL(int process_used_slots, (VOID_DECL));
    5050#ifdef KMK
    51 EXTERN_DECL(int process_kmk_register_submit, (HANDLE hEvent, intptr_t clue));
     51EXTERN_DECL(int process_kmk_register_submit, (HANDLE hEvent, intptr_t clue, pid_t *pPid));
    5252#endif
    5353
  • trunk/src/kmk/w32/subproc/sub_proc.c

    r2843 r2844  
    206206 * @param   hEvent              The event semaphore to wait on.
    207207 * @param   clue                The clue to base.
     208 * @param   pPid                Where to return the pid that job.c expects.
    208209 */
    209210int
    210 process_kmk_register_submit(HANDLE hEvent, intptr_t clue)
     211process_kmk_register_submit(HANDLE hEvent, intptr_t clue, pid_t *pPid)
    211212{
    212213        if (proc_index < MAXIMUM_WAIT_OBJECTS) {
     
    217218
    218219                proc_array[proc_index++] = pSubProc;
     220                *pPid = (HANDLE)pSubProc;
    219221                return 0;
    220222        }
  • trunk/src/lib/Makefile.kmk

    r2838 r2844  
    3939kUtil_SOURCES = \
    4040        crc32.c \
    41         md5.c
     41        md5.c \
     42        kbuild_version.c
    4243kUtil_SOURCES.win = \
    4344        nt_fullpath.c \
     
    5455#       restartable-syscall-wrappers.c
    5556kUtil_NOINST = 1
     57
     58kbuild_version.c_DEFS = KBUILD_SVN_REV=$(KBUILD_SVN_REV)
    5659
    5760LIBRARIES.win += kWinStartup
  • trunk/src/lib/kbuild_version.c

    r2837 r2844  
    55
    66/*
    7  * Copyright (c) 2007-2010 knut st. osmundsen <[email protected]>
     7 * Copyright (c) 2007-2016 knut st. osmundsen <[email protected]>
    88 *
    99 * This file is part of kBuild.
     
    2727*   Header Files                                                               *
    2828*******************************************************************************/
    29 #include "config.h"
    30 #include "kmkbuiltin.h"
     29#include "kbuild_version.h"
    3130#include <string.h>
    3231#include <stdio.h>
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