From: Nguyen Thai Ngoc Duy Date: Fri, 14 Jan 2011 14:17:27 GMT Subject: Re: [PATCH] handle rename of case only, for windows Message-ID: In-Reply-To: <1295012644.7883.1415296115@webmail.messagingengine.com> On Fri, Jan 14, 2011 at 8:44 PM, Tim Abell wrote: >                else if (lstat(dst, &st) == 0) { > -                       bad = "destination exists"; > -                       if (force) { > -                               /* > -                                * only files can overwrite each other: > -                                * check both source and destination > -                                */ > -                               if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) { > -                                       warning("%s; will overwrite!", bad); > -                                       bad = NULL; > -                               } else > -                                       bad = "Cannot overwrite"; > +                       /* If we are on a case insensitive files= system (windows) http://is.gd/kyxgg > +                        * and we are only changing the case of the file then lstat for the > +                        * destination will return != 0 because it sees the source file. > +                        * To prevent this causing failure, lstat is used to get the inode of the src > +                        * and see if it's actually the same file. > +                        */ > +                       lstat(src, &src_st); //get file serial number (inode) for source > +                       #warning("src inode: %s, dst inode: %s", src_st.st_ino, st.st_ino); > +                       if (src_st.st_ino != st.st_ino) { > +                               bad = "destination exists"; > +                               if (force) { > +                                       /* > +                                        * only files can overwrite each other: > +                                        * check both source and destination > +                                        */ > +                                       if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) { > +                                               warning("%s; will overwrite!", bad); > +                                               bad = NULL; > +                                       } else > +                                               bad = "Cannot overwrite"; > +                               } >                        } >                } else if (string_list_has_string(&src_for_dst, dst)) >                        bad = "multiple sources for the same target"; I wonder if we can make lstat_case() that would only return 0 if it matches exactly the filename, even on FAT. FindFirstFile/FindNextFile should return true file name, I think. If not, we can make lstat_case() take two paths (src and dst) and move all inode comparison code in there. Much cleaner. -- Duy