]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/xattr-util.c
2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include <sys/xattr.h>
28 #include "alloc-util.h"
31 #include "sparse-endian.h"
32 #include "stdio-util.h"
33 #include "time-util.h"
34 #include "xattr-util.h"
36 int getxattr_malloc(const char *path
, const char *name
, char **value
, bool allow_symlink
) {
45 for (l
= 100; ; l
= (size_t) n
+ 1) {
51 n
= lgetxattr(path
, name
, v
, l
);
53 n
= getxattr(path
, name
, v
, l
);
55 if (n
>= 0 && (size_t) n
< l
) {
62 if (n
< 0 && errno
!= ERANGE
)
66 n
= lgetxattr(path
, name
, NULL
, 0);
68 n
= getxattr(path
, name
, NULL
, 0);
74 int fgetxattr_malloc(int fd
, const char *name
, char **value
) {
83 for (l
= 100; ; l
= (size_t) n
+ 1) {
88 n
= fgetxattr(fd
, name
, v
, l
);
90 if (n
>= 0 && (size_t) n
< l
) {
97 if (n
< 0 && errno
!= ERANGE
)
100 n
= fgetxattr(fd
, name
, NULL
, 0);
106 ssize_t
fgetxattrat_fake(int dirfd
, const char *filename
, const char *attribute
, void *value
, size_t size
, int flags
) {
107 char fn
[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
108 _cleanup_close_
int fd
= -1;
111 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
113 fd
= openat(dirfd
, filename
, O_CLOEXEC
|O_PATH
|(flags
& AT_SYMLINK_NOFOLLOW
? O_NOFOLLOW
: 0));
117 xsprintf(fn
, "/proc/self/fd/%i", fd
);
119 l
= getxattr(fn
, attribute
, value
, size
);
126 static int parse_crtime(le64_t le
, usec_t
*usec
) {
132 if (IN_SET(u
, 0, (uint64_t) -1))
139 int fd_getcrtime(int fd
, usec_t
*usec
) {
146 /* Until Linux gets a real concept of birthtime/creation time,
147 * let's fake one with xattrs */
149 n
= fgetxattr(fd
, "user.crtime_usec", &le
, sizeof(le
));
155 return parse_crtime(le
, usec
);
158 int fd_getcrtime_at(int dirfd
, const char *name
, usec_t
*usec
, int flags
) {
162 n
= fgetxattrat_fake(dirfd
, name
, "user.crtime_usec", &le
, sizeof(le
), flags
);
168 return parse_crtime(le
, usec
);
171 int path_getcrtime(const char *p
, usec_t
*usec
) {
178 n
= getxattr(p
, "user.crtime_usec", &le
, sizeof(le
));
184 return parse_crtime(le
, usec
);
187 int fd_setcrtime(int fd
, usec_t usec
) {
193 usec
= now(CLOCK_REALTIME
);
195 le
= htole64((uint64_t) usec
);
196 if (fsetxattr(fd
, "user.crtime_usec", &le
, sizeof(le
), 0) < 0)