aboutsummaryrefslogtreecommitdiffhomepage
path: root/wutil.h
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2014-04-28 15:14:33 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2014-04-28 15:14:33 -0700
commit91aadab3dda85cf51b7c6d89b7e70f32bd437e5b (patch)
tree83795d0565e567f04b61ef4493c079c25efa4686 /wutil.h
parentc3425bc55f9b4c627519e49d8c29a7d4abde2019 (diff)
Enhance file_id_t to have richer information, to guard against inode
recycling on Linux filesystems
Diffstat (limited to 'wutil.h')
-rw-r--r--wutil.h20
1 files changed, 18 insertions, 2 deletions
diff --git a/wutil.h b/wutil.h
index 1b2f6f2b..3355ab14 100644
--- a/wutil.h
+++ b/wutil.h
@@ -158,8 +158,24 @@ int wrename(const wcstring &oldName, const wcstring &newName);
/** Like wcstol(), but fails on a value outside the range of an int */
int fish_wcstoi(const wchar_t *str, wchar_t ** endptr, int base);
-/** Class for representing a file's inode. We use this to detect and avoid symlink loops, among other things. */
-typedef std::pair<dev_t, ino_t> file_id_t;
+/** Class for representing a file's inode. We use this to detect and avoid symlink loops, among other things. While an inode / dev pair is sufficient to distinguish co-existing files, Linux seems to aggressively re-use inodes, so it cannot determine if a file has been deleted (ABA problem). Therefore we include richer information. */
+struct file_id_t
+{
+ dev_t device;
+ ino_t inode;
+ uint64_t size;
+ time_t change_seconds;
+ long change_nanoseconds;
+ uint32_t generation;
+
+ bool operator==(const file_id_t &rhs) const;
+ bool operator!=(const file_id_t &rhs) const;
+
+ // Used to permit these as keys in std::map
+ bool operator<(const file_id_t &rhs) const;
+
+ static file_id_t file_id_from_stat(const struct stat *buf);
+};
file_id_t file_id_for_fd(int fd);
file_id_t file_id_for_path(const wcstring &path);