- Timestamp:
- Mar 28, 2018, 6:11:30 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/w32/winchildren.c
r3196 r3197 101 101 102 102 #include "nt/nt_child_inject_standard_handles.h" 103 #include "console.h" 103 104 104 105 #ifndef KMK_BUILTIN_STANDALONE … … 111 112 *********************************************************************************************************************************/ 112 113 #define MKWINCHILD_MAX_PATH 1024 114 115 #define MKWINCHILD_DO_SET_PROCESSOR_GROUP 113 116 114 117 /** Checks the UTF-16 environment variable pointed to is the PATH. */ … … 125 128 * Structures and Typedefs * 126 129 *********************************************************************************************************************************/ 130 /** Pointer to a childcare worker thread. */ 131 typedef struct WINCHILDCAREWORKER *PWINCHILDCAREWORKER; 132 /** Pointer to a windows child process. */ 133 typedef struct WINCHILD *PWINCHILD; 134 127 135 /** 128 136 * Child process type. … … 148 156 149 157 150 /** Pointer to a windows child process. */151 typedef struct WINCHILD *PWINCHILD;152 158 /** 153 159 * Windows child process. … … 175 181 * annoying source name output. */ 176 182 BOOL fProbableClExe; 183 /** The worker executing this child. */ 184 PWINCHILDCAREWORKER pWorker; 177 185 178 186 /** Type specific data. */ … … 334 342 long volatile fIdle; 335 343 } WINCHILDCAREWORKER; 336 /** Pointer to a childcare worker thread. */337 typedef WINCHILDCAREWORKER *PWINCHILDCAREWORKER;338 344 /** WINCHILD::uMagic value. */ 339 345 #define WINCHILDCAREWORKER_MAGIC 0xdad0dad0U … … 616 622 617 623 /** 624 * Output error message while running on a worker thread. 625 * 626 * @returns -1 627 * @param pWorker The calling worker. Mainly for getting the 628 * current child and its stderr output unit. Pass 629 * NULL if the output should go thru the child 630 * stderr buffering. 631 * @param iType The error type: 632 * - 0: more of a info directly to stdout, 633 * - 1: child related error, 634 * - 2: child related error for immedate release. 635 * @param pszFormat The message format string. 636 * @param ... Argument for the message. 637 */ 638 static int MkWinChildError(PWINCHILDCAREWORKER pWorker, int iType, const char *pszFormat, ...) 639 { 640 /* 641 * Format the message into stack buffer. 642 */ 643 char szMsg[4096]; 644 int cchMsg; 645 int cchPrefix; 646 va_list va; 647 648 /* Compose the prefix, being paranoid about it not exceeding the buffer in any way. */ 649 const char *pszInfix = iType == 0 ? "info: " : "error: "; 650 const char *pszProgram = program; 651 if (strlen(pszProgram) > 80) 652 { 653 #ifdef KMK 654 pszProgram = "kmk"; 655 #else 656 pszProgram = "gnumake"; 657 #endif 658 } 659 if (makelevel == 0) 660 cchPrefix = snprintf(szMsg, sizeof(szMsg) / 2, "%s: %s", pszProgram, pszInfix); 661 else 662 cchPrefix = snprintf(szMsg, sizeof(szMsg) / 2, "%s[%u]: %s", pszProgram, makelevel, pszInfix); 663 assert(cchPrefix < sizeof(szMsg) / 2 && cchPrefix > 0); 664 665 /* Format the user specified message. */ 666 va_start(va, pszFormat); 667 cchMsg = vsnprintf(&szMsg[cchPrefix], sizeof(szMsg) - 2 - cchPrefix, pszFormat, va); 668 va_end(va); 669 szMsg[sizeof(szMsg) - 2] = '\0'; 670 cchMsg = strlen(szMsg); 671 672 /* Make sure there's a newline at the end of it (we reserved space for that). */ 673 if (cchMsg <= 0 || szMsg[cchMsg - 1] != '\n') 674 { 675 szMsg[cchMsg++] = '\n'; 676 szMsg[cchMsg] = '\0'; 677 } 678 679 #ifdef CONFIG_WITH_OUTPUT_IN_MEMORY 680 /* 681 * Try use the stderr of the current child of the worker. 682 */ 683 if ( iType != 0 684 && iType != 3 685 && pWorker) 686 { 687 PWINCHILD pChild = pWorker->pCurChild; 688 if (pChild) 689 { 690 struct child *pMkChild = pChild->pMkChild; 691 if (pMkChild) 692 { 693 output_write_text(&pMkChild->output, 1 /*is_err*/, szMsg, cchMsg); 694 return -1; 695 } 696 } 697 } 698 #endif 699 700 /* 701 * Fallback to writing directly to stderr. 702 */ 703 maybe_con_fwrite(szMsg, cchMsg, 1, iType == 0 ? stdout : stderr); 704 return -1; 705 } 706 707 /** 618 708 * Duplicates the given UTF-16 string. 619 709 * … … 816 906 else 817 907 { 818 fprintf(stderr, "warning:GetOverlappedResult failed: %u\n", GetLastError());908 MkWinChildError(pChild->pWorker, 2, "GetOverlappedResult failed: %u\n", GetLastError()); 819 909 pPipe->fReadPending = FALSE; 820 910 if (fDraining) … … 844 934 pPipe->fReadPending = TRUE; 845 935 else 846 fprintf(stderr, "warning:ReadFile failed on standard %s: %u\n",847 pPipe->iWhich == 1 ? "output" : "error", GetLastError());936 MkWinChildError(pChild->pWorker, 2, "ReadFile failed on standard %s: %u\n", 937 pPipe->iWhich == 1 ? "output" : "error", GetLastError()); 848 938 return; 849 939 } … … 956 1046 || !pChild->pMkChild->file 957 1047 || !pChild->pMkChild->file->name) 958 printf("Pid %u ('%s') still running after %u seconds\n",959 GetProcessId(hProcess), pwszJob, (msNow - msStart) / 1000);1048 MkWinChildError(NULL, 0, "Pid %u ('%s') still running after %u seconds\n", 1049 GetProcessId(hProcess), pwszJob, (msNow - msStart) / 1000); 960 1050 else 961 printf("Target '%s' (pid %u) still running after %u seconds\n",962 pChild->pMkChild->file->name, GetProcessId(hProcess), (msNow - msStart) / 1000);1051 MkWinChildError(NULL, 0, "Target '%s' (pid %u) still running after %u seconds\n", 1052 pChild->pMkChild->file->name, GetProcessId(hProcess), (msNow - msStart) / 1000); 963 1053 } 964 1054 … … 1094 1184 else 1095 1185 { 1096 fprintf(stderr, "CreateProcess(%ls) failed: %u\n", pwszImageName, dwErr);1186 MkWinChildError(pWorker, 1, "CreateProcess(%ls) failed: %u\n", pwszImageName, dwErr); 1097 1187 return (int)dwErr; 1098 1188 } … … 1125 1215 dwErr = nt_child_inject_standard_handles(ProcInfo.hProcess, pafReplace, pahChild, szErrMsg, sizeof(szErrMsg)); 1126 1216 if (dwErr != 0) 1127 fprintf(stderr, "%s\n", szErrMsg);1217 MkWinChildError(pWorker, 1, "%s\n", szErrMsg); 1128 1218 } 1129 1219 … … 1131 1221 * Assign processor group (ignore failure). 1132 1222 */ 1223 #ifdef MKWINCHILD_DO_SET_PROCESSOR_GROUP 1133 1224 if (g_cProcessorGroups > 1) 1134 1225 { 1135 GROUP_AFFINITY Affinity = { ~(ULONG_PTR)0, pWorker->iProcessorGroup, { 0, 0, 0 } };1226 GROUP_AFFINITY Affinity = { 0, pWorker->iProcessorGroup, { 0, 0, 0 } }; 1136 1227 fRet = g_pfnSetThreadGroupAffinity(ProcInfo.hThread, &Affinity, NULL); 1137 1228 assert(fRet); 1138 1229 } 1230 #endif 1139 1231 1140 1232 #ifdef KMK … … 1164 1256 { 1165 1257 dwErr = GetLastError(); 1166 fprintf(stderr, "ResumeThread failed on child process: %u\n", dwErr);1258 MkWinChildError(pWorker, 1, "ResumeThread failed on child process: %u\n", dwErr); 1167 1259 } 1168 1260 } … … 1185 1277 * 1186 1278 * @returns 0 on success, non-zero on failure. 1279 * @param pWorker The childcare worker. 1187 1280 * @param papszArgs The argument vector to convert. 1188 1281 * @param ppwszCommandLine Where to return the command line. 1189 1282 */ 1190 static int mkWinChildcareWorkerConvertQuotedArgvToCommandline(char **papszArgs, WCHAR **ppwszCommandLine) 1283 static int mkWinChildcareWorkerConvertQuotedArgvToCommandline(PWINCHILDCAREWORKER pWorker, char **papszArgs, 1284 WCHAR **ppwszCommandLine) 1191 1285 { 1192 1286 WCHAR *pwszCmdLine; … … 1207 1301 { 1208 1302 DWORD dwErr = GetLastError(); 1209 fprintf(stderr, _("MultiByteToWideChar failed to convert argv[%u] (%s): %u\n"), i, pszSrc, dwErr);1303 MkWinChildError(pWorker, 1, _("MultiByteToWideChar failed to convert argv[%u] (%s): %u\n"), i, pszSrc, dwErr); 1210 1304 return dwErr; 1211 1305 } … … 1231 1325 { 1232 1326 DWORD dwErr = GetLastError(); 1233 fprintf(stderr, _("MultiByteToWideChar failed to convert argv[%u] (%s): %u\n"), i, pszSrc, dwErr);1327 MkWinChildError(pWorker, 1, _("MultiByteToWideChar failed to convert argv[%u] (%s): %u\n"), i, pszSrc, dwErr); 1234 1328 free(pwszCmdLine); 1235 1329 return dwErr; … … 1253 1347 #define MKWCCWCMD_F_HAVE_KASH_C 8 /**< kmk_ash -c "..." */ 1254 1348 1255 static int mkWinChildcareWorkerConvertCommandline(char **papszArgs, unsigned fFlags, WCHAR **ppwszCommandLine) 1349 /* 1350 * @param pWorker The childcare worker if on one, otherwise NULL. 1351 */ 1352 static int mkWinChildcareWorkerConvertCommandline(PWINCHILDCAREWORKER pWorker, char **papszArgs, unsigned fFlags, 1353 WCHAR **ppwszCommandLine) 1256 1354 { 1257 1355 struct ARGINFO … … 1310 1408 { 1311 1409 DWORD dwErr = GetLastError(); 1312 fprintf(stderr, _("MultiByteToWideChar failed to convert argv[%u] (%s): %u\n"), i, pszSrc, dwErr);1410 MkWinChildError(pWorker, 1, _("MultiByteToWideChar failed to convert argv[%u] (%s): %u\n"), i, pszSrc, dwErr); 1313 1411 return dwErr; 1314 1412 } … … 1479 1577 } 1480 1578 1481 static int mkWinChildcareWorkerConvertCommandlineWithShell(const WCHAR *pwszShell, char **papszArgs, WCHAR **ppwszCommandLine) 1482 { 1483 fprintf(stderr, "%s: not found!\n", papszArgs[0]); 1579 static int mkWinChildcareWorkerConvertCommandlineWithShell(PWINCHILDCAREWORKER pWorker, const WCHAR *pwszShell, char **papszArgs, 1580 WCHAR **ppwszCommandLine) 1581 { 1582 MkWinChildError(pWorker, 1, "%s: not found!\n", papszArgs[0]); 1484 1583 //__debugbreak(); 1485 1584 return ERROR_FILE_NOT_FOUND; … … 1573 1672 * 1574 1673 * @returns 0 on success, windows error code on failure. 1674 * @param pWorker The childcare worker. 1575 1675 * @param pszArg0 The first argument. 1576 1676 * @param pwszSearchPath In case mkWinChildcareWorkerConvertEnvironment … … 1584 1684 * @param pfProbableClExe Where to return an indicator of probably CL.EXE. 1585 1685 */ 1586 static int mkWinChildcareWorkerFindImage(char const *pszArg0, WCHAR *pwszSearchPath, WCHAR const *pwszzEnv, 1587 const char *pszShell, WCHAR **ppwszImagePath, BOOL *pfNeedShell, BOOL *pfProbableClExe) 1686 static int mkWinChildcareWorkerFindImage(PWINCHILDCAREWORKER pWorker, char const *pszArg0, WCHAR *pwszSearchPath, 1687 WCHAR const *pwszzEnv, const char *pszShell, 1688 WCHAR **ppwszImagePath, BOOL *pfNeedShell, BOOL *pfProbableClExe) 1588 1689 { 1589 1690 /** @todo Slap a cache on this code. We usually end up executing the same … … 1881 1982 return mkWinChildDuplicateUtf16String(wszPathBuf, cwc, ppwszImagePath); 1882 1983 dwErr = GetLastError(); 1883 fprintf(stderr, _("MultiByteToWideChar failed to convert shell (%s): %u\n"), pszShell, dwErr);1984 MkWinChildError(pWorker, 1, _("MultiByteToWideChar failed to convert shell (%s): %u\n"), pszShell, dwErr); 1884 1985 } 1885 1986 else 1886 1987 { 1887 fprintf(stderr, "%s: not found!\n", pszArg0);1988 MkWinChildError(pWorker, 1, "%s: not found!\n", pszArg0); 1888 1989 dwErr = ERROR_FILE_NOT_FOUND; 1889 1990 } … … 1892 1993 { 1893 1994 dwErr = GetLastError(); 1894 fprintf(stderr, _("MultiByteToWideChar failed to convert argv[0] (%s): %u\n"), pszArg0, dwErr);1995 MkWinChildError(pWorker, 1, _("MultiByteToWideChar failed to convert argv[0] (%s): %u\n"), pszArg0, dwErr); 1895 1996 } 1896 1997 return dwErr == ERROR_INSUFFICIENT_BUFFER ? ERROR_FILENAME_EXCED_RANGE : dwErr; … … 1901 2002 * 1902 2003 * @returns 0 on success, windows error code on failure. 2004 * @param pWorker The childcare worker if on one, otherwise NULL. 1903 2005 * @param papszEnv The environment vector to convert. 1904 2006 * @param cbEnvStrings The size of the environment strings, iff they are … … 1911 2013 * mkWinChildcareWorkerFindImage() search when needed. 1912 2014 */ 1913 static int mkWinChildcareWorkerConvertEnvironment( char **papszEnv, size_t cbEnvStrings,2015 static int mkWinChildcareWorkerConvertEnvironment(PWINCHILDCAREWORKER pWorker, char **papszEnv, size_t cbEnvStrings, 1914 2016 WCHAR **ppwszEnv, WCHAR const **ppwszSearchPath) 1915 2017 { … … 1953 2055 dwErr = GetLastError(); 1954 2056 } 1955 fprintf(stderr, _("MultiByteToWideChar failed to convert environment block: %u\n"), dwErr);2057 MkWinChildError(pWorker, 1, _("MultiByteToWideChar failed to convert environment block: %u\n"), dwErr); 1956 2058 } 1957 2059 /* … … 2031 2133 if (cwcRc <= 0) 2032 2134 { 2033 fprintf(stderr, _("MultiByteToWideChar failed to convert environment string #%u (%s): %u\n"),2034 iVar, pszSrc, dwErr);2135 MkWinChildError(pWorker, 1, _("MultiByteToWideChar failed to convert environment string #%u (%s): %u\n"), 2136 iVar, pszSrc, dwErr); 2035 2137 free(pwszzDst); 2036 2138 return dwErr; … … 2077 2179 * search for the executable. 2078 2180 */ 2079 rc = mkWinChildcareWorkerConvertEnvironment(p Child->u.Process.papszEnv ? pChild->u.Process.papszEnv : environ,2181 rc = mkWinChildcareWorkerConvertEnvironment(pWorker, pChild->u.Process.papszEnv ? pChild->u.Process.papszEnv : environ, 2080 2182 pChild->u.Process.cbEnvStrings, 2081 2183 &pwszzEnvironment, &pwszSearchPath); … … 2085 2187 */ 2086 2188 if (rc == 0) 2087 rc = mkWinChildcareWorkerFindImage(p Child->u.Process.papszArgs[0], pwszSearchPath, pwszzEnvironment,2189 rc = mkWinChildcareWorkerFindImage(pWorker, pChild->u.Process.papszArgs[0], pwszSearchPath, pwszzEnvironment, 2088 2190 pChild->u.Process.pszShell, &pwszImageName, &fNeedShell, &pChild->fProbableClExe); 2089 2191 if (rc == 0) 2090 2192 { 2091 2193 if (!fNeedShell) 2092 rc = mkWinChildcareWorkerConvertCommandline(p Child->u.Process.papszArgs, 0 /*fFlags*/, &pwszCommandLine);2194 rc = mkWinChildcareWorkerConvertCommandline(pWorker, pChild->u.Process.papszArgs, 0 /*fFlags*/, &pwszCommandLine); 2093 2195 else 2094 rc = mkWinChildcareWorkerConvertCommandlineWithShell(pwszImageName, pChild->u.Process.papszArgs, &pwszCommandLine); 2196 rc = mkWinChildcareWorkerConvertCommandlineWithShell(pWorker, pwszImageName, pChild->u.Process.papszArgs, 2197 &pwszCommandLine); 2095 2198 2096 2199 /* … … 2184 2287 return; 2185 2288 } 2186 fprintf(stderr, "kmk_builtin_append: close failed on '%s': %u (%s)\n",2187 pChild->u.Append.pszFilename, errno, strerror(errno));2289 MkWinChildError(pWorker, 1, "kmk_builtin_append: close failed on '%s': %u (%s)\n", 2290 pChild->u.Append.pszFilename, errno, strerror(errno)); 2188 2291 } 2189 2292 else 2190 fprintf(stderr, "kmk_builtin_append: error writing %lu bytes to on '%s': %u (%s)\n",2191 pChild->u.Append.cbAppend, pChild->u.Append.pszFilename, errno, strerror(errno));2293 MkWinChildError(pWorker, 1, "kmk_builtin_append: error writing %lu bytes to on '%s': %u (%s)\n", 2294 pChild->u.Append.cbAppend, pChild->u.Append.pszFilename, errno, strerror(errno)); 2192 2295 close(fd); 2193 2296 } 2194 2297 else 2195 fprintf(stderr, "kmk_builtin_append: error opening '%s': %u (%s)\n",2196 pChild->u.Append.pszFilename, errno, strerror(errno));2298 MkWinChildError(pWorker, 1, "kmk_builtin_append: error opening '%s': %u (%s)\n", 2299 pChild->u.Append.pszFilename, errno, strerror(errno)); 2197 2300 pChild->iExitCode = 1; 2198 2301 } … … 2251 2354 assert(pWorker->uMagic == WINCHILDCAREWORKER_MAGIC); 2252 2355 2356 #ifdef MKWINCHILD_DO_SET_PROCESSOR_GROUP 2253 2357 /* 2254 2358 * Adjust process group if necessary. 2359 * 2360 * Note! It seems that setting the mask to zero means that we select all 2361 * active processors. Couldn't find any alternative API for getting 2362 * the correct active processor mask. 2255 2363 */ 2256 2364 if (g_cProcessorGroups > 1) 2257 2365 { 2258 GROUP_AFFINITY Affinity = { ~(ULONG_PTR)0, pWorker->iProcessorGroup, { 0, 0, 0 } };2366 GROUP_AFFINITY Affinity = { 0 /* == all active apparently */ , pWorker->iProcessorGroup, { 0, 0, 0 } }; 2259 2367 BOOL fRet = g_pfnSetThreadGroupAffinity(GetCurrentThread(), &Affinity, NULL); 2260 2368 assert(fRet); (void)fRet; 2261 } 2369 # ifndef NDEBUG 2370 { 2371 GROUP_AFFINITY ActualAffinity = { 0xbeefbeefU, 0xbeef, { 0xbeef, 0xbeef, 0xbeef } }; 2372 fRet = GetThreadGroupAffinity(GetCurrentThread(), &ActualAffinity); 2373 assert(fRet); (void)fRet; 2374 assert(ActualAffinity.Group == pWorker->iProcessorGroup); 2375 } 2376 # endif 2377 } 2378 #endif 2262 2379 2263 2380 /* … … 2304 2421 PWINCHILD pTailExpect; 2305 2422 2423 pChild->pWorker = pWorker; 2306 2424 pWorker->pCurChild = pChild; 2307 2425 switch (pChild->enmType) … … 2328 2446 } 2329 2447 pWorker->pCurChild = NULL; 2448 pChild->pWorker = NULL; 2330 2449 2331 2450 /* … … 2347 2466 if (SetEvent(g_hEvtWaitChildren)) 2348 2467 break; 2349 fprintf(stderr, "SetEvent(g_hEvtWaitChildren=%p) failed: %u\n", g_hEvtWaitChildren, GetLastError()); 2468 MkWinChildError(pWorker, 1, "SetEvent(g_hEvtWaitChildren=%p) failed: %u\n", 2469 g_hEvtWaitChildren, GetLastError()); 2350 2470 break; 2351 2471 } … … 2524 2644 2525 2645 /* Bail out! */ 2526 fprintf(stderr, "warning!_beginthreadex failed: %u (%s)\n", errno, strerror(errno));2646 ONS (error, NILF, "_beginthreadex failed: %u (%s)\n", errno, strerror(errno)); 2527 2647 mkWinChildcareDeleteWorkerPipe(&pWorker->StdErr); 2528 2648 } 2529 2649 else 2530 fprintf(stderr, "warning!Failed to create stderr pipe: %u\n", GetLastError());2650 ON (error, NILF, "Failed to create stderr pipe: %u\n", GetLastError()); 2531 2651 mkWinChildcareDeleteWorkerPipe(&pWorker->StdOut); 2532 2652 } 2533 2653 else 2534 fprintf(stderr, "warning!Failed to create stdout pipe: %u\n", GetLastError());2654 ON (error, NILF, "Failed to create stdout pipe: %u\n", GetLastError()); 2535 2655 CloseHandle(pWorker->hEvtIdle); 2536 2656 } 2537 2657 else 2538 fprintf(stderr, "warning!CreateEvent failed: %u\n", GetLastError());2658 ON (error, NILF, "CreateEvent failed: %u\n", GetLastError()); 2539 2659 pWorker->uMagic = ~WINCHILDCAREWORKER_MAGIC; 2540 2660 free(pWorker); … … 3061 3181 { 3062 3182 rc = GetLastError(); 3063 fprintf(stderr, _("MultiByteToWideChar failed to convert CWD (%s): %u\n"), pszCwd, (unsigned)rc);3183 MkWinChildError(pWorker, 1, _("MultiByteToWideChar failed to convert CWD (%s): %u\n"), pszCwd, (unsigned)rc); 3064 3184 return rc; 3065 3185 } … … 3070 3190 * have to traverse it twice to find the PATH. 3071 3191 */ 3072 rc = mkWinChildcareWorkerConvertEnvironment(p apszEnvVars ? papszEnvVars : environ, 0/*cbEnvStrings*/,3192 rc = mkWinChildcareWorkerConvertEnvironment(pWorker, papszEnvVars ? papszEnvVars : environ, 0/*cbEnvStrings*/, 3073 3193 &pwszzEnvironment, &pwszSearchPath); 3074 3194 /* … … 3077 3197 */ 3078 3198 if (rc == 0) 3079 rc = mkWinChildcareWorkerFindImage(p szExecutable, pwszSearchPath, pwszzEnvironment, NULL /*pszShell*/,3199 rc = mkWinChildcareWorkerFindImage(pWorker, pszExecutable, pwszSearchPath, pwszzEnvironment, NULL /*pszShell*/, 3080 3200 &pwszImageName, &fNeedShell, &pChild->fProbableClExe); 3081 3201 if (rc == 0) … … 3083 3203 assert(!fNeedShell); 3084 3204 if (!fQuotedArgv) 3085 rc = mkWinChildcareWorkerConvertCommandline(p apszArgs, 0 /*fFlags*/, &pwszCommandLine);3205 rc = mkWinChildcareWorkerConvertCommandline(pWorker, papszArgs, 0 /*fFlags*/, &pwszCommandLine); 3086 3206 else 3087 rc = mkWinChildcareWorkerConvertQuotedArgvToCommandline(p apszArgs, &pwszCommandLine);3207 rc = mkWinChildcareWorkerConvertQuotedArgvToCommandline(pWorker, papszArgs, &pwszCommandLine); 3088 3208 3089 3209 /* … … 3281 3401 * Create the command line and environment. 3282 3402 */ 3283 rc = mkWinChildcareWorkerConvertCommandline( papszArgs, 0 /*fFlags*/, &pwszCommandLine);3403 rc = mkWinChildcareWorkerConvertCommandline(NULL, papszArgs, 0 /*fFlags*/, &pwszCommandLine); 3284 3404 if (rc != 0) 3285 3405 ON(fatal, NILF, _("MkWinChildReExecMake: mkWinChildcareWorkerConvertCommandline failed: %u\n"), rc); 3286 3406 3287 rc = mkWinChildcareWorkerConvertEnvironment( papszEnv ? papszEnv : environ, 0 /*cbEnvStrings*/,3407 rc = mkWinChildcareWorkerConvertEnvironment(NULL, papszEnv ? papszEnv : environ, 0 /*cbEnvStrings*/, 3288 3408 &pwszzEnvironment, &pwszPathIgnored); 3289 3409 if (rc != 0)
Note:
See TracChangeset
for help on using the changeset viewer.