Changeset 2838 in kBuild
- Timestamp:
- Aug 25, 2016 9:46:25 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 4 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Config.kmk
r2819 r2838 385 385 386 386 387 LIB_KDEP = $(PATH_OBJ)/kDep/$(TOOL_$(TEMPLATE_LIB_TOOL)_ARLIBPREF)kDep$(TOOL_$(TEMPLATE_LIB_TOOL)_ARLIBSUFF) 387 # 388 # Template for static threaded binaries (windows). 389 # 390 TEMPLATE_BIN-STATIC-THREADED = Threaded command line binary 391 TEMPLATE_BIN-STATIC-THREADED_EXTENDS = BIN-THREADED 392 ifeq ($(filter-out win nt,$(KBUILD_TARGET)),) 393 TEMPLATE_BIN-STATIC-THREADED_CFLAGS = $(filter-out -MD,$(TEMPLATE_BIN-THREADED_CFLAGS)) -MT 394 TEMPLATE_BIN-STATIC-THREADED_LIBS = $(filter-out %/msvcrt.lib,$(TEMPLATE_BIN-THREADED_LIBS)) \ 395 $(PATH_TOOL_$(TEMPLATE_BIN_TOOL)_LIB)/libcmt.lib \ 396 $(PATH_TOOL_$(TEMPLATE_BIN_TOOL)_LIB)/libcpmt.lib 397 else 398 TEMPLATE_BIN-STATIC-THREADED_CFLAGS = $(TEMPLATE_BIN-THREADED_CFLAGS) -static 399 TEMPLATE_BIN-STATIC-THREADED_LDFLAGS = $(TEMPLATE_BIN-THREADED_LDFLAGS) -static 400 endif 401 402 # 403 # Template for static threaded libraries. 404 # 405 TEMPLATE_LIB-STATIC-THREADED = Threaded command line library 406 TEMPLATE_LIB-STATIC-THREADED_EXTENDS = BIN-STATIC-THREADED 407 TEMPLATE_LIB-STATIC-THREADED_INST = lib/ 408 409 410 # 411 # Library macros. 412 # 413 LIB_KDEP = $(PATH_OBJ)/kDep/$(TOOL_$(TEMPLATE_LIB_TOOL)_ARLIBPREF)kDep$(TOOL_$(TEMPLATE_LIB_TOOL)_ARLIBSUFF) 388 414 LIB_KUTIL = $(PATH_OBJ)/kUtil/$(TOOL_$(TEMPLATE_LIB_TOOL)_ARLIBPREF)kUtil$(TOOL_$(TEMPLATE_LIB_TOOL)_ARLIBSUFF) 389 415 -
trunk/src/kWorker/Makefile.kmk
r2836 r2838 24 24 # 25 25 26 ## @todo fixme!!!27 KBUILD_WITH_STATIC_MSVCRT = 128 26 29 27 SUB_DEPTH = ../.. … … 32 30 33 31 PROGRAMS += kWorker 34 kWorker_TEMPLATE = BIN 32 kWorker_TEMPLATE = BIN-STATIC-THREADED 35 33 kWorker_INCS = kStuff/include 36 34 kWorker_DEFS.debug = K_STRICT … … 39 37 kWorker_LIBS = \ 40 38 $(kStuff_1_TARGET) \ 41 $(LIB_KDEP) \ 42 $(LIB_KUTIL) 39 $(kWorkerLib_1_TARGET) 43 40 include $(KBUILD_PATH)/sdks/WINDDK71.kmk 44 41 kWorker_LIBS.win = \ 45 $(TEMPLATE_BIN _LIBS) \42 $(TEMPLATE_BIN-STATIC-THREADED_LIBS) \ 46 43 $(PATH_SDK_WINDDK71_LIB_WNET)/ntdll.lib 47 44 kWorker_LDFLAGS.win = \ … … 50 47 51 48 # 49 # Stuff from ../libs. Need to rebuilt it with static CRT. 50 # 51 LIBRARIES += kWorkerLib 52 kWorkerLib_TEMPLATE = LIB-STATIC-THREADED 53 kWorkerLib_DEFPATH = ../lib # Need fix from r2837. 54 kWorkerLib_DEFPATH := $(PATH_SUB_CURRENT)/../lib 55 kWorkerLib_SOURCES = \ 56 crc32.c \ 57 md5.c 58 kWorkerLib_SOURCES.win = \ 59 nt_fullpath.c \ 60 quoted_spawn.c \ 61 nt/nthlpcore.c \ 62 nt/nthlpfs.c \ 63 nt/ntdir.c \ 64 nt/ntstat.c \ 65 nt/ntunlink.c 66 67 # 52 68 # kStuff library. 53 69 # 54 70 LIBRARIES += kStuff 55 kStuff_TEMPLATE = LIB 71 kStuff_TEMPLATE = LIB-STATIC-THREADED 56 72 kStuff_DEFS.debug = K_STRICT 57 73 kStuff_INCS = kStuff/include -
trunk/src/kWorker/kWorker.c
r2836 r2838 4922 4922 #else 4923 4923 // Skylake (W10/amd64, only stdandard MS defender): 4924 // run 4: 32.67/1024 = 0x0 (0.031904296875) 4925 // run 3: 32.77/1024 = 0x0 (0.032001953125) 4926 // run 2: 34/1024 = 0x0 (0.033203125) 4927 // run 1: 37/1024 = 0x0 (0.0361328125) 4928 // kmk 1: 44/1024 = 0x0 (0.04296875) 4929 // cmd 1: 48/1024 = 0x0 (0.046875) 4924 // cmd 1: 48 /1024 = 0x0 (0.046875) [for /l %i in (1,1,1024) do ...] 4925 // kmk 1: 44 /1024 = 0x0 (0.04296875) [all: ; 1024 x cl.exe] 4926 // run 1: 37 /1024 = 0x0 (0.0361328125) [just process creation gain] 4927 // run 2: 34 /1024 = 0x0 (0.033203125) [get file attribs] 4928 // run 3: 32.77 /1024 = 0x0 (0.032001953125) [read caching of headers] 4929 // run 4: 32.67 /1024 = 0x0 (0.031904296875) [loader tweaking] 4930 // run 5: 29.144/1024 = 0x0 (0.0284609375) [with temp files in memory] 4930 4931 // Dell (W7/amd64, infected by mcafee): 4931 4932 // kmk 1: 285.278/1024 = 0x0 (0.278591796875) -
trunk/src/lib/Makefile.kmk
r2713 r2838 42 42 kUtil_SOURCES.win = \ 43 43 nt_fullpath.c \ 44 quote_argv.c \ 44 45 quoted_spawn.c \ 45 46 nt/nthlpcore.c \ -
trunk/src/lib/quote_argv.c
r2837 r2838 1 1 /* $Id$ */ 2 2 /** @file 3 * kmk_redirect - Do simple program <-> file redirection (++).3 * quote_argv - Correctly quote argv for spawn, windows specific. 4 4 */ 5 5 … … 27 27 * Header Files * 28 28 *******************************************************************************/ 29 #ifdef __APPLE__ 30 # define _POSIX_C_SOURCE 1 /* 10.4 sdk and unsetenv */ 31 #endif 32 #include "config.h" 33 #include <stdio.h> 29 #include "quote_argv.h" 34 30 #include <stdlib.h> 35 31 #include <string.h> 36 #include <errno.h> 37 #include <fcntl.h> 38 #if defined(_MSC_VER) 39 # include <ctype.h> 40 # include <io.h> 41 # include <direct.h> 42 # include <process.h> 43 #else 44 # include <unistd.h> 32 #include <ctype.h> 33 34 #ifndef KBUILD_OS_WINDOWS 35 # error "KBUILD_OS_WINDOWS not defined" 45 36 #endif 46 37 47 #ifdef __OS2__48 # define INCL_BASE49 # include <os2.h>50 # ifndef LIBPATHSTRICT51 # define LIBPATHSTRICT 352 # endif53 #endif54 55 56 /*********************************************************************************************************************************57 * Global Variables *58 *********************************************************************************************************************************/59 /** Number of times the '-v' switch was seen. */60 static unsigned g_cVerbosity = 0;61 62 63 #if defined(_MSC_VER)64 38 65 39 /** … … 97 71 * Replaces arguments in need of quoting. 98 72 * 99 * This will "leak" the original and/or the replacement string, depending on100 * how you look at it.101 *102 73 * For details on how MSC parses the command line, see "Parsing C Command-Line 103 74 * Arguments": http://msdn.microsoft.com/en-us/library/a1y7w461.aspx … … 108 79 * OpenWatcom tools. They seem to follow some 109 80 * ancient or home made quoting convention. 110 * @param pStdErr For verbose debug info. 111 */ 112 static void quoteArguments(int argc, char **argv, int fWatcomBrainDamage, FILE *pStdErr) 81 * @param fFreeOrLeak Whether to free replaced argv members 82 * (non-zero), or just leak them (zero). This 83 * depends on which argv you're working on. 84 * Suggest doing the latter if it's main()'s argv. 85 */ 86 void quote_argv(int argc, char **argv, int fWatcomBrainDamage, int fFreeOrLeak) 113 87 { 114 88 int i; 115 89 for (i = 0; i < argc; i++) 116 90 { 117 c onst char *pszOrgOrg = argv[i];91 char *const pszOrgOrg = argv[i]; 118 92 const char *pszOrg = pszOrgOrg; 119 93 size_t cchOrg = strlen(pszOrg); … … 219 193 *pszNew++ = '"'; 220 194 *pszNew = '\0'; 221 } 222 223 if (g_cVerbosity > 0) 224 { 225 if (argv[i] == pszOrgOrg) 226 fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", i, pszOrgOrg); 227 else 228 { 229 fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", i, argv[i]); 230 fprintf(pStdErr, "kmk_redirect: debug:(orig[%i]=%s<eos>)\n", i, pszOrgOrg); 231 } 195 196 if (fFreeOrLeak) 197 free(pszOrgOrg); 232 198 } 233 199 } … … 236 202 } 237 203 238 239 /** Used by safeCloseFd. */240 static void __cdecl ignore_invalid_parameter(const wchar_t *a, const wchar_t *b, const wchar_t *c, unsigned d, uintptr_t e)241 {242 }243 244 #endif /* _MSC_VER */245 246 247 /**248 * Safely works around MS CRT's pedantic close() function.249 *250 * @param fd The file handle.251 */252 static void safeCloseFd(int fd)253 {254 #ifdef _MSC_VER255 _invalid_parameter_handler pfnOld = _get_invalid_parameter_handler();256 _set_invalid_parameter_handler(ignore_invalid_parameter);257 close(fd);258 _set_invalid_parameter_handler(pfnOld);259 #else260 close(fd);261 #endif262 }263 264 265 static const char *name(const char *pszName)266 {267 const char *psz = strrchr(pszName, '/');268 #if defined(_MSC_VER) || defined(__OS2__)269 const char *psz2 = strrchr(pszName, '\\');270 if (!psz2)271 psz2 = strrchr(pszName, ':');272 if (psz2 && (!psz || psz2 > psz))273 psz = psz2;274 #endif275 return psz ? psz + 1 : pszName;276 }277 278 279 static int usage(FILE *pOut, const char *argv0)280 {281 fprintf(pOut,282 "usage: %s [-[rwa+tb]<fd> <file>] [-c<fd>] [-Z] [-E <var=val>] [-C <dir>] [--wcc-brain-damage] [-v] -- <program> [args]\n"283 " or: %s --help\n"284 " or: %s --version\n"285 "\n"286 "The rwa+tb is like for fopen, if not specified it defaults to w+.\n"287 "The <fd> is either a number or an alias for the standard handles:\n"288 " i = stdin\n"289 " o = stdout\n"290 " e = stderr\n"291 "\n"292 "The -c switch will close the specified file descriptor.\n"293 "\n"294 "The -Z switch zaps the environment.\n"295 "\n"296 "The -E switch is for making changes to the environment in a putenv\n"297 "fashion.\n"298 "\n"299 "The -C switch is for changing the current directory. This takes immediate\n"300 "effect, so be careful where you put it.\n"301 "\n"302 "The --wcc-brain-damage switch is to work around wcc and wcc386 (Open Watcom)\n"303 "not following normal quoting conventions on Windows, OS/2, and DOS.\n"304 "\n"305 "The -v switch is for making the thing more verbose.\n"306 "\n"307 "This command was originally just a quick hack to avoid invoking the shell\n"308 "on Windows (cygwin) where forking is very expensive and has exhibited\n"309 "stability issues on SMP machines. It has since grown into something like\n"310 "/usr/bin/env on steroids.\n"311 ,312 argv0, argv0, argv0);313 return 1;314 }315 316 317 int main(int argc, char **argv, char **envp)318 {319 int i;320 #if defined(_MSC_VER)321 intptr_t rc;322 #else323 int j;324 #endif325 FILE *pStdErr = stderr;326 FILE *pStdOut = stdout;327 int fWatcomBrainDamage = 0;328 329 /*330 * Parse arguments.331 */332 if (argc <= 1)333 return usage(pStdErr, name(argv[0]));334 for (i = 1; i < argc; i++)335 {336 if (argv[i][0] == '-')337 {338 int fd;339 int fdOpened;340 int fOpen;341 char *psz = &argv[i][1];342 if (*psz == '-')343 {344 /* '--' ? */345 if (!psz[1])346 {347 i++;348 break;349 }350 351 /* convert to short. */352 if (!strcmp(psz, "-help"))353 psz = "h";354 else if (!strcmp(psz, "-version"))355 psz = "V";356 else if (!strcmp(psz, "-env"))357 psz = "E";358 else if (!strcmp(psz, "-chdir"))359 psz = "C";360 else if (!strcmp(psz, "-zap-env"))361 psz = "Z";362 else if (!strcmp(psz, "-close"))363 psz = "c";364 else if (!strcmp(psz, "-wcc-brain-damage"))365 {366 fWatcomBrainDamage = 1;367 continue;368 }369 }370 371 /*372 * Deal with the obligatory help and version switches first.373 */374 if (*psz == 'h')375 {376 usage(pStdOut, name(argv[0]));377 return 0;378 }379 if (*psz == 'V')380 {381 printf("kmk_redirect - kBuild version %d.%d.%d (r%u)\n"382 "Copyright (C) 2007-2012 knut st. osmundsen\n",383 KBUILD_VERSION_MAJOR, KBUILD_VERSION_MINOR, KBUILD_VERSION_PATCH,384 KBUILD_SVN_REV);385 return 0;386 }387 388 /*389 * Environment switch?390 */391 if (*psz == 'E')392 {393 psz++;394 if (*psz == ':' || *psz == '=')395 psz++;396 else397 {398 if (i + 1 >= argc)399 {400 fprintf(pStdErr, "%s: syntax error: no argument for %s\n", name(argv[0]), argv[i]);401 return 1;402 }403 psz = argv[++i];404 }405 #ifdef __OS2__406 if ( !strncmp(psz, "BEGINLIBPATH=", sizeof("BEGINLIBPATH=") - 1)407 || !strncmp(psz, "ENDLIBPATH=", sizeof("ENDLIBPATH=") - 1)408 || !strncmp(psz, "LIBPATHSTRICT=", sizeof("LIBPATHSTRICT=") - 1))409 {410 ULONG ulVar = *psz == 'B' ? BEGIN_LIBPATH411 : *psz == 'E' ? END_LIBPATH412 : LIBPATHSTRICT;413 const char *pszVal = strchr(psz, '=') + 1;414 APIRET rc = DosSetExtLIBPATH(pszVal, ulVar);415 if (rc)416 {417 fprintf(pStdErr, "%s: error: DosSetExtLibPath(\"%s\", %.*s (%lu)): %lu\n",418 name(argv[0]), pszVal, pszVal - psz - 1, psz, ulVar, rc);419 return 1;420 }421 }422 else423 #endif /* __OS2__ */424 {425 const char *pchEqual = strchr(psz, '=');426 if (pchEqual && pchEqual[1] != '\0')427 {428 if (putenv(psz))429 {430 fprintf(pStdErr, "%s: error: putenv(\"%s\"): %s\n", name(argv[0]), psz, strerror(errno));431 return 1;432 }433 }434 else435 {436 size_t cchVar = pchEqual ? (size_t)(pchEqual - psz) : strlen(psz);437 char *pszCopy = (char *)malloc(cchVar + 2);438 memcpy(pszCopy, psz, cchVar);439 440 #if defined(_MSC_VER) || defined(__OS2__)441 pszCopy[cchVar] = '=';442 pszCopy[cchVar + 1] = '\0';443 if (putenv(pszCopy))444 {445 fprintf(pStdErr, "%s: error: putenv(\"%s\"): %s\n", name(argv[0]), pszCopy, strerror(errno));446 return 1;447 }448 #else449 pszCopy[cchVar] = '\0';450 if (unsetenv(pszCopy))451 {452 fprintf(pStdErr, "%s: error: unsetenv(\"%s\"): %s\n", name(argv[0]), pszCopy, strerror(errno));453 return 1;454 }455 #endif456 free(pszCopy);457 }458 }459 continue;460 }461 462 /*463 * Change directory switch?464 */465 if (*psz == 'C')466 {467 psz++;468 if (*psz == ':' || *psz == '=')469 psz++;470 else471 {472 if (i + 1 >= argc)473 {474 fprintf(pStdErr, "%s: syntax error: no argument for %s\n", name(argv[0]), argv[i]);475 return 1;476 }477 psz = argv[++i];478 }479 if (!chdir(psz))480 continue;481 #ifdef _MSC_VER482 {483 /* drop trailing slash if any. */484 size_t cch = strlen(psz);485 if ( cch > 2486 && (psz[cch - 1] == '/' || psz[cch - 1] == '\\')487 && psz[cch - 1] != ':')488 {489 int rc2;490 char *pszCopy = strdup(psz);491 do pszCopy[--cch] = '\0';492 while ( cch > 2493 && (pszCopy[cch - 1] == '/' || pszCopy[cch - 1] == '\\')494 && pszCopy[cch - 1] != ':');495 rc2 = chdir(pszCopy);496 free(pszCopy);497 if (!rc2)498 continue;499 }500 }501 #endif502 fprintf(pStdErr, "%s: error: chdir(\"%s\"): %s\n", name(argv[0]), psz, strerror(errno));503 return 1;504 }505 506 /*507 * Zap environment switch?508 * This is a bit of a hack.509 */510 if (*psz == 'Z')511 {512 unsigned j = 0;513 while (envp[j] != NULL)514 j++;515 while (j-- > 0)516 {517 char *pszEqual = strchr(envp[j], '=');518 char *pszCopy;519 520 if (pszEqual)521 *pszEqual = '\0';522 pszCopy = strdup(envp[j]);523 if (pszEqual)524 *pszEqual = '=';525 526 #if defined(_MSC_VER) || defined(__OS2__)527 putenv(pszCopy);528 #else529 unsetenv(pszCopy);530 #endif531 free(pszCopy);532 }533 continue;534 }535 536 /*537 * Verbose operation switch?538 */539 if (*psz == 'v')540 {541 g_cVerbosity++;542 continue;543 }544 545 /*546 * Close the specified file descriptor (no stderr/out/in aliases).547 */548 if (*psz == 'c')549 {550 psz++;551 if (!*psz)552 {553 i++;554 if (i >= argc)555 {556 fprintf(pStdErr, "%s: syntax error: missing filename argument.\n", name(argv[0]));557 return 1;558 }559 psz = argv[i];560 }561 562 fd = (int)strtol(psz, &psz, 0);563 if (!fd || *psz)564 {565 fprintf(pStdErr, "%s: error: failed to convert '%s' to a number\n", name(argv[0]), argv[i]);566 return 1;567 568 }569 if (fd < 0)570 {571 fprintf(pStdErr, "%s: error: negative fd %d (%s)\n", name(argv[0]), fd, argv[i]);572 return 1;573 }574 /** @todo deal with stderr */575 safeCloseFd(fd);576 continue;577 }578 579 /*580 * Parse a file descriptor argument.581 */582 583 /* mode */584 switch (*psz)585 {586 case 'r':587 psz++;588 if (*psz == '+')589 {590 fOpen = O_RDWR;591 psz++;592 }593 else594 fOpen = O_RDONLY;595 break;596 597 case 'w':598 psz++;599 if (*psz == '+')600 {601 psz++;602 fOpen = O_RDWR | O_CREAT | O_TRUNC;603 }604 else605 fOpen = O_WRONLY | O_CREAT | O_TRUNC;606 break;607 608 case 'a':609 psz++;610 if (*psz == '+')611 {612 psz++;613 fOpen = O_RDWR | O_CREAT | O_APPEND;614 }615 else616 fOpen = O_WRONLY | O_CREAT | O_APPEND;617 break;618 619 case 'i': /* make sure stdin is read-only. */620 fOpen = O_RDONLY;621 break;622 623 case '+':624 fprintf(pStdErr, "%s: syntax error: Unexpected '+' in '%s'\n", name(argv[0]), argv[i]);625 return 1;626 627 default:628 fOpen = O_RDWR | O_CREAT | O_TRUNC;629 break;630 }631 632 /* binary / text modifiers */633 switch (*psz)634 {635 case 'b':636 #ifdef O_BINARY637 fOpen |= O_BINARY;638 #endif639 psz++;640 break;641 642 case 't':643 #ifdef O_TEXT644 fOpen |= O_TEXT;645 #endif646 psz++;647 break;648 649 default:650 #ifdef O_BINARY651 fOpen |= O_BINARY;652 #endif653 break;654 655 }656 657 /* convert to file descriptor number */658 switch (*psz)659 {660 case 'i':661 fd = 0;662 psz++;663 break;664 665 case 'o':666 fd = 1;667 psz++;668 break;669 670 case 'e':671 fd = 2;672 psz++;673 break;674 675 case '0':676 if (!psz[1])677 {678 fd = 0;679 psz++;680 break;681 }682 case '1':683 case '2':684 case '3':685 case '4':686 case '5':687 case '6':688 case '7':689 case '8':690 case '9':691 fd = (int)strtol(psz, &psz, 0);692 if (!fd)693 {694 fprintf(pStdErr, "%s: error: failed to convert '%s' to a number\n", name(argv[0]), argv[i]);695 return 1;696 697 }698 if (fd < 0)699 {700 fprintf(pStdErr, "%s: error: negative fd %d (%s)\n", name(argv[0]), fd, argv[i]);701 return 1;702 }703 break;704 705 /*706 * Invalid argument.707 */708 default:709 fprintf(pStdErr, "%s: error: failed to convert '%s' ('%s') to a file descriptor\n", name(argv[0]), psz, argv[i]);710 return 1;711 }712 713 /*714 * Check for the filename.715 */716 if (*psz)717 {718 if (*psz != ':' && *psz != '=')719 {720 fprintf(pStdErr, "%s: syntax error: characters following the file descriptor: '%s' ('%s')\n", name(argv[0]), psz, argv[i]);721 return 1;722 }723 psz++;724 }725 else726 {727 i++;728 if (i >= argc)729 {730 fprintf(pStdErr, "%s: syntax error: missing filename argument.\n", name(argv[0]));731 return 1;732 }733 psz = argv[i];734 }735 736 /*737 * Setup the redirection.738 */739 if (fd == fileno(pStdErr))740 {741 /*742 * Move stderr to a new location, making it close on exec.743 * If pStdOut has already teamed up with pStdErr, update it too.744 */745 FILE *pNew;746 fdOpened = dup(fileno(pStdErr));747 if (fdOpened == -1)748 {749 fprintf(pStdErr, "%s: error: failed to dup stderr (%d): %s\n", name(argv[0]), fileno(pStdErr), strerror(errno));750 return 1;751 }752 #ifdef _MSC_VER753 /** @todo figure out how to make the handle close-on-exec. We'll simply close it for now.754 * SetHandleInformation + set FNOINHERIT in CRT.755 */756 #else757 if (fcntl(fdOpened, F_SETFD, FD_CLOEXEC) == -1)758 {759 fprintf(pStdErr, "%s: error: failed to make stderr (%d) close-on-exec: %s\n", name(argv[0]), fdOpened, strerror(errno));760 return 1;761 }762 #endif763 764 pNew = fdopen(fdOpened, "w");765 if (!pNew)766 {767 fprintf(pStdErr, "%s: error: failed to fdopen the new stderr (%d): %s\n", name(argv[0]), fdOpened, strerror(errno));768 return 1;769 }770 if (pStdOut == pStdErr)771 pStdOut = pNew;772 pStdErr = pNew;773 }774 else if (fd == 1 && pStdOut != pStdErr)775 pStdOut = pStdErr;776 777 /*778 * Close and open the new file descriptor.779 */780 safeCloseFd(fd);781 #if defined(_MSC_VER)782 if (!strcmp(psz, "/dev/null"))783 psz = (char *)"nul";784 #endif785 fdOpened = open(psz, fOpen, 0666);786 if (fdOpened == -1)787 {788 fprintf(pStdErr, "%s: error: failed to open '%s' as %d: %s\n", name(argv[0]), psz, fd, strerror(errno));789 return 1;790 }791 if (fdOpened != fd)792 {793 /* move it (dup2 returns 0 on MSC). */794 if (dup2(fdOpened, fd) == -1)795 {796 fprintf(pStdErr, "%s: error: failed to dup '%s' as %d: %s\n", name(argv[0]), psz, fd, strerror(errno));797 return 1;798 }799 close(fdOpened);800 }801 }802 else803 {804 fprintf(pStdErr, "%s: syntax error: Invalid argument '%s'.\n", name(argv[0]), argv[i]);805 return usage(pStdErr, name(argv[0]));806 }807 }808 809 /*810 * Make sure there's something to execute.811 */812 if (i >= argc)813 {814 fprintf(pStdErr, "%s: syntax error: nothing to execute!\n", name(argv[0]));815 return usage(pStdErr, name(argv[0]));816 }817 818 #if defined(_MSC_VER)819 if (fileno(pStdErr) != 2) /* no close-on-exec flag on windows */820 {821 fclose(pStdErr);822 pStdErr = NULL;823 }824 825 /* MSC is a PITA since it refuses to quote the arguments... */826 quoteArguments(argc - i, &argv[i], fWatcomBrainDamage, pStdErr);827 rc = _spawnvp(_P_WAIT, argv[i], &argv[i]);828 if (rc == -1 && pStdErr)829 {830 fprintf(pStdErr, "%s: error: _spawnvp(_P_WAIT, \"%s\", ...) failed: %s\n", name(argv[0]), argv[i], strerror(errno));831 rc = 1;832 }833 return rc;834 #else835 if (g_cVerbosity > 0)836 for (j = i; j < argc; j++)837 fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", j - i, argv[j]);838 execvp(argv[i], &argv[i]);839 fprintf(pStdErr, "%s: error: _execvp(_P_WAIT, \"%s\", ...) failed: %s\n", name(argv[0]), argv[i], strerror(errno));840 return 1;841 #endif842 }843
Note:
See TracChangeset
for help on using the changeset viewer.