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;