Karsten Hopp 4dcdfe
To: vim-dev@vim.org
Karsten Hopp 4dcdfe
Subject: Patch 7.2.077
Karsten Hopp 4dcdfe
Fcc: outbox
Karsten Hopp 4dcdfe
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 4dcdfe
Mime-Version: 1.0
Karsten Hopp 4dcdfe
Content-Type: text/plain; charset=ISO-8859-1
Karsten Hopp 4dcdfe
Content-Transfer-Encoding: 8bit
Karsten Hopp 4dcdfe
------------
Karsten Hopp 4dcdfe
Karsten Hopp 4dcdfe
Patch 7.2.077 (after 7.2.076)
Karsten Hopp 4dcdfe
Problem:    rename(from, to) doesn't work if "from" and "to" differ only in
Karsten Hopp 4dcdfe
	    case on a system that ignores case in file names.
Karsten Hopp 4dcdfe
Solution:   Go through another file name.
Karsten Hopp 4dcdfe
Files:	    src/fileio.c
Karsten Hopp 4dcdfe
Karsten Hopp 4dcdfe
Karsten Hopp 4dcdfe
*** ../vim-7.2.076/src/fileio.c	Tue Dec 30 16:15:16 2008
Karsten Hopp 4dcdfe
--- src/fileio.c	Wed Dec 31 14:59:59 2008
Karsten Hopp 4dcdfe
***************
Karsten Hopp 4dcdfe
*** 6106,6117 ****
Karsten Hopp 4dcdfe
  #ifdef HAVE_ACL
Karsten Hopp 4dcdfe
      vim_acl_T	acl;		/* ACL from original file */
Karsten Hopp 4dcdfe
  #endif
Karsten Hopp 4dcdfe
  
Karsten Hopp 4dcdfe
      /*
Karsten Hopp 4dcdfe
!      * When the names are identical, there is nothing to do.
Karsten Hopp 4dcdfe
       */
Karsten Hopp 4dcdfe
      if (fnamecmp(from, to) == 0)
Karsten Hopp 4dcdfe
! 	return 0;
Karsten Hopp 4dcdfe
  
Karsten Hopp 4dcdfe
      /*
Karsten Hopp 4dcdfe
       * Fail if the "from" file doesn't exist.  Avoids that "to" is deleted.
Karsten Hopp 4dcdfe
--- 6106,6129 ----
Karsten Hopp 4dcdfe
  #ifdef HAVE_ACL
Karsten Hopp 4dcdfe
      vim_acl_T	acl;		/* ACL from original file */
Karsten Hopp 4dcdfe
  #endif
Karsten Hopp 4dcdfe
+ #if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
Karsten Hopp 4dcdfe
+     int		use_tmp_file = FALSE;
Karsten Hopp 4dcdfe
+ #endif
Karsten Hopp 4dcdfe
  
Karsten Hopp 4dcdfe
      /*
Karsten Hopp 4dcdfe
!      * When the names are identical, there is nothing to do.  When they refer
Karsten Hopp 4dcdfe
!      * to the same file (ignoring case and slash/backslash differences) but
Karsten Hopp 4dcdfe
!      * the file name differs we need to go through a temp file.
Karsten Hopp 4dcdfe
       */
Karsten Hopp 4dcdfe
      if (fnamecmp(from, to) == 0)
Karsten Hopp 4dcdfe
!     {
Karsten Hopp 4dcdfe
! #ifdef CASE_INSENSITIVE_FILENAME
Karsten Hopp 4dcdfe
! 	if (STRCMP(gettail(from), gettail(to)) != 0)
Karsten Hopp 4dcdfe
! 	    use_tmp_file = TRUE;
Karsten Hopp 4dcdfe
! 	else
Karsten Hopp 4dcdfe
! #endif
Karsten Hopp 4dcdfe
! 	    return 0;
Karsten Hopp 4dcdfe
!     }
Karsten Hopp 4dcdfe
  
Karsten Hopp 4dcdfe
      /*
Karsten Hopp 4dcdfe
       * Fail if the "from" file doesn't exist.  Avoids that "to" is deleted.
Karsten Hopp 4dcdfe
***************
Karsten Hopp 4dcdfe
*** 6122,6128 ****
Karsten Hopp 4dcdfe
  #ifdef UNIX
Karsten Hopp 4dcdfe
      {
Karsten Hopp 4dcdfe
  	struct stat	st_to;
Karsten Hopp 4dcdfe
- 	char		tempname[MAXPATHL + 1];
Karsten Hopp 4dcdfe
  
Karsten Hopp 4dcdfe
  	/* It's possible for the source and destination to be the same file.
Karsten Hopp 4dcdfe
  	 * This happens when "from" and "to" differ in case and are on a FAT32
Karsten Hopp 4dcdfe
--- 6134,6139 ----
Karsten Hopp 4dcdfe
***************
Karsten Hopp 4dcdfe
*** 6130,6162 ****
Karsten Hopp 4dcdfe
  	if (mch_stat((char *)to, &st_to) >= 0
Karsten Hopp 4dcdfe
  		&& st.st_dev == st_to.st_dev
Karsten Hopp 4dcdfe
  		&& st.st_ino == st_to.st_ino)
Karsten Hopp 4dcdfe
  	{
Karsten Hopp 4dcdfe
! 	    /* Find a name that doesn't exist and is in the same directory.
Karsten Hopp 4dcdfe
! 	     * Move "from" to "tempname" and then to "to". */
Karsten Hopp 4dcdfe
! 	    if (STRLEN(from) >= MAXPATHL - 5)
Karsten Hopp 4dcdfe
! 		return -1;
Karsten Hopp 4dcdfe
! 	    STRCPY(tempname, from);
Karsten Hopp 4dcdfe
! 	    for (n = 123; n < 99999; ++n)
Karsten Hopp 4dcdfe
  	    {
Karsten Hopp 4dcdfe
! 		sprintf(gettail(tempname), "%d", n);
Karsten Hopp 4dcdfe
! 		if (mch_stat(tempname, &st_to) < 0)
Karsten Hopp 4dcdfe
  		{
Karsten Hopp 4dcdfe
! 		    if (mch_rename((char *)from, tempname) == 0)
Karsten Hopp 4dcdfe
! 		    {
Karsten Hopp 4dcdfe
! 			if (mch_rename(tempname, (char *)to) == 0)
Karsten Hopp 4dcdfe
! 			    return 0;
Karsten Hopp 4dcdfe
! 			/* Strange, the second step failed.  Try moving the
Karsten Hopp 4dcdfe
! 			 * file back and return failure. */
Karsten Hopp 4dcdfe
! 			mch_rename(tempname, (char *)from);
Karsten Hopp 4dcdfe
! 			return -1;
Karsten Hopp 4dcdfe
! 		    }
Karsten Hopp 4dcdfe
! 		    /* If it fails for one temp name it will most likely fail
Karsten Hopp 4dcdfe
! 		     * for any temp name, give up. */
Karsten Hopp 4dcdfe
  		    return -1;
Karsten Hopp 4dcdfe
  		}
Karsten Hopp 4dcdfe
  	    }
Karsten Hopp 4dcdfe
- 	    return -1;
Karsten Hopp 4dcdfe
  	}
Karsten Hopp 4dcdfe
      }
Karsten Hopp 4dcdfe
  #endif
Karsten Hopp 4dcdfe
  
Karsten Hopp 4dcdfe
--- 6141,6182 ----
Karsten Hopp 4dcdfe
  	if (mch_stat((char *)to, &st_to) >= 0
Karsten Hopp 4dcdfe
  		&& st.st_dev == st_to.st_dev
Karsten Hopp 4dcdfe
  		&& st.st_ino == st_to.st_ino)
Karsten Hopp 4dcdfe
+ 	    use_tmp_file = TRUE;
Karsten Hopp 4dcdfe
+     }
Karsten Hopp 4dcdfe
+ #endif
Karsten Hopp 4dcdfe
+ 
Karsten Hopp 4dcdfe
+ #if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
Karsten Hopp 4dcdfe
+     if (use_tmp_file)
Karsten Hopp 4dcdfe
+     {
Karsten Hopp 4dcdfe
+ 	char	tempname[MAXPATHL + 1];
Karsten Hopp 4dcdfe
+ 
Karsten Hopp 4dcdfe
+ 	/*
Karsten Hopp 4dcdfe
+ 	 * Find a name that doesn't exist and is in the same directory.
Karsten Hopp 4dcdfe
+ 	 * Rename "from" to "tempname" and then rename "tempname" to "to".
Karsten Hopp 4dcdfe
+ 	 */
Karsten Hopp 4dcdfe
+ 	if (STRLEN(from) >= MAXPATHL - 5)
Karsten Hopp 4dcdfe
+ 	    return -1;
Karsten Hopp 4dcdfe
+ 	STRCPY(tempname, from);
Karsten Hopp 4dcdfe
+ 	for (n = 123; n < 99999; ++n)
Karsten Hopp 4dcdfe
  	{
Karsten Hopp 4dcdfe
! 	    sprintf((char *)gettail((char_u *)tempname), "%d", n);
Karsten Hopp 4dcdfe
! 	    if (mch_stat(tempname, &st) < 0)
Karsten Hopp 4dcdfe
  	    {
Karsten Hopp 4dcdfe
! 		if (mch_rename((char *)from, tempname) == 0)
Karsten Hopp 4dcdfe
  		{
Karsten Hopp 4dcdfe
! 		    if (mch_rename(tempname, (char *)to) == 0)
Karsten Hopp 4dcdfe
! 			return 0;
Karsten Hopp 4dcdfe
! 		    /* Strange, the second step failed.  Try moving the
Karsten Hopp 4dcdfe
! 		     * file back and return failure. */
Karsten Hopp 4dcdfe
! 		    mch_rename(tempname, (char *)from);
Karsten Hopp 4dcdfe
  		    return -1;
Karsten Hopp 4dcdfe
  		}
Karsten Hopp 4dcdfe
+ 		/* If it fails for one temp name it will most likely fail
Karsten Hopp 4dcdfe
+ 		 * for any temp name, give up. */
Karsten Hopp 4dcdfe
+ 		return -1;
Karsten Hopp 4dcdfe
  	    }
Karsten Hopp 4dcdfe
  	}
Karsten Hopp 4dcdfe
+ 	return -1;
Karsten Hopp 4dcdfe
      }
Karsten Hopp 4dcdfe
  #endif
Karsten Hopp 4dcdfe
  
Karsten Hopp 4dcdfe
*** ../vim-7.2.076/src/version.c	Tue Dec 30 16:15:16 2008
Karsten Hopp 4dcdfe
--- src/version.c	Wed Dec 31 16:19:29 2008
Karsten Hopp 4dcdfe
***************
Karsten Hopp 4dcdfe
*** 678,679 ****
Karsten Hopp 4dcdfe
--- 678,681 ----
Karsten Hopp 4dcdfe
  {   /* Add new patch number below this line */
Karsten Hopp 4dcdfe
+ /**/
Karsten Hopp 4dcdfe
+     77,
Karsten Hopp 4dcdfe
  /**/
Karsten Hopp 4dcdfe
Karsten Hopp 4dcdfe
-- 
Karsten Hopp 4dcdfe
We apologise again for the fault in the subtitles.  Those responsible for
Karsten Hopp 4dcdfe
sacking the people who have just been sacked have been sacked.
Karsten Hopp 4dcdfe
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
Karsten Hopp 4dcdfe
Karsten Hopp 4dcdfe
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 4dcdfe
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 4dcdfe
\\\        download, build and distribute -- http://www.A-A-P.org        ///
Karsten Hopp 4dcdfe
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///