Karsten Hopp 527e92
To: vim_dev@googlegroups.com
Karsten Hopp 527e92
Subject: Patch 7.3.172
Karsten Hopp 527e92
Fcc: outbox
Karsten Hopp 527e92
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 527e92
Mime-Version: 1.0
Karsten Hopp 527e92
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 527e92
Content-Transfer-Encoding: 8bit
Karsten Hopp 527e92
------------
Karsten Hopp 527e92
Karsten Hopp 527e92
Patch 7.3.172
Karsten Hopp 527e92
Problem:    MS-Windows: rename() might delete the file if the name differs but
Karsten Hopp 527e92
	    it's actually the same file.
Karsten Hopp 527e92
Solution:   Use the file handle to check if it's the same file. (Yukihiro
Karsten Hopp 527e92
	    Nakadaira)
Karsten Hopp 527e92
Files:	    src/if_cscope.c, src/fileio.c, src/os_win32.c,
Karsten Hopp 527e92
	    src/proto/os_win32.pro, src/vim.h
Karsten Hopp 527e92
Karsten Hopp 527e92
Karsten Hopp 527e92
*** ../vim-7.3.171/src/if_cscope.c	2011-03-03 15:01:25.000000000 +0100
Karsten Hopp 527e92
--- src/if_cscope.c	2011-05-05 16:16:38.000000000 +0200
Karsten Hopp 527e92
***************
Karsten Hopp 527e92
*** 1412,1428 ****
Karsten Hopp 527e92
  {
Karsten Hopp 527e92
      short	i, j;
Karsten Hopp 527e92
  #ifndef UNIX
Karsten Hopp 527e92
-     HANDLE	hFile;
Karsten Hopp 527e92
      BY_HANDLE_FILE_INFORMATION bhfi;
Karsten Hopp 527e92
  
Karsten Hopp 527e92
-     vim_memset(&bhfi, 0, sizeof(bhfi));
Karsten Hopp 527e92
      /* On windows 9x GetFileInformationByHandle doesn't work, so skip it */
Karsten Hopp 527e92
      if (!mch_windows95())
Karsten Hopp 527e92
      {
Karsten Hopp 527e92
! 	hFile = CreateFile(fname, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
Karsten Hopp 527e92
! 						 FILE_ATTRIBUTE_NORMAL, NULL);
Karsten Hopp 527e92
! 	if (hFile == INVALID_HANDLE_VALUE)
Karsten Hopp 527e92
  	{
Karsten Hopp 527e92
  	    if (p_csverbose)
Karsten Hopp 527e92
  	    {
Karsten Hopp 527e92
  		char *cant_msg = _("E625: cannot open cscope database: %s");
Karsten Hopp 527e92
--- 1412,1426 ----
Karsten Hopp 527e92
  {
Karsten Hopp 527e92
      short	i, j;
Karsten Hopp 527e92
  #ifndef UNIX
Karsten Hopp 527e92
      BY_HANDLE_FILE_INFORMATION bhfi;
Karsten Hopp 527e92
  
Karsten Hopp 527e92
      /* On windows 9x GetFileInformationByHandle doesn't work, so skip it */
Karsten Hopp 527e92
      if (!mch_windows95())
Karsten Hopp 527e92
      {
Karsten Hopp 527e92
! 	switch (win32_fileinfo(fname, &bhfi))
Karsten Hopp 527e92
  	{
Karsten Hopp 527e92
+ 	case FILEINFO_ENC_FAIL:		/* enc_to_utf16() failed */
Karsten Hopp 527e92
+ 	case FILEINFO_READ_FAIL:	/* CreateFile() failed */
Karsten Hopp 527e92
  	    if (p_csverbose)
Karsten Hopp 527e92
  	    {
Karsten Hopp 527e92
  		char *cant_msg = _("E625: cannot open cscope database: %s");
Karsten Hopp 527e92
***************
Karsten Hopp 527e92
*** 1438,1452 ****
Karsten Hopp 527e92
  		    (void)EMSG2(cant_msg, fname);
Karsten Hopp 527e92
  	    }
Karsten Hopp 527e92
  	    return -1;
Karsten Hopp 527e92
! 	}
Karsten Hopp 527e92
! 	if (!GetFileInformationByHandle(hFile, &bhfi))
Karsten Hopp 527e92
! 	{
Karsten Hopp 527e92
! 	    CloseHandle(hFile);
Karsten Hopp 527e92
  	    if (p_csverbose)
Karsten Hopp 527e92
  		(void)EMSG(_("E626: cannot get cscope database information"));
Karsten Hopp 527e92
  	    return -1;
Karsten Hopp 527e92
  	}
Karsten Hopp 527e92
- 	CloseHandle(hFile);
Karsten Hopp 527e92
      }
Karsten Hopp 527e92
  #endif
Karsten Hopp 527e92
  
Karsten Hopp 527e92
--- 1436,1447 ----
Karsten Hopp 527e92
  		    (void)EMSG2(cant_msg, fname);
Karsten Hopp 527e92
  	    }
Karsten Hopp 527e92
  	    return -1;
Karsten Hopp 527e92
! 
Karsten Hopp 527e92
! 	case FILEINFO_INFO_FAIL:    /* GetFileInformationByHandle() failed */
Karsten Hopp 527e92
  	    if (p_csverbose)
Karsten Hopp 527e92
  		(void)EMSG(_("E626: cannot get cscope database information"));
Karsten Hopp 527e92
  	    return -1;
Karsten Hopp 527e92
  	}
Karsten Hopp 527e92
      }
Karsten Hopp 527e92
  #endif
Karsten Hopp 527e92
  
Karsten Hopp 527e92
*** ../vim-7.3.171/src/fileio.c	2011-04-11 21:35:03.000000000 +0200
Karsten Hopp 527e92
--- src/fileio.c	2011-05-05 16:22:22.000000000 +0200
Karsten Hopp 527e92
***************
Karsten Hopp 527e92
*** 6555,6560 ****
Karsten Hopp 527e92
--- 6555,6575 ----
Karsten Hopp 527e92
  	    use_tmp_file = TRUE;
Karsten Hopp 527e92
      }
Karsten Hopp 527e92
  #endif
Karsten Hopp 527e92
+ #ifdef WIN3264
Karsten Hopp 527e92
+     {
Karsten Hopp 527e92
+ 	BY_HANDLE_FILE_INFORMATION info1, info2;
Karsten Hopp 527e92
+ 
Karsten Hopp 527e92
+ 	/* It's possible for the source and destination to be the same file.
Karsten Hopp 527e92
+ 	 * In that case go through a temp file name.  This makes rename("foo",
Karsten Hopp 527e92
+ 	 * "./foo") a no-op (in a complicated way). */
Karsten Hopp 527e92
+ 	if (win32_fileinfo(from, &info1) == FILEINFO_OK
Karsten Hopp 527e92
+ 		&& win32_fileinfo(to, &info2) == FILEINFO_OK
Karsten Hopp 527e92
+ 		&& info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
Karsten Hopp 527e92
+ 		&& info1.nFileIndexHigh == info2.nFileIndexHigh
Karsten Hopp 527e92
+ 		&& info1.nFileIndexLow == info2.nFileIndexLow)
Karsten Hopp 527e92
+ 	    use_tmp_file = TRUE;
Karsten Hopp 527e92
+     }
Karsten Hopp 527e92
+ #endif
Karsten Hopp 527e92
  
Karsten Hopp 527e92
  #if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
Karsten Hopp 527e92
      if (use_tmp_file)
Karsten Hopp 527e92
*** ../vim-7.3.171/src/os_win32.c	2011-02-01 13:48:47.000000000 +0100
Karsten Hopp 527e92
--- src/os_win32.c	2011-05-05 16:24:17.000000000 +0200
Karsten Hopp 527e92
***************
Karsten Hopp 527e92
*** 2645,2669 ****
Karsten Hopp 527e92
      int
Karsten Hopp 527e92
  mch_is_linked(char_u *fname)
Karsten Hopp 527e92
  {
Karsten Hopp 527e92
      HANDLE	hFile;
Karsten Hopp 527e92
!     int		res = 0;
Karsten Hopp 527e92
!     BY_HANDLE_FILE_INFORMATION inf;
Karsten Hopp 527e92
  #ifdef FEAT_MBYTE
Karsten Hopp 527e92
      WCHAR	*wn = NULL;
Karsten Hopp 527e92
  
Karsten Hopp 527e92
      if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
Karsten Hopp 527e92
  	wn = enc_to_utf16(fname, NULL);
Karsten Hopp 527e92
      if (wn != NULL)
Karsten Hopp 527e92
      {
Karsten Hopp 527e92
  	hFile = CreateFileW(wn,		/* file name */
Karsten Hopp 527e92
  		    GENERIC_READ,	/* access mode */
Karsten Hopp 527e92
! 		    0,			/* share mode */
Karsten Hopp 527e92
  		    NULL,		/* security descriptor */
Karsten Hopp 527e92
  		    OPEN_EXISTING,	/* creation disposition */
Karsten Hopp 527e92
! 		    0,			/* file attributes */
Karsten Hopp 527e92
  		    NULL);		/* handle to template file */
Karsten Hopp 527e92
  	if (hFile == INVALID_HANDLE_VALUE
Karsten Hopp 527e92
! 		&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 527e92
  	{
Karsten Hopp 527e92
  	    /* Retry with non-wide function (for Windows 98). */
Karsten Hopp 527e92
  	    vim_free(wn);
Karsten Hopp 527e92
--- 2645,2688 ----
Karsten Hopp 527e92
      int
Karsten Hopp 527e92
  mch_is_linked(char_u *fname)
Karsten Hopp 527e92
  {
Karsten Hopp 527e92
+     BY_HANDLE_FILE_INFORMATION info;
Karsten Hopp 527e92
+ 
Karsten Hopp 527e92
+     return win32_fileinfo(fname, &info) == FILEINFO_OK
Karsten Hopp 527e92
+ 						   && info.nNumberOfLinks > 1;
Karsten Hopp 527e92
+ }
Karsten Hopp 527e92
+ 
Karsten Hopp 527e92
+ /*
Karsten Hopp 527e92
+  * Get the by-handle-file-information for "fname".
Karsten Hopp 527e92
+  * Returns FILEINFO_OK when OK.
Karsten Hopp 527e92
+  * returns FILEINFO_ENC_FAIL when enc_to_utf16() failed.
Karsten Hopp 527e92
+  * Returns FILEINFO_READ_FAIL when CreateFile() failed.
Karsten Hopp 527e92
+  * Returns FILEINFO_INFO_FAIL when GetFileInformationByHandle() failed.
Karsten Hopp 527e92
+  */
Karsten Hopp 527e92
+     int
Karsten Hopp 527e92
+ win32_fileinfo(char_u *fname, BY_HANDLE_FILE_INFORMATION *info)
Karsten Hopp 527e92
+ {
Karsten Hopp 527e92
      HANDLE	hFile;
Karsten Hopp 527e92
!     int		res = FILEINFO_READ_FAIL;
Karsten Hopp 527e92
  #ifdef FEAT_MBYTE
Karsten Hopp 527e92
      WCHAR	*wn = NULL;
Karsten Hopp 527e92
  
Karsten Hopp 527e92
      if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
Karsten Hopp 527e92
+     {
Karsten Hopp 527e92
  	wn = enc_to_utf16(fname, NULL);
Karsten Hopp 527e92
+ 	if (wn == NULL)
Karsten Hopp 527e92
+ 	    res = FILEINFO_ENC_FAIL;
Karsten Hopp 527e92
+     }
Karsten Hopp 527e92
      if (wn != NULL)
Karsten Hopp 527e92
      {
Karsten Hopp 527e92
  	hFile = CreateFileW(wn,		/* file name */
Karsten Hopp 527e92
  		    GENERIC_READ,	/* access mode */
Karsten Hopp 527e92
! 		    FILE_SHARE_READ | FILE_SHARE_WRITE,	/* share mode */
Karsten Hopp 527e92
  		    NULL,		/* security descriptor */
Karsten Hopp 527e92
  		    OPEN_EXISTING,	/* creation disposition */
Karsten Hopp 527e92
! 		    FILE_FLAG_BACKUP_SEMANTICS,	/* file attributes */
Karsten Hopp 527e92
  		    NULL);		/* handle to template file */
Karsten Hopp 527e92
  	if (hFile == INVALID_HANDLE_VALUE
Karsten Hopp 527e92
! 			      && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 527e92
  	{
Karsten Hopp 527e92
  	    /* Retry with non-wide function (for Windows 98). */
Karsten Hopp 527e92
  	    vim_free(wn);
Karsten Hopp 527e92
***************
Karsten Hopp 527e92
*** 2674,2690 ****
Karsten Hopp 527e92
  #endif
Karsten Hopp 527e92
  	hFile = CreateFile(fname,	/* file name */
Karsten Hopp 527e92
  		    GENERIC_READ,	/* access mode */
Karsten Hopp 527e92
! 		    0,			/* share mode */
Karsten Hopp 527e92
  		    NULL,		/* security descriptor */
Karsten Hopp 527e92
  		    OPEN_EXISTING,	/* creation disposition */
Karsten Hopp 527e92
! 		    0,			/* file attributes */
Karsten Hopp 527e92
  		    NULL);		/* handle to template file */
Karsten Hopp 527e92
  
Karsten Hopp 527e92
      if (hFile != INVALID_HANDLE_VALUE)
Karsten Hopp 527e92
      {
Karsten Hopp 527e92
! 	if (GetFileInformationByHandle(hFile, &inf) != 0
Karsten Hopp 527e92
! 		&& inf.nNumberOfLinks > 1)
Karsten Hopp 527e92
! 	    res = 1;
Karsten Hopp 527e92
  	CloseHandle(hFile);
Karsten Hopp 527e92
      }
Karsten Hopp 527e92
  
Karsten Hopp 527e92
--- 2693,2710 ----
Karsten Hopp 527e92
  #endif
Karsten Hopp 527e92
  	hFile = CreateFile(fname,	/* file name */
Karsten Hopp 527e92
  		    GENERIC_READ,	/* access mode */
Karsten Hopp 527e92
! 		    FILE_SHARE_READ | FILE_SHARE_WRITE,	/* share mode */
Karsten Hopp 527e92
  		    NULL,		/* security descriptor */
Karsten Hopp 527e92
  		    OPEN_EXISTING,	/* creation disposition */
Karsten Hopp 527e92
! 		    FILE_FLAG_BACKUP_SEMANTICS,	/* file attributes */
Karsten Hopp 527e92
  		    NULL);		/* handle to template file */
Karsten Hopp 527e92
  
Karsten Hopp 527e92
      if (hFile != INVALID_HANDLE_VALUE)
Karsten Hopp 527e92
      {
Karsten Hopp 527e92
! 	if (GetFileInformationByHandle(hFile, info) != 0)
Karsten Hopp 527e92
! 	    res = FILEINFO_OK;
Karsten Hopp 527e92
! 	else
Karsten Hopp 527e92
! 	    res = FILEINFO_INFO_FAIL;
Karsten Hopp 527e92
  	CloseHandle(hFile);
Karsten Hopp 527e92
      }
Karsten Hopp 527e92
  
Karsten Hopp 527e92
*** ../vim-7.3.171/src/proto/os_win32.pro	2010-10-23 14:02:48.000000000 +0200
Karsten Hopp 527e92
--- src/proto/os_win32.pro	2011-05-05 16:17:42.000000000 +0200
Karsten Hopp 527e92
***************
Karsten Hopp 527e92
*** 21,26 ****
Karsten Hopp 527e92
--- 21,27 ----
Karsten Hopp 527e92
  void mch_hide __ARGS((char_u *name));
Karsten Hopp 527e92
  int mch_isdir __ARGS((char_u *name));
Karsten Hopp 527e92
  int mch_is_linked __ARGS((char_u *fname));
Karsten Hopp 527e92
+ int win32_fileinfo __ARGS((char_u *name, BY_HANDLE_FILE_INFORMATION *lpFileInfo));
Karsten Hopp 527e92
  int mch_writable __ARGS((char_u *name));
Karsten Hopp 527e92
  int mch_can_exe __ARGS((char_u *name));
Karsten Hopp 527e92
  int mch_nodetype __ARGS((char_u *name));
Karsten Hopp 527e92
*** ../vim-7.3.171/src/vim.h	2011-04-11 21:35:03.000000000 +0200
Karsten Hopp 527e92
--- src/vim.h	2011-05-05 16:16:57.000000000 +0200
Karsten Hopp 527e92
***************
Karsten Hopp 527e92
*** 2217,2220 ****
Karsten Hopp 527e92
--- 2217,2226 ----
Karsten Hopp 527e92
  #define KEYLEN_PART_MAP -2	/* keylen value for incomplete mapping */
Karsten Hopp 527e92
  #define KEYLEN_REMOVED  9999	/* keylen value for removed sequence */
Karsten Hopp 527e92
  
Karsten Hopp 527e92
+ /* Return values from win32_fileinfo(). */
Karsten Hopp 527e92
+ #define FILEINFO_OK	     0
Karsten Hopp 527e92
+ #define FILEINFO_ENC_FAIL    1	/* enc_to_utf16() failed */
Karsten Hopp 527e92
+ #define FILEINFO_READ_FAIL   2	/* CreateFile() failed */
Karsten Hopp 527e92
+ #define FILEINFO_INFO_FAIL   3	/* GetFileInformationByHandle() failed */
Karsten Hopp 527e92
+ 
Karsten Hopp 527e92
  #endif /* VIM__H */
Karsten Hopp 527e92
*** ../vim-7.3.171/src/version.c	2011-05-05 14:26:37.000000000 +0200
Karsten Hopp 527e92
--- src/version.c	2011-05-05 16:39:35.000000000 +0200
Karsten Hopp 527e92
***************
Karsten Hopp 527e92
*** 716,717 ****
Karsten Hopp 527e92
--- 716,719 ----
Karsten Hopp 527e92
  {   /* Add new patch number below this line */
Karsten Hopp 527e92
+ /**/
Karsten Hopp 527e92
+     172,
Karsten Hopp 527e92
  /**/
Karsten Hopp 527e92
Karsten Hopp 527e92
-- 
Karsten Hopp 527e92
Q: What is a patch 22?
Karsten Hopp 527e92
A: A patch you need to include to make it possible to include patches.
Karsten Hopp 527e92
Karsten Hopp 527e92
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 527e92
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 527e92
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 527e92
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///