LCOV - code coverage report
Current view: top level - basic - chattr-util.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 19 46 41.3 %
Date: 2019-08-23 13:36:53 Functions: 2 4 50.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 14 44 31.8 %

           Branch data     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                 :         72 : int chattr_fd(int fd, unsigned value, unsigned mask, unsigned *previous) {
      14                 :            :         unsigned old_attr, new_attr;
      15                 :            :         struct stat st;
      16                 :            : 
      17         [ -  + ]:         72 :         assert(fd >= 0);
      18                 :            : 
      19         [ -  + ]:         72 :         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   [ +  +  -  + ]:         72 :         if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
      29                 :          0 :                 return -ENOTTY;
      30                 :            : 
      31   [ -  +  #  # ]:         72 :         if (mask == 0 && !previous)
      32                 :          0 :                 return 0;
      33                 :            : 
      34         [ -  + ]:         72 :         if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
      35                 :          0 :                 return -errno;
      36                 :            : 
      37                 :         72 :         new_attr = (old_attr & ~mask) | (value & mask);
      38         [ +  + ]:         72 :         if (new_attr == old_attr) {
      39         [ -  + ]:          8 :                 if (previous)
      40                 :          0 :                         *previous = old_attr;
      41                 :          8 :                 return 0;
      42                 :            :         }
      43                 :            : 
      44         [ +  - ]:         64 :         if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
      45                 :         64 :                 return -errno;
      46                 :            : 
      47         [ #  # ]:          0 :         if (previous)
      48                 :          0 :                 *previous = old_attr;
      49                 :            : 
      50                 :          0 :         return 1;
      51                 :            : }
      52                 :            : 
      53                 :         64 : int chattr_path(const char *p, unsigned value, unsigned mask, unsigned *previous) {
      54                 :         64 :         _cleanup_close_ int fd = -1;
      55                 :            : 
      56         [ -  + ]:         64 :         assert(p);
      57                 :            : 
      58         [ -  + ]:         64 :         if (mask == 0)
      59                 :          0 :                 return 0;
      60                 :            : 
      61                 :         64 :         fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
      62         [ -  + ]:         64 :         if (fd < 0)
      63                 :          0 :                 return -errno;
      64                 :            : 
      65                 :         64 :         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