Changeset 3192 for trunk/src/kmk/kmkbuiltin/touch.c
- Timestamp:
- Mar 26, 2018, 10:25:56 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/touch.c
r3140 r3192 91 91 typedef struct KMKTOUCHOPTS 92 92 { 93 /** Command execution context. */ 94 PKMKBUILTINCTX pCtx; 93 95 /** What timestamps to modify on the files. */ 94 96 KMKTOUCHTARGET enmWhatToTouch; … … 111 113 typedef KMKTOUCHOPTS *PKMKTOUCHOPTS; 112 114 113 114 115 static int touch_error(const char *pszMsg, ...)116 {117 va_list va;118 fputs(TOUCH_NAME ": error: ", stderr);119 va_start(va, pszMsg);120 vfprintf(stderr, pszMsg, va);121 va_end(va);122 fputc('\n', stderr);123 return 1;124 }125 126 static int touch_syntax(const char *pszMsg, ...)127 {128 va_list va;129 fputs(TOUCH_NAME ": syntax error: ", stderr);130 va_start(va, pszMsg);131 vfprintf(stderr, pszMsg, va);132 va_end(va);133 fputc('\n', stderr);134 return 2;135 }136 115 137 116 static int touch_usage(void) … … 189 168 * Parses adjustment value: [-][[hh]mm]SS 190 169 */ 191 static int touch_parse_adjust( const char *pszValue, int *piAdjustValue)170 static int touch_parse_adjust(PKMKBUILTINCTX pCtx, const char *pszValue, int *piAdjustValue) 192 171 { 193 172 const char * const pszInValue = pszValue; … … 210 189 if ( !IS_DIGIT(pszValue[0], 9) 211 190 || !IS_DIGIT(pszValue[0], 9)) 212 return touch_syntax("Malformed hour part of -A value: %s", pszInValue);191 return errx(pCtx, 2, "Malformed hour part of -A value: %s", pszInValue); 213 192 *piAdjustValue = TWO_CHARS_TO_INT(pszValue[0], pszValue[1]) * 60 * 60; 214 193 /* fall thru */ … … 216 195 if ( !IS_DIGIT(pszValue[cchValue - 4], 9) /* don't bother limit to 60 minutes */ 217 196 || !IS_DIGIT(pszValue[cchValue - 3], 9)) 218 return touch_syntax("Malformed minute part of -A value: %s", pszInValue);197 return errx(pCtx, 2, "Malformed minute part of -A value: %s", pszInValue); 219 198 *piAdjustValue += TWO_CHARS_TO_INT(pszValue[cchValue - 4], pszValue[cchValue - 3]) * 60; 220 199 /* fall thru */ … … 222 201 if ( !IS_DIGIT(pszValue[cchValue - 2], 9) /* don't bother limit to 60 seconds */ 223 202 || !IS_DIGIT(pszValue[cchValue - 1], 9)) 224 return touch_syntax("Malformed second part of -A value: %s", pszInValue);203 return errx(pCtx, 2, "Malformed second part of -A value: %s", pszInValue); 225 204 *piAdjustValue += TWO_CHARS_TO_INT(pszValue[cchValue - 2], pszValue[cchValue - 1]); 226 205 break; 227 206 228 207 default: 229 return touch_syntax("Invalid -A value (length): %s", pszInValue);208 return errx(pCtx, 2, "Invalid -A value (length): %s", pszInValue); 230 209 } 231 210 … … 241 220 * Parse -d timestamp: YYYY-MM-DDThh:mm:SS[.frac][tz] 242 221 */ 243 static int touch_parse_d_ts( const char *pszTs, struct timeval *pDst)222 static int touch_parse_d_ts(PKMKBUILTINCTX pCtx, const char *pszTs, struct timeval *pDst) 244 223 { 245 224 const char * const pszTsIn = pszTs; … … 257 236 || !IS_DIGIT(pszTs[3], 9) 258 237 || pszTs[4] != '-') 259 return touch_error("Malformed timestamp '%s' given to -d: expected to start with 4 digit year followed by a dash",260 238 return errx(pCtx, 2, "Malformed timestamp '%s' given to -d: expected to start with 4 digit year followed by a dash", 239 pszTsIn); 261 240 ExpTime.tm_year = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]) * 100 262 241 + TWO_CHARS_TO_INT(pszTs[2], pszTs[3]) … … 268 247 || !IS_DIGIT(pszTs[1], 9) 269 248 || pszTs[2] != '-') 270 return touch_error("Malformed timestamp '%s' given to -d: expected to two digit month at position 6 followed by a dash",271 249 return errx(pCtx, 2, "Malformed timestamp '%s' given to -d: expected to two digit month at position 6 followed by a dash", 250 pszTsIn); 272 251 ExpTime.tm_mon = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]) - 1; 273 252 pszTs += 3; … … 277 256 || !IS_DIGIT(pszTs[1], 9) 278 257 || (pszTs[2] != 'T' && pszTs[2] != 't' && pszTs[2] != ' ') ) 279 return touch_error("Malformed timestamp '%s' given to -d: expected to two digit day of month at position 9 followed by 'T' or space",280 258 return errx(pCtx, 2, "Malformed timestamp '%s' given to -d: expected to two digit day of month at position 9 followed by 'T' or space", 259 pszTsIn); 281 260 ExpTime.tm_mday = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]); 282 261 pszTs += 3; … … 286 265 || !IS_DIGIT(pszTs[1], 9) 287 266 || pszTs[2] != ':') 288 return touch_error("Malformed timestamp '%s' given to -d: expected to two digit hour at position 12 followed by colon",289 267 return errx(pCtx, 2, "Malformed timestamp '%s' given to -d: expected to two digit hour at position 12 followed by colon", 268 pszTsIn); 290 269 ExpTime.tm_hour = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]); 291 270 pszTs += 3; … … 295 274 || !IS_DIGIT(pszTs[1], 9) 296 275 || pszTs[2] != ':') 297 return touch_error("Malformed timestamp '%s' given to -d: expected to two digit minute at position 15 followed by colon",298 276 return errx(pCtx, 2, "Malformed timestamp '%s' given to -d: expected to two digit minute at position 15 followed by colon", 277 pszTsIn); 299 278 ExpTime.tm_min = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]); 300 279 pszTs += 3; … … 303 282 if ( !IS_DIGIT(pszTs[0], 5) 304 283 || !IS_DIGIT(pszTs[1], 9)) 305 return touch_error("Malformed timestamp '%s' given to -d: expected to two digit seconds at position 12", pszTsIn);284 return errx(pCtx, 2, "Malformed timestamp '%s' given to -d: expected to two digit seconds at position 12", pszTsIn); 306 285 ExpTime.tm_sec = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]); 307 286 pszTs += 2; … … 315 294 pszTs++; 316 295 if (!IS_DIGIT(*pszTs, 9)) 317 return touch_error("Malformed timestamp '%s' given to -d: empty fraction", pszTsIn);296 return errx(pCtx, 2, "Malformed timestamp '%s' given to -d: empty fraction", pszTsIn); 318 297 319 298 iFactor = 100000; … … 333 312 pszTs++; 334 313 if (*pszTs != '\0') 335 return touch_error("Malformed timestamp '%s' given to -d: Unexpected character(s) after zulu time indicator at end of timestamp", 336 pszTsIn); 314 return errx(pCtx, 2, 315 "Malformed timestamp '%s' given to -d: Unexpected character(s) after zulu time indicator at end of timestamp", 316 pszTsIn); 337 317 } 338 318 else if (*pszTs != '\0') 339 return touch_error("Malformed timestamp '%s' given to -d: expected to 'Z' (zulu) or nothing at end of timestamp", pszTsIn);319 return errx(pCtx, 2, "Malformed timestamp '%s' given to -d: expected to 'Z' (zulu) or nothing at end of timestamp", pszTsIn); 340 320 341 321 /* … … 352 332 #endif 353 333 if (pDst->tv_sec == -1) 354 return touch_error("timegm failed on '%s': %s", pszTs, strerror(errno));334 return errx(pCtx, 1, "timegm failed on '%s': %s", pszTs, strerror(errno)); 355 335 } 356 336 else … … 358 338 pDst->tv_sec = mktime(&ExpTime); 359 339 if (pDst->tv_sec == -1) 360 return touch_error("mktime failed on '%s': %s", pszTs, strerror(errno));340 return errx(pCtx, 1, "mktime failed on '%s': %s", pszTs, strerror(errno)); 361 341 } 362 342 return 0; … … 367 347 * Parse -t timestamp: [[CC]YY]MMDDhhmm[.SS] 368 348 */ 369 static int touch_parse_ts( const char *pszTs, struct timeval *pDst)349 static int touch_parse_ts(PKMKBUILTINCTX pCtx, const char *pszTs, struct timeval *pDst) 370 350 { 371 351 size_t const cchTs = strlen(pszTs); … … 380 360 */ 381 361 if ((cchTs & 1) && pszTs[cchTs - 3] != '.') 382 return touch_error("Invalid timestamp given to -t: %s", pszTs);362 return errx(pCtx, 2, "Invalid timestamp given to -t: %s", pszTs); 383 363 switch (cchTs) 384 364 { … … 392 372 case 8 + 3 + 2 + 2: /* CCYYMMDDhhmm.SS */ 393 373 if (pszTs[cchTs - 3] != '.') 394 return touch_error("Invalid timestamp (-t) '%s': missing dot for seconds part", pszTs);374 return errx(pCtx, 2, "Invalid timestamp (-t) '%s': missing dot for seconds part", pszTs); 395 375 if ( !IS_DIGIT(pszTs[cchTs - 2], 5) 396 376 || !IS_DIGIT(pszTs[cchTs - 1], 9)) 397 return touch_error("Invalid timestamp (-t) '%s': malformed seconds part", pszTs);377 return errx(pCtx, 2, "Invalid timestamp (-t) '%s': malformed seconds part", pszTs); 398 378 cchTsNoSec = cchTs - 3; 399 379 break; 400 380 default: 401 return touch_error("Invalid timestamp (-t) '%s': wrong length (%d)", pszTs, (int)cchTs);381 return errx(pCtx, 1, "Invalid timestamp (-t) '%s': wrong length (%d)", pszTs, (int)cchTs); 402 382 } 403 383 … … 407 387 if ( !IS_DIGIT(pszTs[cchTsNoSec - 12], 9) 408 388 || !IS_DIGIT(pszTs[cchTsNoSec - 11], 9)) 409 return touch_error("Invalid timestamp (-t) '%s': malformed CC part", pszTs);389 return errx(pCtx, 2, "Invalid timestamp (-t) '%s': malformed CC part", pszTs); 410 390 /* fall thru */ 411 391 case 8 + 2: /* YYMMDDhhmm */ 412 392 if ( !IS_DIGIT(pszTs[cchTsNoSec - 10], 9) 413 393 || !IS_DIGIT(pszTs[cchTsNoSec - 9], 9)) 414 return touch_error("Invalid timestamp (-t) '%s': malformed YY part", pszTs);394 return errx(pCtx, 2, "Invalid timestamp (-t) '%s': malformed YY part", pszTs); 415 395 /* fall thru */ 416 396 case 8: /* MMDDhhmm */ 417 397 if ( !IS_DIGIT(pszTs[cchTsNoSec - 8], 1) 418 398 || !IS_DIGIT(pszTs[cchTsNoSec - 7], 9) ) 419 return touch_error("Invalid timestamp (-t) '%s': malformed month part", pszTs);399 return errx(pCtx, 2, "Invalid timestamp (-t) '%s': malformed month part", pszTs); 420 400 if ( !IS_DIGIT(pszTs[cchTsNoSec - 6], 3) 421 401 || !IS_DIGIT(pszTs[cchTsNoSec - 5], 9) ) 422 return touch_error("Invalid timestamp (-t) '%s': malformed day part", pszTs);402 return errx(pCtx, 2, "Invalid timestamp (-t) '%s': malformed day part", pszTs); 423 403 if ( !IS_DIGIT(pszTs[cchTsNoSec - 4], 2) 424 404 || !IS_DIGIT(pszTs[cchTsNoSec - 3], 9) ) 425 return touch_error("Invalid timestamp (-t) '%s': malformed hour part", pszTs);405 return errx(pCtx, 2, "Invalid timestamp (-t) '%s': malformed hour part", pszTs); 426 406 if ( !IS_DIGIT(pszTs[cchTsNoSec - 2], 5) 427 407 || !IS_DIGIT(pszTs[cchTsNoSec - 1], 9) ) 428 return touch_error("Invalid timestamp (-t) '%s': malformed minute part", pszTs);408 return errx(pCtx, 2, "Invalid timestamp (-t) '%s': malformed minute part", pszTs); 429 409 break; 430 410 } … … 435 415 rc = gettimeofday(&Now, NULL); 436 416 if (rc != 0) 437 return touch_error("gettimeofday failed: %s", strerror(errno));417 return errx(pCtx, 1, "gettimeofday failed: %s", strerror(errno)); 438 418 439 419 pExpTime = localtime_r(&Now.tv_sec, &ExpTime); 440 420 if (pExpTime == NULL) 441 return touch_error("localtime_r failed: %s", strerror(errno));421 return errx(pCtx, 1, "localtime_r failed: %s", strerror(errno)); 442 422 443 423 /* … … 475 455 if (pDst->tv_sec != -1) 476 456 return 0; 477 return touch_error("mktime failed on '%s': %s", pszTs, strerror(errno));457 return errx(pCtx, 1, "mktime failed on '%s': %s", pszTs, strerror(errno)); 478 458 } 479 459 … … 482 462 * Check for old timestamp: MMDDhhmm[YY] 483 463 */ 484 static int touch_parse_old_ts( const char *pszOldTs, time_t Now, struct timeval *pDst)464 static int touch_parse_old_ts(PKMKBUILTINCTX pCtx, const char *pszOldTs, time_t Now, struct timeval *pDst) 485 465 { 486 466 /* … … 509 489 pExpTime = localtime_r(&Now, &ExpTime); 510 490 if (pExpTime == NULL) 511 return touch_error("localtime_r failed: %s", strerror(errno));491 return errx(pCtx, 1, "localtime_r failed: %s", strerror(errno)); 512 492 513 493 /* … … 535 515 if (pDst->tv_sec != -1) 536 516 return 0; 537 return touch_error("mktime failed on '%s': %s", pszOldTs, strerror(errno));517 return errx(pCtx, 1, "mktime failed on '%s': %s", pszOldTs, strerror(errno)); 538 518 } 539 519 … … 544 524 545 525 /** 546 * Parses the arguments into p Opts.526 * Parses the arguments into pThis. 547 527 * 548 528 * @returns exit code. 549 * @param p Opts Options structure to return the parsed info in.529 * @param pThis Options structure to return the parsed info in. 550 530 * Caller initalizes this with defaults. 551 531 * @param cArgs The number of arguments. … … 554 534 * files. 555 535 */ 556 static int touch_parse_args(PKMKTOUCHOPTS p Opts, int cArgs, char **papszArgs, KBOOL *pfExit)536 static int touch_parse_args(PKMKTOUCHOPTS pThis, int cArgs, char **papszArgs, KBOOL *pfExit) 557 537 { 558 538 int iAdjustValue = 0; … … 583 563 { 584 564 while (++iArg < cArgs) 585 p Opts->papszFiles[pOpts->cFiles++] = papszArgs[iArg];565 pThis->papszFiles[pThis->cFiles++] = papszArgs[iArg]; 586 566 break; /* '--' */ 587 567 } … … 626 606 return kbuild_version(papszArgs[0]); 627 607 else 628 return touch_syntax("Unknown option: --%s", pszLong);608 return errx(pThis->pCtx, 2, "Unknown option: --%s", pszLong); 629 609 } 630 610 … … 651 631 pszValue = papszArgs[++iArg]; 652 632 else 653 return touch_syntax("Option -%c requires a value", ch);633 return errx(pThis->pCtx, 2, "Option -%c requires a value", ch); 654 634 break; 655 635 … … 663 643 /* -A [-][[HH]MM]SS */ 664 644 case 'A': 665 rc = touch_parse_adjust(p szValue, &iAdjustValue);645 rc = touch_parse_adjust(pThis->pCtx, pszValue, &iAdjustValue); 666 646 if (rc != 0) 667 647 return rc; 668 if (p Opts->enmAction != kTouchActionSet)648 if (pThis->enmAction != kTouchActionSet) 669 649 { 670 p Opts->enmAction = kTouchActionAdjust;671 p Opts->NewATime.tv_sec = iAdjustValue;672 p Opts->NewATime.tv_usec = 0;673 p Opts->NewMTime = pOpts->NewATime;650 pThis->enmAction = kTouchActionAdjust; 651 pThis->NewATime.tv_sec = iAdjustValue; 652 pThis->NewATime.tv_usec = 0; 653 pThis->NewMTime = pThis->NewATime; 674 654 } 675 655 /* else: applied after parsing everything. */ … … 677 657 678 658 case 'a': 679 p Opts->enmWhatToTouch = kTouchAccessOnly;659 pThis->enmWhatToTouch = kTouchAccessOnly; 680 660 break; 681 661 682 662 case 'c': 683 p Opts->fCreate = K_FALSE;663 pThis->fCreate = K_FALSE; 684 664 break; 685 665 686 666 case 'd': 687 rc = touch_parse_d_ts(p szValue, &pOpts->NewATime);667 rc = touch_parse_d_ts(pThis->pCtx, pszValue, &pThis->NewATime); 688 668 if (rc != 0) 689 669 return rc; 690 p Opts->enmAction = kTouchActionSet;691 p Opts->NewMTime = pOpts->NewATime;670 pThis->enmAction = kTouchActionSet; 671 pThis->NewMTime = pThis->NewATime; 692 672 break; 693 673 … … 697 677 698 678 case 'h': 699 p Opts->fDereference = K_FALSE;679 pThis->fDereference = K_FALSE; 700 680 break; 701 681 702 682 case 'm': 703 p Opts->enmWhatToTouch = kTouchModifyOnly;683 pThis->enmWhatToTouch = kTouchModifyOnly; 704 684 break; 705 685 … … 708 688 struct stat St; 709 689 if (stat(pszValue, &St) != 0) 710 return touch_error("Failed to stat '%s' (-r option): %s", pszValue, strerror(errno));711 712 p Opts->enmAction = kTouchActionSet;713 p Opts->NewATime.tv_sec = St.st_atime;714 p Opts->NewMTime.tv_sec = St.st_mtime;690 return errx(pThis->pCtx, 1, "Failed to stat '%s' (-r option): %s", pszValue, strerror(errno)); 691 692 pThis->enmAction = kTouchActionSet; 693 pThis->NewATime.tv_sec = St.st_atime; 694 pThis->NewMTime.tv_sec = St.st_mtime; 715 695 #if FILE_TIMESTAMP_HI_RES 716 p Opts->NewATime.tv_usec = St.st_atim.tv_nsec / 1000;717 p Opts->NewMTime.tv_usec = St.st_mtim.tv_nsec / 1000;696 pThis->NewATime.tv_usec = St.st_atim.tv_nsec / 1000; 697 pThis->NewMTime.tv_usec = St.st_mtim.tv_nsec / 1000; 718 698 #else 719 p Opts->NewATime.tv_usec = 0;720 p Opts->NewMTime.tv_usec = 0;699 pThis->NewATime.tv_usec = 0; 700 pThis->NewMTime.tv_usec = 0; 721 701 #endif 722 702 break; … … 724 704 725 705 case 't': 726 rc = touch_parse_ts(p szValue, &pOpts->NewATime);706 rc = touch_parse_ts(pThis->pCtx, pszValue, &pThis->NewATime); 727 707 if (rc != 0) 728 708 return rc; 729 p Opts->enmAction = kTouchActionSet;730 p Opts->NewMTime = pOpts->NewATime;709 pThis->enmAction = kTouchActionSet; 710 pThis->NewMTime = pThis->NewATime; 731 711 break; 732 712 … … 734 714 if ( strcmp(pszValue, "atime") == 0 735 715 || strcmp(pszValue, "access") == 0) 736 p Opts->enmWhatToTouch = kTouchAccessOnly;716 pThis->enmWhatToTouch = kTouchAccessOnly; 737 717 else if ( strcmp(pszValue, "mtime") == 0 738 718 || strcmp(pszValue, "modify") == 0) 739 p Opts->enmWhatToTouch = kTouchModifyOnly;719 pThis->enmWhatToTouch = kTouchModifyOnly; 740 720 else 741 return touch_syntax("Unknown --time value: %s", pszValue);721 return errx(pThis->pCtx, 2, "Unknown --time value: %s", pszValue); 742 722 break; 743 723 … … 746 726 747 727 default: 748 return touch_syntax("Unknown option: -%c (%c%s)", ch, ch, pszArg);728 return errx(pThis->pCtx, 2, "Unknown option: -%c (%c%s)", ch, ch, pszArg); 749 729 } 750 730 … … 752 732 } 753 733 else 754 p Opts->papszFiles[pOpts->cFiles++] = papszArgs[iArg];734 pThis->papszFiles[pThis->cFiles++] = papszArgs[iArg]; 755 735 } 756 736 … … 758 738 * Allow adjusting specified timestamps too like BSD does. 759 739 */ 760 if ( p Opts->enmAction == kTouchActionSet740 if ( pThis->enmAction == kTouchActionSet 761 741 && iAdjustValue != 0) 762 742 { 763 if ( p Opts->enmWhatToTouch == kTouchAccessAndModify764 || p Opts->enmWhatToTouch == kTouchAccessOnly)765 p Opts->NewATime.tv_sec += iAdjustValue;766 if ( p Opts->enmWhatToTouch == kTouchAccessAndModify767 || p Opts->enmWhatToTouch == kTouchModifyOnly)768 p Opts->NewMTime.tv_sec += iAdjustValue;743 if ( pThis->enmWhatToTouch == kTouchAccessAndModify 744 || pThis->enmWhatToTouch == kTouchAccessOnly) 745 pThis->NewATime.tv_sec += iAdjustValue; 746 if ( pThis->enmWhatToTouch == kTouchAccessAndModify 747 || pThis->enmWhatToTouch == kTouchModifyOnly) 748 pThis->NewMTime.tv_sec += iAdjustValue; 769 749 } 770 750 … … 772 752 * Check for old timestamp: MMDDhhmm[YY] 773 753 */ 774 if ( p Opts->enmAction == kTouchActionCurrent775 && p Opts->cFiles >= 2)754 if ( pThis->enmAction == kTouchActionCurrent 755 && pThis->cFiles >= 2) 776 756 { 777 757 struct timeval OldTs; 778 rc = touch_parse_old_ts(p Opts->papszFiles[0], pOpts->NewATime.tv_sec, &OldTs);758 rc = touch_parse_old_ts(pThis->pCtx, pThis->papszFiles[0], pThis->NewATime.tv_sec, &OldTs); 779 759 if (rc == 0) 780 760 { 781 761 int iFile; 782 762 783 p Opts->NewATime = OldTs;784 p Opts->NewMTime = OldTs;785 p Opts->enmAction = kTouchActionSet;786 787 for (iFile = 1; iFile < p Opts->cFiles; iFile++)788 p Opts->papszFiles[iFile - 1] = pOpts->papszFiles[iFile];789 p Opts->cFiles--;763 pThis->NewATime = OldTs; 764 pThis->NewMTime = OldTs; 765 pThis->enmAction = kTouchActionSet; 766 767 for (iFile = 1; iFile < pThis->cFiles; iFile++) 768 pThis->papszFiles[iFile - 1] = pThis->papszFiles[iFile]; 769 pThis->cFiles--; 790 770 } 791 771 else if (rc > 0) … … 796 776 * Check that we've found at least one file argument. 797 777 */ 798 if (p Opts->cFiles > 0)778 if (pThis->cFiles > 0) 799 779 { 800 780 *pfExit = K_FALSE; 801 781 return 0; 802 782 } 803 return touch_syntax("No file specified");783 return errx(pThis->pCtx, 2, "No file specified"); 804 784 } 805 785 … … 809 789 * 810 790 * @returns exit code. 811 * @param p Opts The options.791 * @param pThis The options. 812 792 * @param pszFile The file to touch. 813 793 */ 814 static int touch_process_file(PKMKTOUCHOPTS p Opts, const char *pszFile)794 static int touch_process_file(PKMKTOUCHOPTS pThis, const char *pszFile) 815 795 { 816 796 int fd; … … 823 803 * in effect, we silently skip the file if it doesn't already exist. 824 804 */ 825 if (p Opts->fDereference)805 if (pThis->fDereference) 826 806 rc = stat(pszFile, &St); 827 807 else … … 830 810 { 831 811 if (errno != ENOENT) 832 return touch_error("Failed to stat '%s': %s", pszFile, strerror(errno));833 834 if (!p Opts->fCreate)812 return errx(pThis->pCtx, 1, "Failed to stat '%s': %s", pszFile, strerror(errno)); 813 814 if (!pThis->fCreate) 835 815 return 0; 836 fd = open(pszFile, O_WRONLY | O_CREAT , 0666);816 fd = open(pszFile, O_WRONLY | O_CREAT | KMK_OPEN_NO_INHERIT, 0666); 837 817 if (fd == -1) 838 return touch_error("Failed to create '%s': %s", pszFile, strerror(errno));818 return errx(pThis->pCtx, 1, "Failed to create '%s': %s", pszFile, strerror(errno)); 839 819 840 820 /* If we're not setting the current time, we may need value stat info 841 821 on the file, so get it thru the file descriptor before closing it. */ 842 if (p Opts->enmAction == kTouchActionCurrent)822 if (pThis->enmAction == kTouchActionCurrent) 843 823 rc = 0; 844 824 else 845 825 rc = fstat(fd, &St); 846 826 if (close(fd) != 0) 847 return touch_error("Failed to close '%s' after creation: %s", pszFile, strerror(errno));827 return errx(pThis->pCtx, 1, "Failed to close '%s' after creation: %s", pszFile, strerror(errno)); 848 828 if (rc != 0) 849 return touch_error("Failed to fstat '%s' after creation: %s", pszFile, strerror(errno));829 return errx(pThis->pCtx, 1, "Failed to fstat '%s' after creation: %s", pszFile, strerror(errno)); 850 830 851 831 /* We're done now if we're setting the current time. */ 852 if (p Opts->enmAction == kTouchActionCurrent)832 if (pThis->enmAction == kTouchActionCurrent) 853 833 return 0; 854 834 } … … 866 846 aTimes[1].tv_usec = 0; 867 847 #endif 868 if ( p Opts->enmWhatToTouch == kTouchAccessAndModify869 || p Opts->enmWhatToTouch == kTouchAccessOnly)870 { 871 if ( p Opts->enmAction == kTouchActionCurrent872 || p Opts->enmAction == kTouchActionSet)873 aTimes[0] = p Opts->NewATime;848 if ( pThis->enmWhatToTouch == kTouchAccessAndModify 849 || pThis->enmWhatToTouch == kTouchAccessOnly) 850 { 851 if ( pThis->enmAction == kTouchActionCurrent 852 || pThis->enmAction == kTouchActionSet) 853 aTimes[0] = pThis->NewATime; 874 854 else 875 aTimes[0].tv_sec += p Opts->NewATime.tv_sec;876 } 877 if ( p Opts->enmWhatToTouch == kTouchAccessAndModify878 || p Opts->enmWhatToTouch == kTouchModifyOnly)879 { 880 if ( p Opts->enmAction == kTouchActionCurrent881 || p Opts->enmAction == kTouchActionSet)882 aTimes[1] = p Opts->NewMTime;855 aTimes[0].tv_sec += pThis->NewATime.tv_sec; 856 } 857 if ( pThis->enmWhatToTouch == kTouchAccessAndModify 858 || pThis->enmWhatToTouch == kTouchModifyOnly) 859 { 860 if ( pThis->enmAction == kTouchActionCurrent 861 || pThis->enmAction == kTouchActionSet) 862 aTimes[1] = pThis->NewMTime; 883 863 else 884 aTimes[1].tv_sec += p Opts->NewMTime.tv_sec;864 aTimes[1].tv_sec += pThis->NewMTime.tv_sec; 885 865 } 886 866 … … 891 871 * may do more than what we want (st_ctime).) 892 872 */ 893 if (p Opts->fDereference)873 if (pThis->fDereference) 894 874 rc = utimes(pszFile, aTimes); 895 875 else … … 897 877 if (rc != 0) 898 878 { 899 if (p Opts->enmAction == kTouchActionCurrent)879 if (pThis->enmAction == kTouchActionCurrent) 900 880 { 901 if (p Opts->fDereference)881 if (pThis->fDereference) 902 882 rc = utimes(pszFile, NULL); 903 883 else … … 905 885 } 906 886 if (rc != 0) 907 rc = touch_error("%stimes failed on '%s': %s", pOpts->fDereference ? "" : "l", pszFile, strerror(errno));887 rc = errx(pThis->pCtx, 1, "%stimes failed on '%s': %s", pThis->fDereference ? "" : "l", pszFile, strerror(errno)); 908 888 } 909 889 … … 913 893 914 894 /** 915 * The function that does almost everything here... ugly.895 * Actual main function for the touch command. 916 896 */ 917 #ifdef KMK 918 int kmk_builtin_touch(int argc, char **argv, char **envp) 919 #else 920 int main(int argc, char **argv, char **envp) 921 #endif 897 int kmk_builtin_touch(int argc, char **argv, char **envp, PKMKBUILTINCTX pCtx) 922 898 { 923 899 int rc; 924 KMKTOUCHOPTS Opts;900 KMKTOUCHOPTS This; 925 901 K_NOREF(envp); 926 902 … … 928 904 * Initialize options with defaults and parse them. 929 905 */ 930 Opts.enmWhatToTouch = kTouchAccessAndModify; 931 Opts.enmAction = kTouchActionCurrent; 932 Opts.fCreate = K_TRUE; 933 Opts.fDereference = K_TRUE; 934 Opts.cFiles = 0; 935 Opts.papszFiles = (char **)calloc(argc, sizeof(char *)); 936 if (Opts.papszFiles) 937 { 938 rc = gettimeofday(&Opts.NewATime, NULL); 906 This.pCtx = pCtx; 907 This.enmWhatToTouch = kTouchAccessAndModify; 908 This.enmAction = kTouchActionCurrent; 909 This.fCreate = K_TRUE; 910 This.fDereference = K_TRUE; 911 This.cFiles = 0; 912 This.papszFiles = (char **)calloc(argc, sizeof(char *)); 913 if (This.papszFiles) 914 { 915 rc = gettimeofday(&This.NewATime, NULL); 939 916 if (rc == 0) 940 917 { 941 918 KBOOL fExit; 942 Opts.NewMTime = Opts.NewATime;943 944 rc = touch_parse_args(& Opts, argc, argv, &fExit);919 This.NewMTime = This.NewATime; 920 921 rc = touch_parse_args(&This, argc, argv, &fExit); 945 922 if (rc == 0 && !fExit) 946 923 { … … 949 926 */ 950 927 int iFile; 951 for (iFile = 0; iFile < Opts.cFiles; iFile++)928 for (iFile = 0; iFile < This.cFiles; iFile++) 952 929 { 953 int rc2 = touch_process_file(& Opts, Opts.papszFiles[iFile]);930 int rc2 = touch_process_file(&This, This.papszFiles[iFile]); 954 931 if (rc2 != 0 && rc == 0) 955 932 rc = rc2; … … 958 935 } 959 936 else 960 rc = touch_error("gettimeofday failed: %s", strerror(errno));961 free( Opts.papszFiles);937 rc = errx(pCtx, 2, "gettimeofday failed: %s", strerror(errno)); 938 free(This.papszFiles); 962 939 } 963 940 else 964 rc = touch_error("calloc failed");941 rc = errx(pCtx, 2, "calloc failed"); 965 942 return rc; 966 943 } 967 944 945 #ifdef KMK_BUILTIN_STANDALONE 946 int main(int argc, char **argv, char **envp) 947 { 948 KMKBUILTINCTX Ctx = { "kmk_touch", NULL }; 949 return kmk_builtin_touch(argc, argv, envp, &Ctx); 950 } 951 #endif 952
Note:
See TracChangeset
for help on using the changeset viewer.