LCOV - code coverage report
Current view: top level - basic - chattr-util.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 19 46 41.3 %
Date: 2019-08-22 15:41:25 Functions: 2 4 50.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <errno.h>
       4             : #include <fcntl.h>
       5             : #include <sys/ioctl.h>
       6             : #include <sys/stat.h>
       7             : #include <linux/fs.h>
       8             : 
       9             : #include "chattr-util.h"
      10             : #include "fd-util.h"
      11             : #include "macro.h"
      12             : 
      13          18 : int chattr_fd(int fd, unsigned value, unsigned mask, unsigned *previous) {
      14             :         unsigned old_attr, new_attr;
      15             :         struct stat st;
      16             : 
      17          18 :         assert(fd >= 0);
      18             : 
      19          18 :         if (fstat(fd, &st) < 0)
      20           0 :                 return -errno;
      21             : 
      22             :         /* Explicitly check whether this is a regular file or
      23             :          * directory. If it is anything else (such as a device node or
      24             :          * fifo), then the ioctl will not hit the file systems but
      25             :          * possibly drivers, where the ioctl might have different
      26             :          * effects. Notably, DRM is using the same ioctl() number. */
      27             : 
      28          18 :         if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
      29           0 :                 return -ENOTTY;
      30             : 
      31          18 :         if (mask == 0 && !previous)
      32           0 :                 return 0;
      33             : 
      34          18 :         if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
      35           0 :                 return -errno;
      36             : 
      37          18 :         new_attr = (old_attr & ~mask) | (value & mask);
      38          18 :         if (new_attr == old_attr) {
      39           2 :                 if (previous)
      40           0 :                         *previous = old_attr;
      41           2 :                 return 0;
      42             :         }
      43             : 
      44          16 :         if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
      45          16 :                 return -errno;
      46             : 
      47           0 :         if (previous)
      48           0 :                 *previous = old_attr;
      49             : 
      50           0 :         return 1;
      51             : }
      52             : 
      53          16 : int chattr_path(const char *p, unsigned value, unsigned mask, unsigned *previous) {
      54          16 :         _cleanup_close_ int fd = -1;
      55             : 
      56          16 :         assert(p);
      57             : 
      58          16 :         if (mask == 0)
      59           0 :                 return 0;
      60             : 
      61          16 :         fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
      62          16 :         if (fd < 0)
      63           0 :                 return -errno;
      64             : 
      65          16 :         return chattr_fd(fd, value, mask, previous);
      66             : }
      67             : 
      68           0 : int read_attr_fd(int fd, unsigned *ret) {
      69             :         struct stat st;
      70             : 
      71           0 :         assert(fd >= 0);
      72             : 
      73           0 :         if (fstat(fd, &st) < 0)
      74           0 :                 return -errno;
      75             : 
      76           0 :         if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
      77           0 :                 return -ENOTTY;
      78             : 
      79           0 :         if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
      80           0 :                 return -errno;
      81             : 
      82           0 :         return 0;
      83             : }
      84             : 
      85           0 : int read_attr_path(const char *p, unsigned *ret) {
      86           0 :         _cleanup_close_ int fd = -1;
      87             : 
      88           0 :         assert(p);
      89           0 :         assert(ret);
      90             : 
      91           0 :         fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
      92           0 :         if (fd < 0)
      93           0 :                 return -errno;
      94             : 
      95           0 :         return read_attr_fd(fd, ret);
      96             : }

Generated by: LCOV version 1.14