summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/util.c33
-rw-r--r--src/shared/util.h3
2 files changed, 36 insertions, 0 deletions
diff --git a/src/shared/util.c b/src/shared/util.c
index 6293e967c8..88fd78ec8d 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -62,6 +62,7 @@
#include <sys/xattr.h>
#include <libgen.h>
#include <sys/statvfs.h>
+#include <linux/fs.h>
#undef basename
#ifdef HAVE_SYS_AUXV_H
@@ -7740,3 +7741,35 @@ int same_fd(int a, int b) {
return fa == fb;
}
+
+int chattr_fd(int fd, bool b, int mask) {
+ int old_attr, new_attr;
+
+ assert(fd >= 0);
+
+ if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
+ return -errno;
+
+ if (b)
+ new_attr = old_attr | mask;
+ else
+ new_attr = old_attr & ~mask;
+
+ if (new_attr == old_attr)
+ return 0;
+
+ if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
+ return -errno;
+
+ return 0;
+}
+
+int chattr_path(const char *p, bool b, int mask) {
+ _cleanup_close_ int fd = -1;
+
+ fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+ if (fd < 0)
+ return -errno;
+
+ return chattr_fd(fd, b, mask);
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index 4b7e12e628..31103e957f 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -1071,3 +1071,6 @@ int path_getcrtime(const char *p, usec_t *usec);
int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags);
int same_fd(int a, int b);
+
+int chattr_fd(int fd, bool b, int mask);
+int chattr_path(const char *p, bool b, int mask);