Mercurial > vim
comparison src/os_mswin.c @ 9387:f094d4085014 v7.4.1975
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Jul 1 17:17:39 2016 +0200
patch 7.4.1975
Problem: On MS-Windows large files (> 2Gbyte) cause problems.
Solution: Use "off_T" instead of "off_t". Use "stat_T" instead of "struct
stat". Use 64 bit system functions if available. (Ken Takata)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 01 Jul 2016 17:30:07 +0200 |
parents | 294cfd18e9c7 |
children | 4aead6a9b7a9 |
comparison
equal
deleted
inserted
replaced
9386:80deab13679b | 9387:f094d4085014 |
---|---|
479 *p = psepc; | 479 *p = psepc; |
480 mb_ptr_adv(p); | 480 mb_ptr_adv(p); |
481 } | 481 } |
482 } | 482 } |
483 | 483 |
484 /* Use 64-bit stat functions if available. */ | |
485 #ifdef HAVE_STAT64 | |
486 # undef stat | |
487 # undef _stat | |
488 # undef _wstat | |
489 # undef _fstat | |
490 # define stat _stat64 | |
491 # define _stat _stat64 | |
492 # define _wstat _wstat64 | |
493 # define _fstat _fstat64 | |
494 #endif | |
495 | |
484 #if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__) | 496 #if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__) |
485 # define OPEN_OH_ARGTYPE intptr_t | 497 # define OPEN_OH_ARGTYPE intptr_t |
486 #else | 498 #else |
487 # define OPEN_OH_ARGTYPE long | 499 # define OPEN_OH_ARGTYPE long |
488 #endif | 500 #endif |
489 | 501 |
490 static int | 502 static int |
491 stat_symlink_aware(const char *name, struct stat *stp) | 503 stat_symlink_aware(const char *name, stat_T *stp) |
492 { | 504 { |
493 #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__) | 505 #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__) |
494 /* Work around for VC12 or earlier (and MinGW). stat() can't handle | 506 /* Work around for VC12 or earlier (and MinGW). stat() can't handle |
495 * symlinks properly. | 507 * symlinks properly. |
496 * VC9 or earlier: stat() doesn't support a symlink at all. It retrieves | 508 * VC9 or earlier: stat() doesn't support a symlink at all. It retrieves |
525 if (h != INVALID_HANDLE_VALUE) | 537 if (h != INVALID_HANDLE_VALUE) |
526 { | 538 { |
527 int fd, n; | 539 int fd, n; |
528 | 540 |
529 fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY); | 541 fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY); |
530 n = _fstat(fd, (struct _stat*)stp); | 542 n = _fstat(fd, (struct _stat *)stp); |
531 if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY)) | 543 if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY)) |
532 stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR; | 544 stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR; |
533 _close(fd); | 545 _close(fd); |
534 return n; | 546 return n; |
535 } | 547 } |
538 return stat(name, stp); | 550 return stat(name, stp); |
539 } | 551 } |
540 | 552 |
541 #ifdef FEAT_MBYTE | 553 #ifdef FEAT_MBYTE |
542 static int | 554 static int |
543 wstat_symlink_aware(const WCHAR *name, struct _stat *stp) | 555 wstat_symlink_aware(const WCHAR *name, stat_T *stp) |
544 { | 556 { |
545 # if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__) | 557 # if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__) |
546 /* Work around for VC12 or earlier (and MinGW). _wstat() can't handle | 558 /* Work around for VC12 or earlier (and MinGW). _wstat() can't handle |
547 * symlinks properly. | 559 * symlinks properly. |
548 * VC9 or earlier: _wstat() doesn't support a symlink at all. It retrieves | 560 * VC9 or earlier: _wstat() doesn't support a symlink at all. It retrieves |
578 if (h != INVALID_HANDLE_VALUE) | 590 if (h != INVALID_HANDLE_VALUE) |
579 { | 591 { |
580 int fd; | 592 int fd; |
581 | 593 |
582 fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY); | 594 fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY); |
583 n = _fstat(fd, stp); | 595 n = _fstat(fd, (struct _stat *)stp); |
584 if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY)) | 596 if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY)) |
585 stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR; | 597 stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR; |
586 _close(fd); | 598 _close(fd); |
587 return n; | 599 return n; |
588 } | 600 } |
589 } | 601 } |
590 # endif | 602 # endif |
591 return _wstat(name, stp); | 603 return _wstat(name, (struct _stat *)stp); |
592 } | 604 } |
593 #endif | 605 #endif |
594 | 606 |
595 /* | 607 /* |
596 * stat() can't handle a trailing '/' or '\', remove it first. | 608 * stat() can't handle a trailing '/' or '\', remove it first. |
597 */ | 609 */ |
598 int | 610 int |
599 vim_stat(const char *name, struct stat *stp) | 611 vim_stat(const char *name, stat_T *stp) |
600 { | 612 { |
601 #ifdef FEAT_MBYTE | 613 #ifdef FEAT_MBYTE |
602 /* WinNT and later can use _MAX_PATH wide characters for a pathname, which | 614 /* WinNT and later can use _MAX_PATH wide characters for a pathname, which |
603 * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is | 615 * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is |
604 * UTF-8. */ | 616 * UTF-8. */ |
639 WCHAR *wp = enc_to_utf16(buf, NULL); | 651 WCHAR *wp = enc_to_utf16(buf, NULL); |
640 int n; | 652 int n; |
641 | 653 |
642 if (wp != NULL) | 654 if (wp != NULL) |
643 { | 655 { |
644 n = wstat_symlink_aware(wp, (struct _stat *)stp); | 656 n = wstat_symlink_aware(wp, stp); |
645 vim_free(wp); | 657 vim_free(wp); |
646 if (n >= 0 || g_PlatformId == VER_PLATFORM_WIN32_NT) | 658 if (n >= 0 || g_PlatformId == VER_PLATFORM_WIN32_NT) |
647 return n; | 659 return n; |
648 /* Retry with non-wide function (for Windows 98). Can't use | 660 /* Retry with non-wide function (for Windows 98). Can't use |
649 * GetLastError() here and it's unclear what errno gets set to if | 661 * GetLastError() here and it's unclear what errno gets set to if |