chiark / gitweb /
util: make it easy to initialize the crtime from the current time in fd_setcrtime()
[elogind.git] / src / shared / util.c
index 6293e967c8fb4c7c929a14a3578be04efcfe39c6..7d753e448a4f5da69b8d86045d90b6388a85a921 100644 (file)
@@ -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
@@ -7669,6 +7670,9 @@ int fd_setcrtime(int fd, usec_t usec) {
 
         assert(fd >= 0);
 
+        if (usec <= 0)
+                usec = now(CLOCK_REALTIME);
+
         le = htole64((uint64_t) usec);
         if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
                 return -errno;
@@ -7740,3 +7744,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);
+}