From 78d1401eccc469e19cf6177c6a74cfc62ef9d899 Mon Sep 17 00:00:00 2001 From: Karsten Hopp Date: Jun 13 2013 22:29:08 +0000 Subject: - patchlevel 1182 --- diff --git a/7.3.1182 b/7.3.1182 new file mode 100644 index 0000000..eb3a298 --- /dev/null +++ b/7.3.1182 @@ -0,0 +1,588 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.3.1182 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 7.3.1182 +Problem: 'backupcopy' default on MS-Windows does not work for hard and soft + links. +Solution: Check for links. (David Pope, Ken Takata) +Files: src/fileio.c, src/os_win32.c, src/proto/os_win32.pro + + +*** ../vim-7.3.1181/src/fileio.c 2013-06-12 19:52:11.000000000 +0200 +--- src/fileio.c 2013-06-12 22:31:34.000000000 +0200 +*************** +*** 3780,3791 **** + } + } + +- # ifdef UNIX + /* + * Break symlinks and/or hardlinks if we've been asked to. + */ + if ((bkc_flags & BKC_BREAKSYMLINK) || (bkc_flags & BKC_BREAKHARDLINK)) + { + int lstat_res; + + lstat_res = mch_lstat((char *)fname, &st); +--- 3780,3791 ---- + } + } + + /* + * Break symlinks and/or hardlinks if we've been asked to. + */ + if ((bkc_flags & BKC_BREAKSYMLINK) || (bkc_flags & BKC_BREAKHARDLINK)) + { ++ # ifdef UNIX + int lstat_res; + + lstat_res = mch_lstat((char *)fname, &st); +*************** +*** 3801,3808 **** + && st_old.st_nlink > 1 + && (lstat_res != 0 || st.st_ino == st_old.st_ino)) + backup_copy = FALSE; + } +- #endif + + #endif + +--- 3801,3818 ---- + && st_old.st_nlink > 1 + && (lstat_res != 0 || st.st_ino == st_old.st_ino)) + backup_copy = FALSE; ++ # else ++ # if defined(WIN32) ++ /* Symlinks. */ ++ if ((bkc_flags & BKC_BREAKSYMLINK) && mch_is_symbolic_link(fname)) ++ backup_copy = FALSE; ++ ++ /* Hardlinks. */ ++ if ((bkc_flags & BKC_BREAKHARDLINK) && mch_is_hard_link(fname)) ++ backup_copy = FALSE; ++ # endif ++ # endif + } + + #endif + +*** ../vim-7.3.1181/src/os_win32.c 2013-06-07 19:17:12.000000000 +0200 +--- src/os_win32.c 2013-06-12 22:39:53.000000000 +0200 +*************** +*** 78,83 **** +--- 78,93 ---- + # endif + #endif + ++ /* ++ * Reparse Point ++ */ ++ #ifndef FILE_ATTRIBUTE_REPARSE_POINT ++ # define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 ++ #endif ++ #ifndef IO_REPARSE_TAG_SYMLINK ++ # define IO_REPARSE_TAG_SYMLINK 0xA000000C ++ #endif ++ + /* Record all output and all keyboard & mouse input */ + /* #define MCH_WRITE_DUMP */ + +*************** +*** 219,224 **** +--- 229,238 ---- + static char *vimrun_path = "vimrun "; + #endif + ++ static int win32_getattrs(char_u *name); ++ static int win32_setattrs(char_u *name, int attrs); ++ static int win32_set_archive(char_u *name); ++ + #ifndef FEAT_GUI_W32 + static int suppress_winsize = 1; /* don't fiddle with console */ + #endif +*************** +*** 2623,2679 **** + /* + * get file permissions for `name' + * -1 : error +! * else FILE_ATTRIBUTE_* defined in winnt.h + */ + long + mch_getperm(char_u *name) + { +! #ifdef FEAT_MBYTE +! if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) +! { +! WCHAR *p = enc_to_utf16(name, NULL); +! long n; + +! if (p != NULL) +! { +! n = (long)GetFileAttributesW(p); +! vim_free(p); +! if (n >= 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) +! return n; +! /* Retry with non-wide function (for Windows 98). */ +! } +! } +! #endif +! return (long)GetFileAttributes((char *)name); + } + + + /* + * set file permission for `name' to `perm' + */ + int + mch_setperm( + char_u *name, + long perm) + { +! perm |= FILE_ATTRIBUTE_ARCHIVE; /* file has changed, set archive bit */ + #ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { +! WCHAR *p = enc_to_utf16(name, NULL); +! long n; + + if (p != NULL) + { +! n = (long)SetFileAttributesW(p, perm); + vim_free(p); +! if (n || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) +! return n ? OK : FAIL; + /* Retry with non-wide function (for Windows 98). */ + } + } + #endif +! return SetFileAttributes((char *)name, perm) ? OK : FAIL; + } + + /* +--- 2637,2690 ---- + /* + * get file permissions for `name' + * -1 : error +! * else mode_t + */ + long + mch_getperm(char_u *name) + { +! struct stat st; +! int n; + +! n = mch_stat(name, &st); +! return n == 0 ? (int)st.st_mode : -1; + } + + + /* + * set file permission for `name' to `perm' ++ * ++ * return FAIL for failure, OK otherwise + */ + int + mch_setperm( + char_u *name, + long perm) + { +! long n; + #ifdef FEAT_MBYTE ++ WCHAR *p; + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { +! p = enc_to_utf16(name, NULL); + + if (p != NULL) + { +! n = _wchmod(p, perm); + vim_free(p); +! if (n == -1 && GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) +! return FAIL; + /* Retry with non-wide function (for Windows 98). */ + } + } ++ if (p == NULL) + #endif +! n = _chmod(name, perm); +! if (n == -1) +! return FAIL; +! +! win32_set_archive(name); +! +! return OK; + } + + /* +*************** +*** 2682,2730 **** + void + mch_hide(char_u *name) + { +! int perm; +! #ifdef FEAT_MBYTE +! WCHAR *p = NULL; +! +! if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) +! p = enc_to_utf16(name, NULL); +! #endif + +! #ifdef FEAT_MBYTE +! if (p != NULL) +! { +! perm = GetFileAttributesW(p); +! if (perm < 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) +! { +! /* Retry with non-wide function (for Windows 98). */ +! vim_free(p); +! p = NULL; +! } +! } +! if (p == NULL) +! #endif +! perm = GetFileAttributes((char *)name); +! if (perm >= 0) +! { +! perm |= FILE_ATTRIBUTE_HIDDEN; +! #ifdef FEAT_MBYTE +! if (p != NULL) +! { +! if (SetFileAttributesW(p, perm) == 0 +! && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) +! { +! /* Retry with non-wide function (for Windows 98). */ +! vim_free(p); +! p = NULL; +! } +! } +! if (p == NULL) +! #endif +! SetFileAttributes((char *)name, perm); +! } +! #ifdef FEAT_MBYTE +! vim_free(p); +! #endif + } + + /* +--- 2693,2704 ---- + void + mch_hide(char_u *name) + { +! int attrs = win32_getattrs(name); +! if (attrs == -1) +! return; + +! attrs |= FILE_ATTRIBUTE_HIDDEN; +! win32_setattrs(name, attrs); + } + + /* +*************** +*** 2734,2740 **** + int + mch_isdir(char_u *name) + { +! int f = mch_getperm(name); + + if (f == -1) + return FALSE; /* file does not exist at all */ +--- 2708,2714 ---- + int + mch_isdir(char_u *name) + { +! int f = win32_getattrs(name); + + if (f == -1) + return FALSE; /* file does not exist at all */ +*************** +*** 2770,2776 **** + * Return TRUE if file "fname" has more than one link. + */ + int +! mch_is_linked(char_u *fname) + { + BY_HANDLE_FILE_INFORMATION info; + +--- 2744,2750 ---- + * Return TRUE if file "fname" has more than one link. + */ + int +! mch_is_hard_link(char_u *fname) + { + BY_HANDLE_FILE_INFORMATION info; + +*************** +*** 2779,2784 **** +--- 2753,2826 ---- + } + + /* ++ * Return TRUE if file "fname" is a symbolic link. ++ */ ++ int ++ mch_is_symbolic_link(char_u *fname) ++ { ++ HANDLE hFind; ++ int res = FALSE; ++ WIN32_FIND_DATAA findDataA; ++ DWORD fileFlags = 0, reparseTag = 0; ++ #ifdef FEAT_MBYTE ++ WCHAR *wn = NULL; ++ WIN32_FIND_DATAW findDataW; ++ ++ if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) ++ wn = enc_to_utf16(fname, NULL); ++ if (wn != NULL) ++ { ++ hFind = FindFirstFileW(wn, &findDataW); ++ vim_free(wn); ++ if (hFind == INVALID_HANDLE_VALUE ++ && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) ++ { ++ /* Retry with non-wide function (for Windows 98). */ ++ hFind = FindFirstFile(fname, &findDataA); ++ if (hFind != INVALID_HANDLE_VALUE) ++ { ++ fileFlags = findDataA.dwFileAttributes; ++ reparseTag = findDataA.dwReserved0; ++ } ++ } ++ else ++ { ++ fileFlags = findDataW.dwFileAttributes; ++ reparseTag = findDataW.dwReserved0; ++ } ++ } ++ #else ++ hFind = FindFirstFile(fname, &findDataA); ++ if (hFind != INVALID_HANDLE_VALUE) ++ { ++ fileFlags = findDataA.dwFileAttributes; ++ reparseTag = findDataA.dwReserved0; ++ } ++ #endif ++ ++ if (hFind != INVALID_HANDLE_VALUE) ++ FindClose(hFind); ++ ++ if ((fileFlags & FILE_ATTRIBUTE_REPARSE_POINT) ++ && reparseTag == IO_REPARSE_TAG_SYMLINK) ++ res = TRUE; ++ ++ return res; ++ } ++ ++ /* ++ * Return TRUE if file "fname" has more than one link or if it is a symbolic ++ * link. ++ */ ++ int ++ mch_is_linked(char_u *fname) ++ { ++ if (mch_is_hard_link(fname) || mch_is_symbolic_link(fname)) ++ return TRUE; ++ return FALSE; ++ } ++ ++ /* + * Get the by-handle-file-information for "fname". + * Returns FILEINFO_OK when OK. + * returns FILEINFO_ENC_FAIL when enc_to_utf16() failed. +*************** +*** 2842,2847 **** +--- 2884,2975 ---- + } + + /* ++ * get file attributes for `name' ++ * -1 : error ++ * else FILE_ATTRIBUTE_* defined in winnt.h ++ */ ++ static ++ int ++ win32_getattrs(char_u *name) ++ { ++ int attr; ++ #ifdef FEAT_MBYTE ++ WCHAR *p = NULL; ++ ++ if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) ++ p = enc_to_utf16(name, NULL); ++ ++ if (p != NULL) ++ { ++ attr = GetFileAttributesW(p); ++ if (attr < 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) ++ { ++ /* Retry with non-wide function (for Windows 98). */ ++ vim_free(p); ++ p = NULL; ++ } ++ } ++ if (p == NULL) ++ #endif ++ attr = GetFileAttributes((char *)name); ++ #ifdef FEAT_MBYTE ++ vim_free(p); ++ #endif ++ return attr; ++ } ++ ++ /* ++ * set file attributes for `name' to `attrs' ++ * ++ * return -1 for failure, 0 otherwise ++ */ ++ static ++ int ++ win32_setattrs(char_u *name, int attrs) ++ { ++ int res; ++ #ifdef FEAT_MBYTE ++ WCHAR *p = NULL; ++ ++ if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) ++ p = enc_to_utf16(name, NULL); ++ ++ if (p != NULL) ++ { ++ res = SetFileAttributesW(p, attrs); ++ if (res == FALSE ++ && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) ++ { ++ /* Retry with non-wide function (for Windows 98). */ ++ vim_free(p); ++ p = NULL; ++ } ++ } ++ if (p == NULL) ++ #endif ++ res = SetFileAttributes((char *)name, attrs); ++ #ifdef FEAT_MBYTE ++ vim_free(p); ++ #endif ++ return res ? 0 : -1; ++ } ++ ++ /* ++ * Set archive flag for "name". ++ */ ++ static ++ int ++ win32_set_archive(char_u *name) ++ { ++ int attrs = win32_getattrs(name); ++ if (attrs == -1) ++ return -1; ++ ++ attrs |= FILE_ATTRIBUTE_ARCHIVE; ++ return win32_setattrs(name, attrs); ++ } ++ ++ /* + * Return TRUE if file or directory "name" is writable (not readonly). + * Strange semantics of Win32: a readonly directory is writable, but you can't + * delete a file. Let's say this means it is writable. +*************** +*** 2849,2858 **** + int + mch_writable(char_u *name) + { +! int perm = mch_getperm(name); + +! return (perm != -1 && (!(perm & FILE_ATTRIBUTE_READONLY) +! || (perm & FILE_ATTRIBUTE_DIRECTORY))); + } + + /* +--- 2977,2986 ---- + int + mch_writable(char_u *name) + { +! int attrs = win32_getattrs(name); + +! return (attrs != -1 && (!(attrs & FILE_ATTRIBUTE_READONLY) +! || (attrs & FILE_ATTRIBUTE_DIRECTORY))); + } + + /* +*************** +*** 5012,5024 **** + #ifdef FEAT_MBYTE + WCHAR *wn = NULL; + int n; + + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + wn = enc_to_utf16(name, NULL); + if (wn != NULL) + { +- SetFileAttributesW(wn, FILE_ATTRIBUTE_NORMAL); + n = DeleteFileW(wn) ? 0 : -1; + vim_free(wn); + if (n == 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) +--- 5140,5155 ---- + #ifdef FEAT_MBYTE + WCHAR *wn = NULL; + int n; ++ #endif + ++ win32_setattrs(name, FILE_ATTRIBUTE_NORMAL); ++ ++ #ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + wn = enc_to_utf16(name, NULL); + if (wn != NULL) + { + n = DeleteFileW(wn) ? 0 : -1; + vim_free(wn); + if (n == 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) +*************** +*** 5027,5033 **** + } + } + #endif +- SetFileAttributes(name, FILE_ATTRIBUTE_NORMAL); + return DeleteFile(name) ? 0 : -1; + } + +--- 5158,5163 ---- +*** ../vim-7.3.1181/src/proto/os_win32.pro 2012-11-20 16:56:49.000000000 +0100 +--- src/proto/os_win32.pro 2013-06-12 22:29:53.000000000 +0200 +*************** +*** 21,26 **** +--- 21,28 ---- + void mch_hide __ARGS((char_u *name)); + int mch_isdir __ARGS((char_u *name)); + int mch_mkdir __ARGS((char_u *name)); ++ int mch_is_hard_link __ARGS((char_u *fname)); ++ int mch_is_symbolic_link __ARGS((char_u *fname)); + int mch_is_linked __ARGS((char_u *fname)); + int win32_fileinfo __ARGS((char_u *fname, BY_HANDLE_FILE_INFORMATION *info)); + int mch_writable __ARGS((char_u *name)); +*** ../vim-7.3.1181/src/version.c 2013-06-12 22:08:54.000000000 +0200 +--- src/version.c 2013-06-12 22:40:29.000000000 +0200 +*************** +*** 730,731 **** +--- 730,733 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 1182, + /**/ + +-- +If Microsoft would build a car... +... You'd have to press the "Start" button to turn the engine off. + + /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ +/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ +\\\ an exciting new programming language -- http://www.Zimbu.org /// + \\\ help me help AIDS victims -- http://ICCF-Holland.org ///