1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-10-26 17:25:34 +03:00

stat-util: add stat_inode_unmodified() helper that checks if an inode was modified

This commit is contained in:
Lennart Poettering 2020-04-28 18:16:25 +02:00
parent 5a0173147b
commit fee5c52ac2
2 changed files with 23 additions and 0 deletions

View File

@ -388,3 +388,24 @@ int proc_mounted(void) {
return r;
}
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 */
}

View File

@ -89,3 +89,5 @@ 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);
int proc_mounted(void);
bool stat_inode_unmodified(const struct stat *a, const struct stat *b);