chiark / gitweb /
btrfs-util: introduce btrfs_is_filesystem() and make use of it where appropriate
[elogind.git] / src / shared / util.c
index 03edafb952c3b9969a9fab4bc7e492fd2784fd61..f9094cc7e51666be217005953e3109b2b852ceb6 100644 (file)
@@ -1700,7 +1700,7 @@ int parse_size(const char *t, off_t base, off_t *size) {
          * sometimes SI decimal suffixes. This function can parse
          * both. Which one is the right way depends on the
          * context. Wikipedia suggests that SI is customary for
-         * hardrware metrics and network speeds, while IEC is
+         * hardware metrics and network speeds, while IEC is
          * customary for most data sizes used by software and volatile
          * (RAM) memory. Hence be careful which one you pick!
          *
@@ -5923,9 +5923,22 @@ int fd_setcrtime(int fd, usec_t usec) {
 
 int chattr_fd(int fd, unsigned value, unsigned mask) {
         unsigned old_attr, new_attr;
+        struct stat st;
 
         assert(fd >= 0);
 
+        if (fstat(fd, &st) < 0)
+                return -errno;
+
+        /* Explicitly check whether this is a regular file or
+         * directory. If it is anything else (such as a device node or
+         * fifo), then the ioctl will not hit the file systems but
+         * possibly drivers, where the ioctl might have different
+         * effects. Notably, DRM is using the same ioctl() number. */
+
+        if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
+                return -ENOTTY;
+
         if (mask == 0)
                 return 0;
 
@@ -5958,8 +5971,16 @@ int chattr_path(const char *p, unsigned value, unsigned mask) {
 }
 
 int read_attr_fd(int fd, unsigned *ret) {
+        struct stat st;
+
         assert(fd >= 0);
 
+        if (fstat(fd, &st) < 0)
+                return -errno;
+
+        if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
+                return -ENOTTY;
+
         if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
                 return -errno;