Changeset 2844 in kBuild
- Timestamp:
- Aug 29, 2016 4:31:33 PM (9 years ago)
- Location:
- trunk/src
- Files:
-
- 1 added
- 9 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/Makefile.kmk
r2838 r2844 55 55 kWorkerLib_SOURCES = \ 56 56 crc32.c \ 57 md5.c 57 md5.c \ 58 kbuild_version.c 58 59 kWorkerLib_SOURCES.win = \ 59 60 nt_fullpath.c \ … … 64 65 nt/ntstat.c \ 65 66 nt/ntunlink.c 67 kbuild_version.c_DEFS = KBUILD_SVN_REV=$(KBUILD_SVN_REV) 66 68 67 69 # -
trunk/src/kWorker/kWorker.c
r2838 r2844 39 39 #include <ctype.h> 40 40 41 #include <nt/ntstat.h> 41 #include "nt/ntstat.h" 42 #include "kbuild_version.h" 42 43 /* lib/nt_fullpath.c */ 43 44 extern void nt_fullpath(const char *pszPath, char *pszFull, size_t cchFull); 45 44 46 #include <Windows.h> 45 47 #include <winternl.h> 48 46 49 47 50 … … 425 428 426 429 /** The command line. */ 427 c onst char*pszCmdLine;430 char *pszCmdLine; 428 431 /** The UTF-16 command line. */ 429 432 wchar_t *pwszCmdLine; … … 554 557 static int g_cVerbose = 2; 555 558 559 /** Whether we should restart the worker. */ 560 static KBOOL g_fRestart = K_FALSE; 561 556 562 /* Further down. */ 557 563 extern KWREPLACEMENTFUNCTION const g_aSandboxReplacements[]; … … 659 665 DWORD const dwSavedErr = GetLastError(); 660 666 661 fprintf(stderr, " error: ");667 fprintf(stderr, "kWorker: error: "); 662 668 vfprintf(stderr, pszFormat, va); 663 669 … … 4713 4719 4714 4720 4715 static int kwSandboxInit(PKWSANDBOX pSandbox, PKWTOOL pTool, const char *pszCmdLine) 4721 static int kwSandboxInit(PKWSANDBOX pSandbox, PKWTOOL pTool, 4722 KU32 cArgs, const char **papszArgs, KU32 cbArgs, 4723 KU32 cEnvVars, const char **papszEnvVars) 4716 4724 { 4717 4725 PPEB pPeb = kwSandboxGetProcessEnvironmentBlock(); 4726 char *psz; 4718 4727 wchar_t *pwcPool; 4719 4728 KSIZE cbStrings; 4720 4729 KSIZE cwc; 4721 inti;4730 KU32 i; 4722 4731 4723 4732 /* Simple stuff. */ … … 4726 4735 g_Sandbox.idMainThread = GetCurrentThreadId(); 4727 4736 g_Sandbox.TibMainThread = *(PNT_TIB)NtCurrentTeb(); 4728 g_Sandbox.pszCmdLine = pszCmdLine;4729 4737 g_Sandbox.pgmptr = (char *)pTool->pszPath; 4730 4738 g_Sandbox.wpgmptr = (wchar_t *)pTool->pwszPath; 4739 g_Sandbox.cArgs = cArgs; 4740 g_Sandbox.papszArgs = (char **)papszArgs; 4731 4741 4732 4742 /* 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. 4734 4745 */ 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) 4738 4748 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'; 4742 4758 4743 4759 /* … … 4745 4761 * We assume each ANSI char requires a surrogate pair in the UTF-16 variant. 4746 4762 */ 4747 pSandbox->papwszArgs = (wchar_t **)kHlpAlloc(sizeof(wchar_t *) * (pSandbox->cArgs + 2) + cb Strings * 2 * sizeof(wchar_t));4763 pSandbox->papwszArgs = (wchar_t **)kHlpAlloc(sizeof(wchar_t *) * (pSandbox->cArgs + 2) + cbArgs * 2 * sizeof(wchar_t)); 4748 4764 if (!pSandbox->papwszArgs) 4749 4765 return KERR_NO_MEMORY; 4750 4766 pwcPool = (wchar_t *)&pSandbox->papwszArgs[pSandbox->cArgs + 2]; 4751 for (i = 0; i < pSandbox->cArgs; i++)4767 for (i = 0; i < cArgs; i++) 4752 4768 { 4753 4769 *pwcPool++ = pSandbox->papszArgs[i][-1]; /* flags */ … … 4762 4778 * Convert the commandline string to UTF-16, same pessimistic approach as above. 4763 4779 */ 4764 cbStrings = ( kHlpStrLen(pSandbox->pszCmdLine)+ 1) * 2 * sizeof(wchar_t);4780 cbStrings = (cbArgs + 1) * 2 * sizeof(wchar_t); 4765 4781 pSandbox->pwszCmdLine = kHlpAlloc(cbStrings); 4766 4782 if (!pSandbox->pwszCmdLine) … … 4809 4825 4810 4826 4811 static int kwSandboxExec(PKWTOOL pTool, const char *pszCmdLine, int *prcExitCode) 4812 { 4827 static int kwSandboxExec(PKWTOOL pTool, KU32 cArgs, const char **papszArgs, KU32 cbArgs, 4828 KU32 cEnvVars, const char **papszEnvVars) 4829 { 4830 int rcExit = 42; 4813 4831 int rc; 4814 4815 *prcExitCode = 256;4816 4832 4817 4833 /* 4818 4834 * Initialize the sandbox environment. 4819 4835 */ 4820 rc = kwSandboxInit(&g_Sandbox, pTool, pszCmdLine);4836 rc = kwSandboxInit(&g_Sandbox, pTool, cArgs, papszArgs, cbArgs, cEnvVars, papszEnvVars); 4821 4837 if (rc == 0) 4822 4838 { … … 4835 4851 if (rc == 0) 4836 4852 { 4837 int rcExitCode;4838 4853 int (*pfnWin64Entrypoint)(void *pvPeb, void *, void *, void *); 4839 4854 *(KUPTR *)&pfnWin64Entrypoint = uAddrMain; … … 4848 4863 # error "Port me!" 4849 4864 #endif 4850 rcExit Code= pfnWin64Entrypoint(kwSandboxGetProcessEnvironmentBlock(), NULL, NULL, NULL);4865 rcExit = pfnWin64Entrypoint(kwSandboxGetProcessEnvironmentBlock(), NULL, NULL, NULL); 4851 4866 } 4852 4867 else 4853 rcExit Code= g_Sandbox.rcExitCode;4868 rcExit = g_Sandbox.rcExitCode; 4854 4869 } 4855 4870 __except (EXCEPTION_EXECUTE_HANDLER) 4856 4871 { 4857 rcExit Code= 512;4872 rcExit = 512; 4858 4873 } 4859 *prcExitCode = rcExitCode;4860 4874 4861 4875 /* … … 4864 4878 *(PNT_TIB)NtCurrentTeb() = g_Sandbox.TibMainThread; 4865 4879 } 4866 } 4880 else 4881 rcExit = 42 + 5; 4882 } 4883 else 4884 rcExit = 42 + 4; 4867 4885 4868 4886 kwSandboxCleanup(&g_Sandbox); 4869 4887 } 4870 4871 return rc; 4872 } 4873 4874 4888 else 4889 rcExit = 42 + 3; 4890 4891 return rcExit; 4892 } 4893 4894 4895 #if 0 4875 4896 static int kwExecCmdLine(const char *pszExe, const char *pszCmdLine) 4876 4897 { … … 4909 4930 return rc; 4910 4931 } 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 */ 4947 static 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 */ 5017 static 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 */ 5166 static 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 */ 5205 static 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 } 4911 5235 4912 5236 4913 5237 int main(int argc, char **argv) 4914 5238 { 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 4915 5379 int rc = 0; 4916 5380 int i; 4917 5381 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 05382 # if 0 4919 5383 rc = kwExecCmdLine(argv[1], argv[2]); 4920 5384 rc = kwExecCmdLine(argv[1], argv[2]); 4921 5385 K_NOREF(i); 4922 # else5386 # else 4923 5387 // Skylake (W10/amd64, only stdandard MS defender): 4924 5388 // cmd 1: 48 /1024 = 0x0 (0.046875) [for /l %i in (1,1,1024) do ...] … … 4936 5400 for (i = 0; i < 1024 && rc == 0; i++) 4937 5401 rc = kwExecCmdLine(argv[1], argv[2]); 5402 # endif 5403 return rc; 5404 4938 5405 #endif 4939 return rc; 4940 } 4941 5406 } 5407 -
trunk/src/kmk/Makefile.kmk
r2843 r2844 88 88 kmkbuiltin/setmode.c \ 89 89 kmkbuiltin/strmode.c \ 90 kmkbuiltin/kbuild_version.c \91 90 kmkbuiltin/kbuild_protection.c \ 92 91 getopt.c \ -
trunk/src/kmk/job.c
r2843 r2844 1318 1318 assert (*p2); 1319 1319 set_command_state (child->file, cs_running); 1320 child->deleted = 0; 1320 1321 child->pid = 0; 1321 1322 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); 1323 1324 else 1324 1325 { … … 1326 1327 while (argv[argc]) 1327 1328 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); 1329 1330 } 1330 1331 … … 1334 1335 # endif 1335 1336 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) 1342 1338 { 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; 1345 1349 } 1346 1350 -
trunk/src/kmk/kmkbuiltin.h
r2843 r2844 35 35 #endif 36 36 37 #include "kbuild_version.h" 38 37 39 int kmk_builtin_command(const char *pszCmd, struct child *pChild, char ***ppapszArgvToSpawn, pid_t *pPidSpawned); 38 40 int kmk_builtin_command_parsed(int argc, char **argv, struct child *pChild, char ***ppapszArgvToSpawn, pid_t *pPidSpawned); … … 69 71 extern char *kmk_builtin_func_printf(char *o, char **argv, const char *funcname); 70 72 71 extern int kbuild_version(const char *);72 73 73 #endif 74 74 -
trunk/src/kmk/kmkbuiltin/kSubmit.c
r2843 r2844 52 52 #ifdef KBUILD_OS_WINDOWS 53 53 # include "sub_proc.h" 54 # include "quote_argv.h" 54 55 #endif 55 56 … … 366 367 if (pWorker->OverlappedRead.hEvent != NULL) 367 368 { 368 char szHandleArg[ 16];369 char szHandleArg[32]; 369 370 const char *apszArgs[4] = { szExecutable, "--pipe", szHandleArg, NULL }; 370 371 _snprintf(szHandleArg, sizeof(szHandleArg), "%p", hWorkerPipe); … … 557 558 const char *pszCwd, uint32_t *pcbMsg) 558 559 { 559 size_t i;560 560 size_t cbTmp; 561 uint32_t i; 561 562 uint32_t cbMsg; 563 uint32_t cArgs; 564 uint32_t cEnvVars; 562 565 uint8_t *pbMsg; 563 566 uint8_t *pbCursor; 567 568 /* 569 * Adjust input. 570 */ 571 if (!pszExecutable) 572 pszExecutable = papszArgs[0]; 564 573 565 574 /* … … 569 578 cbMsg += sizeof("JOB"); 570 579 cbMsg += strlen(pszExecutable) + 1; 571 580 cbMsg += strlen(pszCwd) + 1; 581 582 cbMsg += sizeof(cArgs); 572 583 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); 576 588 for (i = 0; papszEnvVars[i] != NULL; i++) 577 589 cbMsg += strlen(papszEnvVars[i]) + 1; 578 cbMsg += 1; 579 580 cbMsg += strlen(pszCwd) + 1; 590 cEnvVars = i; 591 581 592 582 593 /* … … 594 605 pbCursor += cbTmp; 595 606 607 cbTmp = strlen(pszCwd) + 1; 608 memcpy(pbCursor, pszCwd, cbTmp); 609 pbCursor += cbTmp; 610 611 memcpy(pbCursor, &cArgs, sizeof(cArgs)); 612 pbCursor += sizeof(cArgs); 596 613 for (i = 0; papszArgs[i] != NULL; i++) 597 614 { 615 *pbCursor++ = 0; /* Argument expansion flags (MSC, EMX). */ 598 616 cbTmp = strlen(papszArgs[i]) + 1; 599 617 memcpy(pbCursor, papszArgs[i], cbTmp); 600 618 pbCursor += cbTmp; 601 619 } 602 *pbCursor++ = '\0'; 603 620 assert(i == cArgs); 621 622 memcpy(pbCursor, &cEnvVars, sizeof(cEnvVars)); 623 pbCursor += sizeof(cEnvVars); 604 624 for (i = 0; papszEnvVars[i] != NULL; i++) 605 625 { … … 608 628 pbCursor += cbTmp; 609 629 } 610 *pbCursor++ = '\0'; 611 612 cbTmp = strlen(pszCwd) + 1; 613 memcpy(pbCursor, pszCwd, cbTmp); 614 pbCursor += cbTmp; 630 assert(i == cEnvVars); 615 631 616 632 assert(pbCursor - pbMsg == (size_t)cbMsg); … … 780 796 /** 781 797 * Used by 782 * @returns 0 if we got the whole result, -1 if I/O is pending, windows last798 * @returns 0 if we got the whole result, -1 if I/O is pending, and windows last 783 799 * error on ReadFile failure. 784 800 * @param pWorker The worker instance. … … 806 822 DWORD dwErr = GetLastError(); 807 823 if (dwErr == ERROR_IO_PENDING) 808 return 1;809 return kSubmitWinReadFailed(pWorker, GetLastError());824 return -1; 825 return kSubmitWinReadFailed(pWorker, dwErr); 810 826 } 811 827 … … 849 865 if (rc == -1) 850 866 { 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) 852 868 { /* likely */ } 853 869 else … … 873 889 */ 874 890 pWorker->pBusyWith = pChild; 891 #ifndef KBUILD_OS_WINDOWS 875 892 *pPidSpawned = pWorker->pid; 893 #endif 876 894 877 895 kSubmitListUnlink(&g_IdleList, pWorker); … … 977 995 PWORKERINSTANCE apWorkers[MAXIMUM_WAIT_OBJECTS]; 978 996 HANDLE ahHandles[MAXIMUM_WAIT_OBJECTS]; 979 DWORD cHandles ;997 DWORD cHandles = 0; 980 998 981 999 for (pWorker = g_IdleList.pHead; pWorker != NULL; pWorker = pWorker->pNext) … … 1329 1347 1330 1348 papszEnv = pChild->environment; 1331 if ( papszEnv)1349 if (!papszEnv) 1332 1350 pChild->environment = papszEnv = target_environment(pChild->file); 1333 1351 cEnvVars = 0; … … 1495 1513 if (pWorker) 1496 1514 { 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 1497 1523 rcExit = kSubmitSendJobMessage(pWorker, pvMsg, cbMsg, 0 /*fNoRespawning*/, cVerbosity); 1498 1524 if (rcExit == 0) … … 1502 1528 if (atexit(kSubmitAtExitCallback) == 0) 1503 1529 g_fAtExitRegistered = 1; 1530 1531 #ifdef KBUILD_OS_WINDOWS 1532 free(pszFreeExec); 1533 #endif 1504 1534 } 1505 1535 else -
trunk/src/kmk/w32/include/sub_proc.h
r2843 r2844 49 49 EXTERN_DECL(int process_used_slots, (VOID_DECL)); 50 50 #ifdef KMK 51 EXTERN_DECL(int process_kmk_register_submit, (HANDLE hEvent, intptr_t clue ));51 EXTERN_DECL(int process_kmk_register_submit, (HANDLE hEvent, intptr_t clue, pid_t *pPid)); 52 52 #endif 53 53 -
trunk/src/kmk/w32/subproc/sub_proc.c
r2843 r2844 206 206 * @param hEvent The event semaphore to wait on. 207 207 * @param clue The clue to base. 208 * @param pPid Where to return the pid that job.c expects. 208 209 */ 209 210 int 210 process_kmk_register_submit(HANDLE hEvent, intptr_t clue )211 process_kmk_register_submit(HANDLE hEvent, intptr_t clue, pid_t *pPid) 211 212 { 212 213 if (proc_index < MAXIMUM_WAIT_OBJECTS) { … … 217 218 218 219 proc_array[proc_index++] = pSubProc; 220 *pPid = (HANDLE)pSubProc; 219 221 return 0; 220 222 } -
trunk/src/lib/Makefile.kmk
r2838 r2844 39 39 kUtil_SOURCES = \ 40 40 crc32.c \ 41 md5.c 41 md5.c \ 42 kbuild_version.c 42 43 kUtil_SOURCES.win = \ 43 44 nt_fullpath.c \ … … 54 55 # restartable-syscall-wrappers.c 55 56 kUtil_NOINST = 1 57 58 kbuild_version.c_DEFS = KBUILD_SVN_REV=$(KBUILD_SVN_REV) 56 59 57 60 LIBRARIES.win += kWinStartup -
trunk/src/lib/kbuild_version.c
r2837 r2844 5 5 6 6 /* 7 * Copyright (c) 2007-201 0knut st. osmundsen <[email protected]>7 * Copyright (c) 2007-2016 knut st. osmundsen <[email protected]> 8 8 * 9 9 * This file is part of kBuild. … … 27 27 * Header Files * 28 28 *******************************************************************************/ 29 #include "config.h" 30 #include "kmkbuiltin.h" 29 #include "kbuild_version.h" 31 30 #include <string.h> 32 31 #include <stdio.h>
Note:
See TracChangeset
for help on using the changeset viewer.