]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/chattr-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
9 #include "chattr-util.h"
13 int chattr_fd(int fd
, unsigned value
, unsigned mask
) {
14 unsigned old_attr
, new_attr
;
19 if (fstat(fd
, &st
) < 0)
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. */
28 if (!S_ISDIR(st
.st_mode
) && !S_ISREG(st
.st_mode
))
34 if (ioctl(fd
, FS_IOC_GETFLAGS
, &old_attr
) < 0)
37 new_attr
= (old_attr
& ~mask
) | (value
& mask
);
38 if (new_attr
== old_attr
)
41 if (ioctl(fd
, FS_IOC_SETFLAGS
, &new_attr
) < 0)
47 int chattr_path(const char *p
, unsigned value
, unsigned mask
) {
48 _cleanup_close_
int fd
= -1;
55 fd
= open(p
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
);
59 return chattr_fd(fd
, value
, mask
);
62 int read_attr_fd(int fd
, unsigned *ret
) {
67 if (fstat(fd
, &st
) < 0)
70 if (!S_ISDIR(st
.st_mode
) && !S_ISREG(st
.st_mode
))
73 if (ioctl(fd
, FS_IOC_GETFLAGS
, ret
) < 0)
79 int read_attr_path(const char *p
, unsigned *ret
) {
80 _cleanup_close_
int fd
= -1;
85 fd
= open(p
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
);
89 return read_attr_fd(fd
, ret
);