home *** CD-ROM | disk | FTP | other *** search
- To: vim_dev@googlegroups.com
- Subject: Patch 7.3.1182
- Fcc: outbox
- From: Bram Moolenaar <Bram@moolenaar.net>
- 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 ///
-