diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c index 4dc5a7de5b1..a37ee4b7ef0 100644 --- a/src/basic/xattr-util.c +++ b/src/basic/xattr-util.c @@ -107,7 +107,14 @@ int fgetxattr_malloc(int fd, const char *name, char **value) { } } -ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) { +int fgetxattrat_fake( + int dirfd, + const char *filename, + const char *attribute, + void *value, size_t size, + int flags, + size_t *ret_size) { + char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; _cleanup_close_ int fd = -1; ssize_t l; @@ -134,7 +141,8 @@ ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, if (l < 0) return -errno; - return l; + *ret_size = l; + return 0; } static int parse_crtime(le64_t le, usec_t *usec) { @@ -154,7 +162,7 @@ int fd_getcrtime_at(int dirfd, const char *name, usec_t *ret, int flags) { struct_statx sx; usec_t a, b; le64_t le; - ssize_t n; + size_t n; int r; assert(ret); @@ -180,13 +188,13 @@ int fd_getcrtime_at(int dirfd, const char *name, usec_t *ret, int flags) { else a = USEC_INFINITY; - n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags); - if (n < 0) - r = -errno; - else if (n != sizeof(le)) - r = -EIO; - else - r = parse_crtime(le, &b); + r = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags, &n); + if (r >= 0) { + if (n != sizeof(le)) + r = -EIO; + else + r = parse_crtime(le, &b); + } if (r < 0) { if (a != USEC_INFINITY) { *ret = a; diff --git a/src/basic/xattr-util.h b/src/basic/xattr-util.h index 1a78027aaac..e25970ee6d2 100644 --- a/src/basic/xattr-util.h +++ b/src/basic/xattr-util.h @@ -29,7 +29,13 @@ int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink); int fgetxattr_malloc(int fd, const char *name, char **value); -ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags); +int fgetxattrat_fake( + int dirfd, + const char *filename, + const char *attribute, + void *value, size_t size, + int flags, + size_t *ret_size); int fd_setcrtime(int fd, usec_t usec); diff --git a/src/test/test-xattr-util.c b/src/test/test-xattr-util.c index 17087a282db..36b64802196 100644 --- a/src/test/test-xattr-util.c +++ b/src/test/test-xattr-util.c @@ -36,8 +36,9 @@ static void test_fgetxattrat_fake(void) { char t[] = "/var/tmp/xattrtestXXXXXX"; _cleanup_close_ int fd = -1; const char *x; - char v[3] = {}; + char v[3]; int r; + size_t size; assert_se(mkdtemp(t)); x = strjoina(t, "/test"); @@ -51,13 +52,14 @@ static void test_fgetxattrat_fake(void) { fd = open(t, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY); assert_se(fd >= 0); - assert_se(fgetxattrat_fake(fd, "test", "user.foo", v, 3, 0) >= 0); + assert_se(fgetxattrat_fake(fd, "test", "user.foo", v, 3, 0, &size) >= 0); + assert_se(size == 3); assert_se(memcmp(v, "bar", 3) == 0); safe_close(fd); fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY); assert_se(fd >= 0); - assert_se(fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0) == -ENODATA); + assert_se(fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0, &size) == -ENODATA); cleanup: assert_se(unlink(x) >= 0);