summaryrefslogtreecommitdiff
path: root/src/basic/stat-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2022-02-14 17:18:32 +0100
committerLennart Poettering <lennart@poettering.net>2022-02-14 17:27:09 +0100
commit38db6211b5aa6e2fb65883ae3353914e82f5bef1 (patch)
tree7d02b343b8d7d4ea05d78a0d3c16f00e963fd3a5 /src/basic/stat-util.c
parentd74da762a3b1edbb7935c3b3a229db601f734125 (diff)
downloadsystemd-38db6211b5aa6e2fb65883ae3353914e82f5bef1.tar.gz
stat-util: add helper stat_inode_same() for comparing stat's st_dev/st_ino in one
We do this all over the place, hence let's add a simple helper that does this and particularly carefully and thoroughly.
Diffstat (limited to 'src/basic/stat-util.c')
-rw-r--r--src/basic/stat-util.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
index c2269844f8..298f46440f 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -417,6 +417,18 @@ int proc_mounted(void) {
return r;
}
+bool stat_inode_same(const struct stat *a, const struct stat *b) {
+
+ /* Returns if the specified stat structure references the same (though possibly modified) inode. Does
+ * a thorough check, comparing inode nr, backing device and if the inode is still of the same type. */
+
+ 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_dev == b->st_dev &&
+ a->st_ino == b->st_ino;
+}
+
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
@@ -428,14 +440,10 @@ bool stat_inode_unmodified(const struct stat *a, const struct stat *b) {
* 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 */
+ return stat_inode_same(a, b) &&
a->st_mtim.tv_sec == b->st_mtim.tv_sec &&
a->st_mtim.tv_nsec == b->st_mtim.tv_nsec &&
(!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 */
}