]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/chattr-util.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
9 #include "chattr-util.h"
13 int chattr_fd(int fd
, unsigned value
, unsigned mask
, unsigned *previous
) {
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
))
31 if (mask
== 0 && !previous
)
34 if (ioctl(fd
, FS_IOC_GETFLAGS
, &old_attr
) < 0)
37 new_attr
= (old_attr
& ~mask
) | (value
& mask
);
38 if (new_attr
== old_attr
) {
44 if (ioctl(fd
, FS_IOC_SETFLAGS
, &new_attr
) < 0)
53 int chattr_path(const char *p
, unsigned value
, unsigned mask
, unsigned *previous
) {
54 _cleanup_close_
int fd
= -1;
61 fd
= open(p
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
);
65 return chattr_fd(fd
, value
, mask
, previous
);
68 int read_attr_fd(int fd
, unsigned *ret
) {
73 if (fstat(fd
, &st
) < 0)
76 if (!S_ISDIR(st
.st_mode
) && !S_ISREG(st
.st_mode
))
79 if (ioctl(fd
, FS_IOC_GETFLAGS
, ret
) < 0)
85 int read_attr_path(const char *p
, unsigned *ret
) {
86 _cleanup_close_
int fd
= -1;
91 fd
= open(p
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
);
95 return read_attr_fd(fd
, ret
);