Changeset 3192 in kBuild for trunk/src/kmk/kmkbuiltin/redirect.c
- Timestamp:
- Mar 26, 2018 8:25:56 PM (7 years ago)
- File:
-
- 1 edited
-
trunk/src/kmk/kmkbuiltin/redirect.c (modified) (87 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/redirect.c
r3179 r3192 69 69 # include "nt/nt_child_inject_standard_handles.h" 70 70 #endif 71 #if defined(__gnu_hurd__) && !defined( kmk_builtin_redirect) /* need constant */71 #if defined(__gnu_hurd__) && !defined(KMK_BUILTIN_STANDALONE) /* need constant */ 72 72 # undef GET_PATH_MAX 73 73 # undef PATH_MAX … … 107 107 108 108 109 static const char *name(const char *pszName)109 static int kmk_redirect_usage(PKMKBUILTINCTX pCtx, int fIsErr) 110 110 { 111 const char *psz = strrchr(pszName, '/'); 112 #if defined(_MSC_VER) || defined(__OS2__) 113 const char *psz2 = strrchr(pszName, '\\'); 114 if (!psz2) 115 psz2 = strrchr(pszName, ':'); 116 if (psz2 && (!psz || psz2 > psz)) 117 psz = psz2; 118 #endif 119 return psz ? psz + 1 : pszName; 120 } 121 122 123 static int usage(FILE *pOut, const char *argv0) 124 { 125 argv0 = name(argv0); 126 fprintf(pOut, 127 "usage: %s [-[rwa+tb]<fd> <file>] [-d<fd>=<src-fd>] [-c<fd>]\n" 128 " [-Z] [-E <var=val>] [-C <dir>] [--wcc-brain-damage]\n" 129 " [-v] -- <program> [args]\n" 130 " or: %s --help\n" 131 " or: %s --version\n" 132 "\n" 133 "The rwa+tb is like for fopen, if not specified it defaults to w+.\n" 134 "The <fd> is either a number or an alias for the standard handles:\n" 135 " i = stdin\n" 136 " o = stdout\n" 137 " e = stderr\n" 138 "\n" 139 "The -d switch duplicate the right hand file descriptor (src-fd) to the left\n" 140 "hand side one (fd). The latter is limited to standard handles on windows.\n" 141 "\n" 142 "The -c switch will close the specified file descriptor. Limited to standard\n" 143 "handles on windows.\n" 144 "\n" 145 "The -Z switch zaps the environment.\n" 146 "\n" 147 "The -E switch is for making changes to the environment in a putenv\n" 148 "fashion.\n" 149 "\n" 150 "The -C switch is for changing the current directory. Please specify an\n" 151 "absolute program path as it's platform dependent whether this takes effect\n" 152 "before or after the executable is located.\n" 153 "\n" 154 "The --wcc-brain-damage switch is to work around wcc and wcc386 (Open Watcom)\n" 155 "not following normal quoting conventions on Windows, OS/2, and DOS.\n" 156 "\n" 157 "The -v switch is for making the thing more verbose.\n" 158 "\n" 159 "This command was originally just a quick hack to avoid invoking the shell\n" 160 "on Windows (cygwin) where forking is very expensive and has exhibited\n" 161 "stability issues on SMP machines. It has since grown into something like\n" 162 "/usr/bin/env on steroids.\n" 163 , 164 argv0, argv0, argv0); 111 kmk_builtin_ctx_printf(pCtx, fIsErr, 112 "usage: %s [-[rwa+tb]<fd> <file>] [-d<fd>=<src-fd>] [-c<fd>]\n" 113 " [-Z] [-E <var=val>] [-C <dir>] [--wcc-brain-damage]\n" 114 " [-v] -- <program> [args]\n" 115 " or: %s --help\n" 116 " or: %s --version\n" 117 "\n" 118 "The rwa+tb is like for fopen, if not specified it defaults to w+.\n" 119 "The <fd> is either a number or an alias for the standard handles:\n" 120 " i = stdin\n" 121 " o = stdout\n" 122 " e = stderr\n" 123 "\n" 124 "The -d switch duplicate the right hand file descriptor (src-fd) to the left\n" 125 "hand side one (fd). The latter is limited to standard handles on windows.\n" 126 "\n" 127 "The -c switch will close the specified file descriptor. Limited to standard\n" 128 "handles on windows.\n" 129 "\n" 130 "The -Z switch zaps the environment.\n" 131 "\n" 132 "The -E switch is for making changes to the environment in a putenv\n" 133 "fashion.\n" 134 "\n" 135 "The -C switch is for changing the current directory. Please specify an\n" 136 "absolute program path as it's platform dependent whether this takes effect\n" 137 "before or after the executable is located.\n" 138 "\n" 139 "The --wcc-brain-damage switch is to work around wcc and wcc386 (Open Watcom)\n" 140 "not following normal quoting conventions on Windows, OS/2, and DOS.\n" 141 "\n" 142 "The -v switch is for making the thing more verbose.\n" 143 "\n" 144 "This command was originally just a quick hack to avoid invoking the shell\n" 145 "on Windows (cygwin) where forking is very expensive and has exhibited\n" 146 "stability issues on SMP machines. It has since grown into something like\n" 147 "/usr/bin/env on steroids.\n" 148 , 149 pCtx->pszProgName, pCtx->pszProgName, pCtx->pszProgName); 165 150 return 2; 166 151 } … … 198 183 199 184 200 #ifdef _MSC_VER201 202 /** Used by mscGetOsHandle. */203 static void __cdecl ignore_invalid_parameter(const wchar_t *a, const wchar_t *b, const wchar_t *c, unsigned d, uintptr_t e)204 {205 }206 207 /**208 * Safe way of getting the OS handle of a file descriptor without triggering209 * invalid parameter handling.210 *211 * @returns The handle value if open, INVALID_HANDLE_VALUE if not.212 * @param fd The file descriptor in question.213 */214 static HANDLE mscGetOsHandle(int fd)215 {216 intptr_t hHandle;217 _invalid_parameter_handler pfnOld = _get_invalid_parameter_handler();218 _set_invalid_parameter_handler(ignore_invalid_parameter);219 hHandle = _get_osfhandle(fd);220 _set_invalid_parameter_handler(pfnOld);221 return hHandle != -1 ? (HANDLE)hHandle : INVALID_HANDLE_VALUE;222 }223 224 /**225 * Checks if the specified file descriptor is open.226 *227 * @returns K_TRUE if open, K_FALSE if not.228 * @param fd The file descriptor in question.229 */230 static KBOOL mscIsOpenFile(int fd)231 {232 return mscGetOsHandle(fd) != INVALID_HANDLE_VALUE;233 }234 235 /**236 * Checks if the native handle is inheritable.237 *238 * @returns K_TRUE if it is, K_FALSE if it isn't or isn't a valid handle.239 * @param hHandle The native handle.240 */241 static KBOOL mscIsNativeHandleInheritable(HANDLE hHandle)242 {243 DWORD fFlags = 0;244 if (GetHandleInformation(hHandle, &fFlags))245 return (fFlags & HANDLE_FLAG_INHERIT) != 0;246 return K_FALSE;247 }248 249 /**250 * Checks if the file descriptor is inheritable or not.251 *252 * @returns K_TRUE if it is, K_FALSE if it isn't or isn't a valid descriptor.253 * @param fd The file descriptor in question.254 */255 static KBOOL mscIsInheritable(int fd)256 {257 HANDLE hHandle = mscGetOsHandle(fd);258 if (hHandle != INVALID_HANDLE_VALUE)259 return mscIsNativeHandleInheritable(hHandle);260 return K_FALSE;261 }262 263 /**264 * A dup3 like function.265 *266 * @returns fdNew on success, -1 on failure w/ error details written to pStdErr.267 * @param fdSource The source descriptor.268 * @param fdNew The new descriptor.269 * @param fFlags The inherit and text/binary mode flag.270 * @param pStdErr Working stderr to write error details to.271 */272 static int mscDup3(int fdSource, int fdNew, int fFlags, FILE *pStdErr)273 {274 if (!fFlags & _O_NOINHERIT)275 {276 /* ASSUMES fFlags doesn't include any changing _O_TEXT/_O_BINARY. */277 int fdDup = _dup2(fdSource, fdNew);278 if (fdDup != -1)279 return fdDup;280 fprintf(pStdErr, "%s: _dup2(%d,%d) failed: %s\n", g_progname, fdSource, fdNew, strerror(errno));281 }282 else283 {284 HANDLE hSource = mscGetOsHandle(fdSource);285 unsigned cTries = 0;286 int aFdTries[48];287 288 if (hSource != INVALID_HANDLE_VALUE)289 {290 HANDLE hCurProc = GetCurrentProcess();291 BOOL fInherit = !(fFlags & _O_NOINHERIT);292 293 /*294 * Make sure the old descriptor is closed and can be used again.295 */296 _invalid_parameter_handler pfnOld = _get_invalid_parameter_handler();297 _set_invalid_parameter_handler(ignore_invalid_parameter);298 close(fdNew);299 _set_invalid_parameter_handler(pfnOld);300 301 /*302 * Duplicate the source handle till we've got a match.303 */304 for (;;)305 {306 HANDLE hDup = INVALID_HANDLE_VALUE;307 if (DuplicateHandle(hCurProc, hSource, hCurProc, &hDup, 0 /* DesiredAccess */,308 fInherit, DUPLICATE_SAME_ACCESS))309 {310 int fdDup = _open_osfhandle((intptr_t)hDup, fFlags);311 if (fdDup != -1)312 {313 if (fdDup == fdNew)314 {315 while (cTries-- > 0)316 close(aFdTries[cTries]);317 return fdDup;318 }319 320 aFdTries[cTries++] = fdDup;321 if ( fdDup < fdNew322 && cTries < K_ELEMENTS(aFdTries))323 continue;324 fprintf(pStdErr, "%s: mscDup3(%d,%d): giving up! (last fdDup=%d)\n",325 g_progname, fdSource, fdNew, fdDup);326 }327 else328 {329 fprintf(pStdErr, "%s: _open_osfhandle(%#x) failed: %u\n", g_progname, hDup, strerror(errno));330 CloseHandle(hDup);331 }332 }333 else334 fprintf(pStdErr, "%s: DuplicateHandle(%#x) failed: %u\n", g_progname, hSource, GetLastError());335 break;336 }337 338 while (cTries-- > 0)339 close(aFdTries[cTries]);340 }341 else342 fprintf(pStdErr, "%s: mscDup3(%d,%d): source descriptor is invalid!\n", g_progname, fdSource, fdNew);343 }344 return -1;345 }346 347 #endif /* _MSC_VER */348 349 185 static KBOOL kRedirectHasConflict(int fd, unsigned cOrders, REDIRECTORDERS *paOrders) 350 186 { … … 374 210 * unless it matches @a fdTarget 375 211 * 212 * @param pCtx The command execution context. 376 213 * @param pszFilename The filename to open. 377 214 * @param fOpen The open flags. … … 382 219 * @param fdTarget The target descriptor. 383 220 */ 384 static int kRedirectOpenWithoutConflict( const char *pszFilename, int fOpen, mode_t fMode,221 static int kRedirectOpenWithoutConflict(PKMKBUILTINCTX pCtx, const char *pszFilename, int fOpen, mode_t fMode, 385 222 unsigned cOrders, REDIRECTORDERS *paOrders, int fRemoveOnFailure, int fdTarget) 386 223 { … … 407 244 fdOpened = open(pszFilename, fOpen | fNoInherit, fMode); 408 245 if (fdOpened < 0) 409 return err( -1, "open(%s,%#x,) failed", pszFilename, fOpen);246 return err(pCtx, -1, "open(%s,%#x,) failed", pszFilename, fOpen); 410 247 411 248 /* Check for conflicts. */ … … 453 290 else 454 291 { 455 err( -1, "open(%s,%#x,) #%u failed", pszFilename, cTries + 1, fOpen);292 err(pCtx, -1, "open(%s,%#x,) #%u failed", pszFilename, cTries + 1, fOpen); 456 293 break; 457 294 } … … 463 300 */ 464 301 if (fdOpened >= 0) 465 errx( -1, "failed to find a conflict free file descriptor for '%s'!", pszFilename);302 errx(pCtx, -1, "failed to find a conflict free file descriptor for '%s'!", pszFilename); 466 303 467 304 while (cTries-- > 0) … … 499 336 500 337 338 /** 339 * Wrapper that chooses between fprintf and kmk_builtin_ctx_printf to get 340 * an error message to the user. 341 * 342 * @param pCtx The command execution context. 343 * @param pWorkingStdErr Work stderr. 344 * @param pszFormat The message format string. 345 * @param ... Format arguments. 346 */ 347 static void safe_err_printf(PKMKBUILTINCTX pCtx, FILE *pWorkingStdErr, const char *pszFormat, ...) 348 { 349 char szMsg[4096]; 350 size_t cchMsg; 351 va_list va; 352 353 va_start(va, pszFormat); 354 vsnprintf(szMsg, sizeof(szMsg) - 1, pszFormat, va); 355 va_end(va); 356 szMsg[sizeof(szMsg) - 1] = '\0'; 357 cchMsg = strlen(szMsg); 358 359 #ifdef KMK_BUILTIN_STANDALONE 360 (void)pCtx; 361 #else 362 if (pCtx->pOut && pCtx->pOut->syncout) 363 output_write_text(pCtx->pOut, 1, szMsg, cchMsg); 364 else 365 #endif 366 fwrite(szMsg, cchMsg, 1, pWorkingStdErr); 367 } 368 501 369 #if !defined(USE_POSIX_SPAWN) && !defined(KBUILD_OS_WINDOWS) 502 370 … … 506 374 * 507 375 * @returns 0 on success, non-zero exit code on failure. 376 * @param pCtx The command execution context. 508 377 * @param pToSave Pointer to the file order to save the target 509 378 * descriptor of. … … 514 383 * keep having a working one to report failures to. 515 384 */ 516 static int kRedirectSaveHandle(REDIRECTORDERS *pToSave, unsigned cOrders, REDIRECTORDERS *paOrders, FILE **ppWorkingStdErr) 385 static int kRedirectSaveHandle(PKMKBUILTINCTX pCtx, REDIRECTORDERS *pToSave, unsigned cOrders, 386 REDIRECTORDERS *paOrders, FILE **ppWorkingStdErr) 517 387 { 518 388 int fdToSave = pToSave->fdTarget; … … 537 407 if (fdDup == -1) 538 408 { 539 fprintf(*ppWorkingStdErr, "%s: dup(%#x) failed: %u\n", g_progname, fdToSave, strerror(errno));409 safe_err_printf(pCtx, *ppWorkingStdErr, "%s: dup(%#x) failed: %u\n", pCtx->pszProgName, fdToSave, strerror(errno)); 540 410 break; 541 411 } … … 550 420 if (*ppWorkingStdErr == NULL) 551 421 { 552 fprintf(stderr, "%s: fdopen(%d,\"wt\") failed: %s\n", g_progname, fdDup, strerror(errno));422 safe_err_printf(pCtx, stderr, "%s: fdopen(%d,\"wt\") failed: %s\n", pCtx->pszProgName, fdDup, strerror(errno)); 553 423 *ppWorkingStdErr = stderr; 554 424 close(fdDup); … … 585 455 * Restores the target file descriptors affected by the file operation orders. 586 456 * 457 * @param pCtx The command execution context. 587 458 * @param cOrders Number of file operation orders. 588 459 * @param paOrders The file operation orders. … … 591 462 * it to stderr. 592 463 */ 593 static void kRedirectRestoreFdOrders( unsigned cOrders, REDIRECTORDERS *paOrders, FILE **ppWorkingStdErr)464 static void kRedirectRestoreFdOrders(PKMKBUILTINCTX pCtx, unsigned cOrders, REDIRECTORDERS *paOrders, FILE **ppWorkingStdErr) 594 465 { 595 466 int iSavedErrno = errno; … … 613 484 } 614 485 else 615 fprintf(*ppWorkingStdErr, "%s: dup2(%d,%d) failed: %s\n",616 g_progname, paOrders[i].fdSaved, paOrders[i].fdTarget, strerror(errno));486 safe_err_printf(pCtx, *ppWorkingStdErr, "%s: dup2(%d,%d) failed: %s\n", 487 pCtx->pszProgName, paOrders[i].fdSaved, paOrders[i].fdTarget, strerror(errno)); 617 488 } 618 489 … … 622 493 paOrders[i].fSaved = -1; 623 494 else 624 fprintf(*ppWorkingStdErr, "%s: fcntl(%d,F_SETFD,%s) failed: %s\n", 625 g_progname, paOrders[i].fdTarget, paOrders[i].fSaved & FD_CLOEXEC ? "FD_CLOEXEC" : "0", strerror(errno)); 495 safe_err_printf(pCtx, *ppWorkingStdErr, "%s: fcntl(%d,F_SETFD,%s) failed: %s\n", 496 pCtx->pszProgName, paOrders[i].fdTarget, paOrders[i].fSaved & FD_CLOEXEC ? "FD_CLOEXEC" : "0", 497 strerror(errno)); 626 498 } 627 499 } … … 634 506 * 635 507 * @returns 0 on success, exit code on failure. 508 * @param pCtx The command execution context. 636 509 * @param cOrders Number of file operation orders. 637 510 * @param paOrders File operation orders to execute. … … 639 512 * kRedirectRestoreFdOrders). 640 513 */ 641 static int kRedirectExecFdOrders( unsigned cOrders, REDIRECTORDERS *paOrders, FILE **ppWorkingStdErr)514 static int kRedirectExecFdOrders(PKMKBUILTINCTX pCtx, unsigned cOrders, REDIRECTORDERS *paOrders, FILE **ppWorkingStdErr) 642 515 { 643 516 unsigned i; … … 669 542 rcExit = 0; 670 543 else 671 fprintf(*ppWorkingStdErr, "%s: fcntl(%d,F_SETFD,FD_CLOEXEC) failed: %s\n",672 g_progname, fdTarget, strerror(errno));544 safe_err_printf(pCtx, *ppWorkingStdErr, "%s: fcntl(%d,F_SETFD,FD_CLOEXEC) failed: %s\n", 545 pCtx->pszProgName, fdTarget, strerror(errno)); 673 546 } 674 547 else if (errno == EBADF) 675 548 rcExit = 0; 676 549 else 677 fprintf(*ppWorkingStdErr, "%s: fcntl(%d,F_GETFD,0) failed: %s\n", g_progname, fdTarget, strerror(errno)); 550 safe_err_printf(pCtx, *ppWorkingStdErr, "%s: fcntl(%d,F_GETFD,0) failed: %s\n", 551 pCtx->pszProgName, fdTarget, strerror(errno)); 678 552 } 679 553 else 680 rcExit = kRedirectSaveHandle( &paOrders[i], cOrders, paOrders, ppWorkingStdErr);554 rcExit = kRedirectSaveHandle(pCtx, &paOrders[i], cOrders, paOrders, ppWorkingStdErr); 681 555 break; 682 556 } … … 684 558 case kRedirectOrder_Dup: 685 559 case kRedirectOrder_Open: 686 rcExit = kRedirectSaveHandle( &paOrders[i], cOrders, paOrders, ppWorkingStdErr);560 rcExit = kRedirectSaveHandle(pCtx, &paOrders[i], cOrders, paOrders, ppWorkingStdErr); 687 561 if (rcExit == 0) 688 562 { … … 692 566 { 693 567 if (paOrders[i].enmOrder == kRedirectOrder_Open) 694 fprintf(*ppWorkingStdErr, "%s: dup2(%d [%s],%d) failed: %s\n", g_progname, paOrders[i].fdSource,695 paOrders[i].pszFilename, paOrders[i].fdTarget, strerror(errno));568 safe_err_printf(pCtx, *ppWorkingStdErr, "%s: dup2(%d [%s],%d) failed: %s\n", pCtx->pszProgName, 569 paOrders[i].fdSource, paOrders[i].pszFilename, paOrders[i].fdTarget, strerror(errno)); 696 570 else 697 fprintf(*ppWorkingStdErr, "%s: dup2(%d,%d) failed: %s\n",698 g_progname, paOrders[i].fdSource, paOrders[i].fdTarget, strerror(errno));571 safe_err_printf(pCtx, *ppWorkingStdErr, "%s: dup2(%d,%d) failed: %s\n", 572 pCtx->pszProgName, paOrders[i].fdSource, paOrders[i].fdTarget, strerror(errno)); 699 573 rcExit = 10; 700 574 } … … 703 577 704 578 default: 705 fprintf(*ppWorkingStdErr, "%s: error! invalid enmOrder=%d\n", g_progname, paOrders[i].enmOrder);579 safe_err_printf(pCtx, *ppWorkingStdErr, "%s: error! invalid enmOrder=%d\n", pCtx->pszProgName, paOrders[i].enmOrder); 706 580 rcExit = 99; 707 581 break; … … 710 584 if (rcExit != 0) 711 585 { 712 kRedirectRestoreFdOrders( i, paOrders, ppWorkingStdErr);586 kRedirectRestoreFdOrders(pCtx, i, paOrders, ppWorkingStdErr); 713 587 return rcExit; 714 588 } … … 799 673 * 800 674 * @returns 0 on success, non-zero on failure to create. 675 * @param pCtx The command execution context. 801 676 * @param pszExecutable The child process executable. 802 677 * @param cArgs Number of arguments. … … 808 683 * @param phProcess Where to return process handle. 809 684 */ 810 static int kRedirectCreateProcessWindows(const char *pszExecutable, int cArgs, char **papszArgs, char **papszEnvVars, 811 const char *pszCwd, unsigned cOrders, REDIRECTORDERS *paOrders, HANDLE *phProcess) 685 static int kRedirectCreateProcessWindows(PKMKBUILTINCTX pCtx, const char *pszExecutable, int cArgs, char **papszArgs, 686 char **papszEnvVars, const char *pszCwd, unsigned cOrders, 687 REDIRECTORDERS *paOrders, HANDLE *phProcess) 812 688 { 813 689 size_t cbArgs; … … 828 704 pszCmdLine = pch = (char *)malloc(cbArgs); 829 705 if (!pszCmdLine) 830 return errx( 9, "out of memory!");706 return errx(pCtx, 9, "out of memory!"); 831 707 for (i = 0; i < cArgs; i++) 832 708 { … … 901 777 } 902 778 else 903 rc = errx( 10, "CreateProcessA(%s) failed: %u", pszExecutable, GetLastError());779 rc = errx(pCtx, 10, "CreateProcessA(%s) failed: %u", pszExecutable, GetLastError()); 904 780 } 905 781 else … … 923 799 if ( (paOrders[i].fOpen & O_APPEND) 924 800 && lseek(paOrders[i].fdSource, 0, SEEK_END) < 0) 925 rc = err( 10, "lseek-to-end failed on %d (for %d)", paOrders[i].fdSource, fdTarget);801 rc = err(pCtx, 10, "lseek-to-end failed on %d (for %d)", paOrders[i].fdSource, fdTarget); 926 802 case kRedirectOrder_Dup: 927 803 ahChild[fdTarget] = (HANDLE)_get_osfhandle(paOrders[i].fdSource); 928 804 if (ahChild[fdTarget] == NULL || ahChild[fdTarget] == INVALID_HANDLE_VALUE) 929 rc = err( 10, "_get_osfhandle failed on %d (for %d)", paOrders[i].fdSource, fdTarget);805 rc = err(pCtx, 10, "_get_osfhandle failed on %d (for %d)", paOrders[i].fdSource, fdTarget); 930 806 break; 931 807 case kRedirectOrder_Close: … … 949 825 rc = nt_child_inject_standard_handles(ProcInfo.hProcess, afReplace, ahChild, szErrMsg, sizeof(szErrMsg)); 950 826 if (rc) 951 rc = errx( 10, "%s", szErrMsg);827 rc = errx(pCtx, 10, "%s", szErrMsg); 952 828 else if (!ResumeThread(ProcInfo.hThread)) 953 rc = errx( 10, "ResumeThread failed: %u", GetLastError());829 rc = errx(pCtx, 10, "ResumeThread failed: %u", GetLastError()); 954 830 955 831 /* Kill it if any of that fails. */ … … 962 838 } 963 839 else 964 rc = errx( 10, "CreateProcessA(%s) failed: %u", pszExecutable, GetLastError());840 rc = errx(pCtx, 10, "CreateProcessA(%s) failed: %u", pszExecutable, GetLastError()); 965 841 } 966 842 } … … 968 844 } 969 845 else 970 rc = errx( 9, "out of memory!");846 rc = errx(pCtx, 9, "out of memory!"); 971 847 free(pszCmdLine); 972 848 return rc; … … 979 855 * 980 856 * @returns Exit code. 857 * @param pCtx The command execution context. 981 858 * @param pszExecutable The child process executable. 982 859 * @param cArgs Number of arguments. … … 998 875 * is from the child or from our setup efforts. 999 876 */ 1000 static int kRedirectDoSpawn( const char *pszExecutable, int cArgs, char **papszArgs, int fWatcomBrainDamage,877 static int kRedirectDoSpawn(PKMKBUILTINCTX pCtx, const char *pszExecutable, int cArgs, char **papszArgs, int fWatcomBrainDamage, 1001 878 char **papszEnvVars, const char *pszCwd, const char *pszSavedCwd, 1002 879 unsigned cOrders, REDIRECTORDERS *paOrders, … … 1025 902 memcpy(papszArgs, papszArgsOriginal, (cArgs + 1) * sizeof(papszArgs[0])); 1026 903 else 1027 return errx( 9, "out of memory!");904 return errx(pCtx, 9, "out of memory!"); 1028 905 1029 906 rcExit = quote_argv(cArgs, papszArgs, fWatcomBrainDamage, 0 /*fFreeOrLeak*/); … … 1037 914 { 1038 915 for (i = 0; i < cArgs; i++) 1039 warnx( "debug: argv[%i]=%s<eos>", i, papszArgs[i]);916 warnx(pCtx, "debug: argv[%i]=%s<eos>", i, papszArgs[i]); 1040 917 for (i = 0; i < (int)cOrders; i++) 1041 918 switch (paOrders[i].enmOrder) 1042 919 { 1043 920 case kRedirectOrder_Close: 1044 warnx( "debug: close %d\n", paOrders[i].fdTarget);921 warnx(pCtx, "debug: close %d\n", paOrders[i].fdTarget); 1045 922 break; 1046 923 case kRedirectOrder_Dup: 1047 warnx( "debug: dup %d to %d\n", paOrders[i].fdSource, paOrders[i].fdTarget);924 warnx(pCtx, "debug: dup %d to %d\n", paOrders[i].fdSource, paOrders[i].fdTarget); 1048 925 break; 1049 926 case kRedirectOrder_Open: 1050 warnx( "debug: open '%s' (%#x) as [%d ->] %d\n",927 warnx(pCtx, "debug: open '%s' (%#x) as [%d ->] %d\n", 1051 928 paOrders[i].pszFilename, paOrders[i].fOpen, paOrders[i].fdSource, paOrders[i].fdTarget); 1052 929 break; 1053 930 default: 1054 warnx( "error! invalid enmOrder=%d", paOrders[i].enmOrder);931 warnx(pCtx, "error! invalid enmOrder=%d", paOrders[i].enmOrder); 1055 932 assert(0); 1056 933 break; 1057 934 } 1058 935 if (pszSavedCwd) 1059 warnx( "debug: chdir %s\n", pszCwd);936 warnx(pCtx, "debug: chdir %s\n", pszCwd); 1060 937 } 1061 938 … … 1067 944 { 1068 945 if (chdir(pszCwd) < 0) 1069 rcExit = errx( 10, "Failed to change directory to '%s'", pszCwd);946 rcExit = errx(pCtx, 10, "Failed to change directory to '%s'", pszCwd); 1070 947 } 1071 948 #endif /* KBUILD_OS_WINDOWS */ … … 1077 954 */ 1078 955 FILE *pWorkingStdErr = NULL; 1079 rcExit = kRedirectExecFdOrders( cOrders, paOrders, &pWorkingStdErr);956 rcExit = kRedirectExecFdOrders(pCtx, cOrders, paOrders, &pWorkingStdErr); 1080 957 if (rcExit == 0) 1081 958 # endif … … 1088 965 /* Windows is slightly complicated due to handles and winchildren.c. */ 1089 966 HANDLE hProcess = INVALID_HANDLE_VALUE; 1090 rcExit = kRedirectCreateProcessWindows(p szExecutable, cArgs, papszArgs, papszEnvVars,967 rcExit = kRedirectCreateProcessWindows(pCtx, pszExecutable, cArgs, papszArgs, papszEnvVars, 1091 968 pszSavedCwd ? pszCwd : NULL, cOrders, paOrders, &hProcess); 1092 969 if (rcExit == 0) … … 1100 977 { 1101 978 if (cVerbosity > 0) 1102 warnx( "debug: spawned %d", *pPidSpawned);979 warnx(pCtx, "debug: spawned %d", *pPidSpawned); 1103 980 } 1104 981 else … … 1106 983 DWORD dwTmp; 1107 984 # ifndef CONFIG_NEW_WIN_CHILDREN 1108 warn( "sub_proc is out of slots, waiting for child...");985 warn(pCtx, "sub_proc is out of slots, waiting for child..."); 1109 986 # else 1110 987 if (pPidSpawned) 1111 warn( "MkWinChildCreateRedirect failed...");988 warn(pCtx, "MkWinChildCreateRedirect failed..."); 1112 989 # endif 1113 990 dwTmp = WaitForSingleObject(hProcess, INFINITE); 1114 991 if (dwTmp != WAIT_OBJECT_0) 1115 warn ("WaitForSingleObject failed: %#x\n", dwTmp);992 warnx(pCtx, "WaitForSingleObject failed: %#x\n", dwTmp); 1116 993 1117 994 if (GetExitCodeProcess(hProcess, &dwTmp)) … … 1119 996 else 1120 997 { 1121 warn ("GetExitCodeProcess failed: %u\n", GetLastError());998 warnx(pCtx, "GetExitCodeProcess failed: %u\n", GetLastError()); 1122 999 TerminateProcess(hProcess, 127); 1123 1000 rcExit = 127; … … 1133 1010 # elif defined(KBUILD_OS_OS2) 1134 1011 *pPidSpawned = _spawnvpe(P_NOWAIT, pszExecutable, papszArgs, papszEnvVars); 1135 kRedirectRestoreFdOrders( cOrders, paOrders, &pWorkingStdErr);1012 kRedirectRestoreFdOrders(pCtx, cOrders, paOrders, &pWorkingStdErr); 1136 1013 if (*pPidSpawned != -1) 1137 1014 { 1138 1015 if (cVerbosity > 0) 1139 warnx( "debug: spawned %d", *pPidSpawned);1016 warnx(pCtx, "debug: spawned %d", *pPidSpawned); 1140 1017 } 1141 1018 else 1142 1019 { 1143 rcExit = err( 10, "_spawnvpe(%s) failed", pszExecutable);1020 rcExit = err(pCtx, 10, "_spawnvpe(%s) failed", pszExecutable); 1144 1021 *pPidSpawned = 0; 1145 1022 } … … 1149 1026 { 1150 1027 if (cVerbosity > 0) 1151 warnx( "debug: spawned %d", *pPidSpawned);1028 warnx(pCtx, "debug: spawned %d", *pPidSpawned); 1152 1029 } 1153 1030 else 1154 1031 { 1155 rcExit = errx( 10, "posix_spawnp(%s) failed: %s", pszExecutable, strerror(rcExit));1032 rcExit = errx(pCtx, 10, "posix_spawnp(%s) failed: %s", pszExecutable, strerror(rcExit)); 1156 1033 *pPidSpawned = 0; 1157 1034 } … … 1164 1041 # ifdef KBUILD_OS_WINDOWS 1165 1042 HANDLE hProcess = INVALID_HANDLE_VALUE; 1166 rcExit = kRedirectCreateProcessWindows(p szExecutable, cArgs, papszArgs, papszEnvVars,1043 rcExit = kRedirectCreateProcessWindows(pCtx, pszExecutable, cArgs, papszArgs, papszEnvVars, 1167 1044 pszSavedCwd ? pszCwd : NULL, cOrders, paOrders, &hProcess); 1168 1045 if (rcExit == 0) … … 1177 1054 rcExit = dwWait; 1178 1055 else 1179 rcExit = errx( 11, "GetExitCodeProcess(%s) failed: %u", pszExecutable, GetLastError());1056 rcExit = errx(pCtx, 11, "GetExitCodeProcess(%s) failed: %u", pszExecutable, GetLastError()); 1180 1057 } 1181 1058 … … 1183 1060 errno = 0; 1184 1061 rcExit = (int)_spawnvpe(P_WAIT, pszExecutable, papszArgs, papszEnvVars); 1185 kRedirectRestoreFdOrders( cOrders, paOrders, &pWorkingStdErr);1062 kRedirectRestoreFdOrders(pCtx, cOrders, paOrders, &pWorkingStdErr); 1186 1063 if (rcExit != -1 || errno == 0) 1187 1064 { 1188 1065 *pfIsChildExitCode = K_TRUE; 1189 1066 if (cVerbosity > 0) 1190 warnx( "debug: exit code: %d", rcExit);1067 warnx(pCtx, "debug: exit code: %d", rcExit); 1191 1068 } 1192 1069 else 1193 rcExit = err( 10, "_spawnvpe(%s) failed", pszExecutable);1070 rcExit = err(pCtx, 10, "_spawnvpe(%s) failed", pszExecutable); 1194 1071 1195 1072 # else … … 1200 1077 *pfIsChildExitCode = K_TRUE; 1201 1078 if (cVerbosity > 0) 1202 warnx( "debug: spawned %d", pidChild);1079 warnx(pCtx, "debug: spawned %d", pidChild); 1203 1080 1204 1081 /* Wait for the child. */ … … 1209 1086 { 1210 1087 if (cVerbosity > 0) 1211 warnx( "debug: %d exit code: %d", pidChild, rcExit);1088 warnx(pCtx, "debug: %d exit code: %d", pidChild, rcExit); 1212 1089 break; 1213 1090 } … … 1218 1095 ) 1219 1096 { 1220 rcExit = err( 11, "waitpid failed");1097 rcExit = err(pCtx, 11, "waitpid failed"); 1221 1098 kill(pidChild, SIGKILL); 1222 1099 break; … … 1225 1102 } 1226 1103 else 1227 rcExit = errx( 10, "posix_spawnp(%s) failed: %s", pszExecutable, strerror(rcExit));1104 rcExit = errx(pCtx, 10, "posix_spawnp(%s) failed: %s", pszExecutable, strerror(rcExit)); 1228 1105 # endif 1229 1106 #endif /* !KMK */ … … 1238 1115 { 1239 1116 if (chdir(pszSavedCwd) < 0) 1240 warn( "Failed to restore directory to '%s'", pszSavedCwd);1117 warn(pCtx, "Failed to restore directory to '%s'", pszSavedCwd); 1241 1118 } 1242 1119 #endif … … 1244 1121 #ifdef _MSC_VER 1245 1122 else 1246 rcExit = errx( 9, "quite_argv failed: %u", rcExit);1123 rcExit = errx(pCtx, 9, "quite_argv failed: %u", rcExit); 1247 1124 1248 1125 /* Restore the original argv strings, freeing the quote_argv replacements. */ … … 1260 1137 * The function that does almost everything here... ugly. 1261 1138 */ 1262 #ifdef KMK 1263 int kmk_builtin_redirect(int argc, char **argv, char **envp, struct child *pChild, pid_t *pPidSpawned) 1264 #else 1265 int main(int argc, char **argv, char **envp) 1266 #endif 1139 int kmk_builtin_redirect(int argc, char **argv, char **envp, PKMKBUILTINCTX pCtx, struct child *pChild, pid_t *pPidSpawned) 1267 1140 { 1268 1141 int rcExit = 0; … … 1290 1163 1291 1164 1292 g_progname = argv[0];1293 1294 1165 if (argc <= 1) 1295 return usage(stderr, argv[0]);1166 return kmk_redirect_usage(pCtx, 1); 1296 1167 1297 1168 /* … … 1305 1176 { /* likely */ } 1306 1177 else 1307 return err( 9, "getcwd failed");1178 return err(pCtx, 9, "getcwd failed"); 1308 1179 1309 1180 /* We start out with a read-only enviornment from kmk or the crt, and will … … 1321 1192 rcExit = posix_spawn_file_actions_init(&FileActions); 1322 1193 if (rcExit != 0) 1323 rcExit = errx( 9, "posix_spawn_file_actions_init failed: %s", strerror(rcExit));1194 rcExit = errx(pCtx, 9, "posix_spawn_file_actions_init failed: %s", strerror(rcExit)); 1324 1195 #endif 1325 1196 … … 1384 1255 else 1385 1256 { 1386 errx( 2, "Unknown option: '%s'", pszArg - 2);1387 rcExit = usage(stderr, argv[0]);1257 errx(pCtx, 2, "Unknown option: '%s'", pszArg - 2); 1258 rcExit = kmk_redirect_usage(pCtx, 1); 1388 1259 break; 1389 1260 } … … 1396 1267 if (chOpt == 'h') 1397 1268 { 1398 usage(stdout, argv[0]);1269 kmk_redirect_usage(pCtx, 0); 1399 1270 rcExit = -1; 1400 1271 break; … … 1425 1296 else 1426 1297 { 1427 errx( 2, "syntax error: Option -%c requires a value!", chOpt);1428 rcExit = usage(stderr, argv[0]);1298 errx(pCtx, 2, "syntax error: Option -%c requires a value!", chOpt); 1299 rcExit = kmk_redirect_usage(pCtx, 1); 1429 1300 break; 1430 1301 } … … 1457 1328 if (rc) 1458 1329 { 1459 rcExit = errx( 9, "DosQueryExtLIBPATH(,%u) failed: %lu", ulVar, rc);1330 rcExit = errx(pCtx, 9, "DosQueryExtLIBPATH(,%u) failed: %lu", ulVar, rc); 1460 1331 free(apszSavedLibPaths[ulVar]); 1461 1332 apszSavedLibPaths[ulVar] = NULL; … … 1463 1334 } 1464 1335 else 1465 rcExit = errx( 9, "out of memory!");1336 rcExit = errx(pCtx, 9, "out of memory!"); 1466 1337 } 1467 1338 if (rcExit == 0) … … 1469 1340 rc = DosSetExtLIBPATH(pchEqual + 1, ulVar); 1470 1341 if (rc) 1471 rcExit = errx( 9, "error: DosSetExtLibPath(\"%s\", %.*s (%lu)): %lu",1342 rcExit = errx(pCtx, 9, "error: DosSetExtLibPath(\"%s\", %.*s (%lu)): %lu", 1472 1343 pchEqual, pchEqual - pszValue, pchEqual + 1, ulVar, rc); 1473 1344 } … … 1480 1351 { 1481 1352 if (pchEqual[1] != '\0') 1482 rcExit = kBuiltinOptEnvSet( &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);1353 rcExit = kBuiltinOptEnvSet(pCtx, &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue); 1483 1354 else 1484 1355 { … … 1487 1358 { 1488 1359 pszCopy[pchEqual - pszValue] = '\0'; 1489 rcExit = kBuiltinOptEnvUnset( &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszCopy);1360 rcExit = kBuiltinOptEnvUnset(pCtx, &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszCopy); 1490 1361 free(pszCopy); 1491 1362 } 1492 1363 else 1493 rcExit = errx( 1, "out of memory!");1364 rcExit = errx(pCtx, 1, "out of memory!"); 1494 1365 } 1495 1366 continue; … … 1508 1379 || strcmp(pszValue, "ENDLIBPATH") == 0 1509 1380 || strcmp(pszValue, "LIBPATHSTRICT") == 0) 1510 rcExit = errx( 2, "error: '%s' cannot currently be appended or prepended to. Please use -E/--set for now.", pszValue);1381 rcExit = errx(pCtx, 2, "error: '%s' cannot currently be appended or prepended to. Please use -E/--set for now.", pszValue); 1511 1382 else 1512 1383 #endif 1513 1384 if (chOpt == 'A') 1514 rcExit = kBuiltinOptEnvAppend( &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);1385 rcExit = kBuiltinOptEnvAppend(pCtx, &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue); 1515 1386 else 1516 rcExit = kBuiltinOptEnvPrepend( &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);1387 rcExit = kBuiltinOptEnvPrepend(pCtx, &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue); 1517 1388 continue; 1518 1389 } … … 1527 1398 || strcmp(pszValue, "ENDLIBPATH") == 0 1528 1399 || strcmp(pszValue, "LIBPATHSTRICT") == 0) 1529 rcExit = errx( 2, "error: '%s' cannot be unset, only set to an empty value using -E/--set.", pszValue);1400 rcExit = errx(pCtx, 2, "error: '%s' cannot be unset, only set to an empty value using -E/--set.", pszValue); 1530 1401 else 1531 1402 #endif 1532 rcExit = kBuiltinOptEnvUnset( &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);1403 rcExit = kBuiltinOptEnvUnset(pCtx, &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue); 1533 1404 continue; 1534 1405 } … … 1540 1411 || chOpt == 'i' /* GNU env compatibility. */ ) 1541 1412 { 1542 rcExit = kBuiltinOptEnvZap( &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity);1413 rcExit = kBuiltinOptEnvZap(pCtx, &papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity); 1543 1414 continue; 1544 1415 } … … 1552 1423 pszSavedCwd = strdup(szCwd); 1553 1424 if (pszSavedCwd) 1554 rcExit = kBuiltinOptChDir( szCwd, cbCwdBuf, pszValue);1425 rcExit = kBuiltinOptChDir(pCtx, szCwd, cbCwdBuf, pszValue); 1555 1426 else 1556 rcExit = err( 9, "out of memory!");1427 rcExit = err(pCtx, 9, "out of memory!"); 1557 1428 continue; 1558 1429 } … … 1593 1464 else 1594 1465 { 1595 rcExit = errx( 2, "error: too many file actions (max: %d)", K_ELEMENTS(aOrders));1466 rcExit = errx(pCtx, 2, "error: too many file actions (max: %d)", K_ELEMENTS(aOrders)); 1596 1467 break; 1597 1468 } … … 1605 1476 fd = (int)strtol(pszValue, &pszTmp, 0); 1606 1477 if (pszTmp == pszValue || *pszTmp != '\0') 1607 rcExit = errx( 2, "error: failed to convert '%s' to a number", pszValue);1478 rcExit = errx(pCtx, 2, "error: failed to convert '%s' to a number", pszValue); 1608 1479 else if (fd < 0) 1609 rcExit = errx( 2, "error: negative fd %d (%s)", fd, pszValue);1480 rcExit = errx(pCtx, 2, "error: negative fd %d (%s)", fd, pszValue); 1610 1481 #ifdef ONLY_TARGET_STANDARD_HANDLES 1611 1482 else if (fd > 2) 1612 rcExit = errx( 2, "error: %d is not a standard descriptor number", fd);1483 rcExit = errx(pCtx, 2, "error: %d is not a standard descriptor number", fd); 1613 1484 #endif 1614 1485 else … … 1620 1491 rcExit = posix_spawn_file_actions_addclose(&FileActions, fd); 1621 1492 if (rcExit != 0) 1622 rcExit = errx( 2, "posix_spawn_file_actions_addclose(%d) failed: %s", fd, strerror(rcExit));1493 rcExit = errx(pCtx, 2, "posix_spawn_file_actions_addclose(%d) failed: %s", fd, strerror(rcExit)); 1623 1494 #endif 1624 1495 } … … 1632 1503 fd = (int)strtol(pszValue, &pszEqual, 0); 1633 1504 if (pszEqual == pszValue) 1634 rcExit = errx( 2, "error: failed to convert target descriptor of '-d %s' to a number", pszValue);1505 rcExit = errx(pCtx, 2, "error: failed to convert target descriptor of '-d %s' to a number", pszValue); 1635 1506 else if (fd < 0) 1636 rcExit = errx( 2, "error: negative target descriptor %d ('-d %s')", fd, pszValue);1507 rcExit = errx(pCtx, 2, "error: negative target descriptor %d ('-d %s')", fd, pszValue); 1637 1508 #ifdef ONLY_TARGET_STANDARD_HANDLES 1638 1509 else if (fd > 2) 1639 rcExit = errx( 2, "error: target %d is not a standard descriptor number", fd);1510 rcExit = errx(pCtx, 2, "error: target %d is not a standard descriptor number", fd); 1640 1511 #endif 1641 1512 else if (*pszEqual != '=') 1642 rcExit = errx( 2, "syntax error: expected '=' to follow target descriptor: '-d %s'", pszValue);1513 rcExit = errx(pCtx, 2, "syntax error: expected '=' to follow target descriptor: '-d %s'", pszValue); 1643 1514 else 1644 1515 { … … 1646 1517 int fdSource = (int)strtol(++pszEqual, &pszEnd, 0); 1647 1518 if (pszEnd == pszEqual || *pszEnd != '\0') 1648 rcExit = errx( 2, "error: failed to convert source descriptor of '-d %s' to a number", pszValue);1519 rcExit = errx(pCtx, 2, "error: failed to convert source descriptor of '-d %s' to a number", pszValue); 1649 1520 else if (fdSource < 0) 1650 rcExit = errx( 2, "error: negative source descriptor %d ('-d %s')", fdSource, pszValue);1521 rcExit = errx(pCtx, 2, "error: negative source descriptor %d ('-d %s')", fdSource, pszValue); 1651 1522 else 1652 1523 { … … 1658 1529 rcExit = posix_spawn_file_actions_adddup2(&FileActions, fdSource, fd); 1659 1530 if (rcExit != 0) 1660 rcExit = errx( 2, "posix_spawn_file_actions_addclose(%d) failed: %s", fd, strerror(rcExit));1531 rcExit = errx(pCtx, 2, "posix_spawn_file_actions_addclose(%d) failed: %s", fd, strerror(rcExit)); 1661 1532 #endif 1662 1533 } … … 1713 1584 1714 1585 case '+': 1715 rcExit = errx( 2, "syntax error: Unexpected '+' in '%s'", argv[iArg]);1586 rcExit = errx(pCtx, 2, "syntax error: Unexpected '+' in '%s'", argv[iArg]); 1716 1587 continue; 1717 1588 … … 1780 1651 fd = (int)strtol(pszValue, &pszArg, 0); 1781 1652 if (pszArg == pszValue) 1782 rcExit = errx( 2, "error: failed to convert '%s' to a number", argv[iArg]);1653 rcExit = errx(pCtx, 2, "error: failed to convert '%s' to a number", argv[iArg]); 1783 1654 else if (fd < 0) 1784 rcExit = errx( 2, "error: negative fd %d (%s)", fd, argv[iArg]);1655 rcExit = errx(pCtx, 2, "error: negative fd %d (%s)", fd, argv[iArg]); 1785 1656 #ifdef ONLY_TARGET_STANDARD_HANDLES 1786 1657 else if (fd > 2) 1787 rcExit = errx( 2, "error: %d is not a standard descriptor number", fd);1658 rcExit = errx(pCtx, 2, "error: %d is not a standard descriptor number", fd); 1788 1659 #endif 1789 1660 else … … 1795 1666 */ 1796 1667 default: 1797 rcExit = errx( 2, "error: failed to convert '%s' ('%s') to a file descriptor", pszArg, argv[iArg]);1668 rcExit = errx(pCtx, 2, "error: failed to convert '%s' ('%s') to a file descriptor", pszArg, argv[iArg]); 1798 1669 continue; 1799 1670 } … … 1806 1677 if (*pszArg != ':' && *pszArg != '=') 1807 1678 { 1808 rcExit = errx( 2, "syntax error: characters following the file descriptor: '%s' ('%s')",1679 rcExit = errx(pCtx, 2, "syntax error: characters following the file descriptor: '%s' ('%s')", 1809 1680 pszArg, argv[iArg]); 1810 1681 break; … … 1816 1687 else 1817 1688 { 1818 rcExit = errx( 2, "syntax error: missing filename argument.");1689 rcExit = errx(pCtx, 2, "syntax error: missing filename argument."); 1819 1690 break; 1820 1691 } … … 1825 1696 * this for windows anyway, just do it the same way everywhere. 1826 1697 */ 1827 fdOpened = kRedirectOpenWithoutConflict(p szArg, fOpen, 0666, cOrders, aOrders,1698 fdOpened = kRedirectOpenWithoutConflict(pCtx, pszArg, fOpen, 0666, cOrders, aOrders, 1828 1699 aOrders[cOrders].fRemoveOnFailure, fd); 1829 1700 if (fdOpened >= 0) … … 1841 1712 rcExit = posix_spawn_file_actions_adddup2(&FileActions, fdOpened, fd); 1842 1713 if (rcExit != 0) 1843 rcExit = err( 9, "posix_spawn_file_actions_adddup2(,%d [%s], %d) failed: %s",1714 rcExit = err(pCtx, 9, "posix_spawn_file_actions_adddup2(,%d [%s], %d) failed: %s", 1844 1715 fdOpened, fd, pszArg, strerror(rcExit)); 1845 1716 } … … 1852 1723 else 1853 1724 { 1854 errx( 2, "syntax error: Invalid argument '%s'.", argv[iArg]);1855 rcExit = usage(stderr, argv[0]);1725 errx(pCtx, 2, "syntax error: Invalid argument '%s'.", argv[iArg]); 1726 rcExit = kmk_redirect_usage(pCtx, 1); 1856 1727 } 1857 1728 } … … 1867 1738 * Do the spawning in a separate function (main is far to large as it is by now). 1868 1739 */ 1869 rcExit = kRedirectDoSpawn(p szExecutable, argc - iArg, &argv[iArg], fWatcomBrainDamage,1740 rcExit = kRedirectDoSpawn(pCtx, pszExecutable, argc - iArg, &argv[iArg], fWatcomBrainDamage, 1870 1741 papszEnvVars, 1871 1742 szCwd, pszSavedCwd, … … 1882 1753 else if (rcExit == 0) 1883 1754 { 1884 errx( 2, "syntax error: nothing to execute!");1885 rcExit = usage(stderr, argv[0]);1755 errx(pCtx, 2, "syntax error: nothing to execute!"); 1756 rcExit = kmk_redirect_usage(pCtx, 1); 1886 1757 } 1887 1758 /* Help and version sets rcExit to -1. Change it to zero. */ … … 1905 1776 APIRET rc = DosSetExtLIBPATH(apszSavedLibPaths[ulLibPath], ulLibPath); 1906 1777 if (rc != 0) 1907 warnx( "DosSetExtLIBPATH('%s',%u) failed with %u when restoring the original values!",1778 warnx(pCtx, "DosSetExtLIBPATH('%s',%u) failed with %u when restoring the original values!", 1908 1779 apszSavedLibPaths[ulLibPath], ulLibPath, rc); 1909 1780 free(apszSavedLibPaths[ulLibPath]); … … 1914 1785 } 1915 1786 1787 #ifdef KMK_BUILTIN_STANDALONE 1788 int main(int argc, char **argv, char **envp) 1789 { 1790 KMKBUILTINCTX Ctx = { "kmk_redirect", NULL }; 1791 return kmk_builtin_redirect(argc, argv, envp, &Ctx, NULL, NULL); 1792 } 1793 #endif 1794 1795
Note:
See TracChangeset
for help on using the changeset viewer.

