54 lines
2.5 KiB
Diff
54 lines
2.5 KiB
Diff
From fee5c52ac260d021466c1062499f0ebd5241db5f Mon Sep 17 00:00:00 2001
|
|
From: Lennart Poettering <lennart@poettering.net>
|
|
Date: Tue, 28 Apr 2020 18:16:25 +0200
|
|
Subject: [PATCH] stat-util: add stat_inode_unmodified() helper that checks if
|
|
an inode was modified
|
|
|
|
---
|
|
src/basic/stat-util.c | 21 +++++++++++++++++++++
|
|
src/basic/stat-util.h | 2 ++
|
|
2 files changed, 23 insertions(+)
|
|
|
|
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
|
|
index 2cd722c..4595ba7 100644
|
|
--- a/src/basic/stat-util.c
|
|
+++ b/src/basic/stat-util.c
|
|
@@ -379,3 +379,24 @@ int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret
|
|
|
|
return 0;
|
|
}
|
|
+
|
|
+bool stat_inode_unmodified(const struct stat *a, const struct stat *b) {
|
|
+
|
|
+ /* Returns if the specified stat structures reference the same, unmodified inode. This check tries to
|
|
+ * be reasonably careful when detecting changes: we check both inode and mtime, to cater for file
|
|
+ * systems where mtimes are fixed to 0 (think: ostree/nixos type installations). We also check file
|
|
+ * size, backing device, inode type and if this refers to a device not the major/minor.
|
|
+ *
|
|
+ * Note that we don't care if file attributes such as ownership or access mode change, this here is
|
|
+ * about contents of the file. The purpose here is to detect file contents changes, and nothing
|
|
+ * else. */
|
|
+
|
|
+ return a && b &&
|
|
+ (a->st_mode & S_IFMT) != 0 && /* We use the check for .st_mode if the structure was ever initialized */
|
|
+ ((a->st_mode ^ b->st_mode) & S_IFMT) == 0 && /* same inode type */
|
|
+ a->st_mtime == b->st_mtime &&
|
|
+ (!S_ISREG(a->st_mode) || a->st_size == b->st_size) && /* if regular file, compare file size */
|
|
+ a->st_dev == b->st_dev &&
|
|
+ a->st_ino == b->st_ino &&
|
|
+ (!(S_ISCHR(a->st_mode) || S_ISBLK(a->st_mode)) || a->st_rdev == b->st_rdev); /* if device node, also compare major/minor, because we can */
|
|
+}
|
|
diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h
|
|
index 7824af3..3665059 100644
|
|
--- a/src/basic/stat-util.h
|
|
+++ b/src/basic/stat-util.h
|
|
@@ -87,3 +87,5 @@ int fd_verify_directory(int fd);
|
|
int device_path_make_major_minor(mode_t mode, dev_t devno, char **ret);
|
|
int device_path_make_canonical(mode_t mode, dev_t devno, char **ret);
|
|
int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret_devno);
|
|
+
|
|
+bool stat_inode_unmodified(const struct stat *a, const struct stat *b);
|
|
--
|
|
2.23.0
|
|
|