From 7f88fcbdf3e80fe22dde586d7770b1529ea29d26 Mon Sep 17 00:00:00 2001 From: Allan Odgaard Date: Wed, 15 May 2013 16:14:07 +0700 Subject: [PATCH] Fix problem with opening multiple empty files on FAT file systems The problem is that empty files on a FAT file system all have the same inode so TextMate would consider them to be links of each other and only show the last one opened. Fixes #979. --- Frameworks/io/src/path.cc | 23 ++++++++++++++++++++--- Frameworks/io/src/path.h | 1 + 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Frameworks/io/src/path.cc b/Frameworks/io/src/path.cc index c021c09d..2c330000 100644 --- a/Frameworks/io/src/path.cc +++ b/Frameworks/io/src/path.cc @@ -397,6 +397,18 @@ namespace path } } + bool identifier_t::can_trust_inode () const + { + if(exists && inode == 999999999) // Zero-length files on FAT file systems share this magic value + { + struct statfs sfsb; + if(statfs(path.c_str(), &sfsb) == 0) + return strcasecmp(sfsb.f_fstypename, "msdos") == 0 && strcasecmp(sfsb.f_fstypename, "exfat") == 0; + perror("statfs"); + } + return true; + } + bool identifier_t::operator< (identifier_t const& rhs) const { if(path == rhs.path) @@ -405,15 +417,20 @@ namespace path if(exists == rhs.exists) { if(exists) - return device == rhs.device ? inode < rhs.inode : device < rhs.device; - else return path < rhs.path; + { + if(device != rhs.device) + return device < rhs.device; + else if(can_trust_inode() && rhs.can_trust_inode()) + return inode < rhs.inode; + } + return path < rhs.path; } return !exists && rhs.exists; } bool identifier_t::operator== (identifier_t const& rhs) const { - return path == rhs.path || (exists && rhs.exists && device == rhs.device && inode == rhs.inode); + return path == rhs.path || (exists && rhs.exists && device == rhs.device && inode == rhs.inode && can_trust_inode()); } bool identifier_t::operator!= (identifier_t const& rhs) const diff --git a/Frameworks/io/src/path.h b/Frameworks/io/src/path.h index b0db0ecb..328f893e 100644 --- a/Frameworks/io/src/path.h +++ b/Frameworks/io/src/path.h @@ -42,6 +42,7 @@ namespace path bool operator!= (identifier_t const& rhs) const; explicit operator bool () const { return exists || path != NULL_STR; } private: + bool can_trust_inode () const; bool exists; dev_t device; ino_t inode;