Merge pull request #14081 from poettering/xattr-list-rework
xattr-util rework and addition of flistxattr_malloc() helper plus test
This commit is contained in:
+17
-51
@@ -20,6 +20,7 @@
|
||||
#include "macro.h"
|
||||
#include "missing_syscall.h"
|
||||
#include "mountpoint-util.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@@ -913,63 +914,28 @@ int copy_times(int fdf, int fdt, CopyFlags flags) {
|
||||
}
|
||||
|
||||
int copy_xattr(int fdf, int fdt) {
|
||||
_cleanup_free_ char *bufa = NULL, *bufb = NULL;
|
||||
size_t sza = 100, szb = 100;
|
||||
ssize_t n;
|
||||
int ret = 0;
|
||||
_cleanup_free_ char *names = NULL;
|
||||
int ret = 0, r;
|
||||
const char *p;
|
||||
|
||||
for (;;) {
|
||||
bufa = malloc(sza);
|
||||
if (!bufa)
|
||||
return -ENOMEM;
|
||||
r = flistxattr_malloc(fdf, &names);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n = flistxattr(fdf, bufa, sza);
|
||||
if (n == 0)
|
||||
return 0;
|
||||
if (n > 0)
|
||||
break;
|
||||
if (errno != ERANGE)
|
||||
return -errno;
|
||||
NULSTR_FOREACH(p, names) {
|
||||
_cleanup_free_ char *value = NULL;
|
||||
|
||||
sza *= 2;
|
||||
if (!startswith(p, "user."))
|
||||
continue;
|
||||
|
||||
bufa = mfree(bufa);
|
||||
}
|
||||
r = fgetxattr_malloc(fdf, p, &value);
|
||||
if (r == -ENODATA)
|
||||
continue; /* gone by now */
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
p = bufa;
|
||||
while (n > 0) {
|
||||
size_t l;
|
||||
|
||||
l = strlen(p);
|
||||
assert(l < (size_t) n);
|
||||
|
||||
if (startswith(p, "user.")) {
|
||||
ssize_t m;
|
||||
|
||||
if (!bufb) {
|
||||
bufb = malloc(szb);
|
||||
if (!bufb)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
m = fgetxattr(fdf, p, bufb, szb);
|
||||
if (m < 0) {
|
||||
if (errno == ERANGE) {
|
||||
szb *= 2;
|
||||
bufb = mfree(bufb);
|
||||
continue;
|
||||
}
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (fsetxattr(fdt, p, bufb, m, 0) < 0)
|
||||
ret = -errno;
|
||||
}
|
||||
|
||||
p += l + 1;
|
||||
n -= l + 1;
|
||||
if (fsetxattr(fdt, p, value, r, 0) < 0)
|
||||
ret = -errno;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
+81
-30
@@ -17,17 +17,23 @@
|
||||
#include "time-util.h"
|
||||
#include "xattr-util.h"
|
||||
|
||||
int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
|
||||
char *v;
|
||||
size_t l;
|
||||
ssize_t n;
|
||||
int getxattr_malloc(
|
||||
const char *path,
|
||||
const char *name,
|
||||
char **ret,
|
||||
bool allow_symlink) {
|
||||
|
||||
size_t l = 100;
|
||||
|
||||
assert(path);
|
||||
assert(name);
|
||||
assert(value);
|
||||
assert(ret);
|
||||
|
||||
for (l = 100; ; l = (size_t) n + 1 /* extra byte to make sure this remains NUL suffixed */) {
|
||||
v = new0(char, l);
|
||||
for(;;) {
|
||||
_cleanup_free_ char *v = NULL;
|
||||
ssize_t n;
|
||||
|
||||
v = new0(char, l+1);
|
||||
if (!v)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -35,53 +41,64 @@ int getxattr_malloc(const char *path, const char *name, char **value, bool allow
|
||||
n = lgetxattr(path, name, v, l);
|
||||
else
|
||||
n = getxattr(path, name, v, l);
|
||||
if (n >= 0 && (size_t) n < l) {
|
||||
*value = v;
|
||||
return n;
|
||||
if (n < 0) {
|
||||
if (errno != ERANGE)
|
||||
return -errno;
|
||||
} else {
|
||||
v[n] = 0; /* NUL terminate */
|
||||
*ret = TAKE_PTR(v);
|
||||
return (int) n;
|
||||
}
|
||||
|
||||
free(v);
|
||||
|
||||
if (n < 0 && errno != ERANGE)
|
||||
return -errno;
|
||||
|
||||
if (allow_symlink)
|
||||
n = lgetxattr(path, name, NULL, 0);
|
||||
else
|
||||
n = getxattr(path, name, NULL, 0);
|
||||
if (n < 0)
|
||||
return -errno;
|
||||
if (n > INT_MAX) /* We couldn't return this as 'int' anymore */
|
||||
return -E2BIG;
|
||||
|
||||
l = (size_t) n;
|
||||
}
|
||||
}
|
||||
|
||||
int fgetxattr_malloc(int fd, const char *name, char **value) {
|
||||
char *v;
|
||||
size_t l;
|
||||
ssize_t n;
|
||||
int fgetxattr_malloc(
|
||||
int fd,
|
||||
const char *name,
|
||||
char **ret) {
|
||||
|
||||
size_t l = 100;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(name);
|
||||
assert(value);
|
||||
assert(ret);
|
||||
|
||||
for (l = 100;; l = (size_t) n + 1 /* extra byte to make sure this remains NUL suffixed */) {
|
||||
v = new0(char, l);
|
||||
for (;;) {
|
||||
_cleanup_free_ char *v = NULL;
|
||||
ssize_t n;
|
||||
|
||||
v = new(char, l+1);
|
||||
if (!v)
|
||||
return -ENOMEM;
|
||||
|
||||
n = fgetxattr(fd, name, v, l);
|
||||
if (n >= 0 && (size_t) n < l) {
|
||||
*value = v;
|
||||
return n;
|
||||
if (n < 0) {
|
||||
if (errno != ERANGE)
|
||||
return -errno;
|
||||
} else {
|
||||
v[n] = 0; /* NUL terminate */
|
||||
*ret = TAKE_PTR(v);
|
||||
return (int) n;
|
||||
}
|
||||
|
||||
free(v);
|
||||
|
||||
if (n < 0 && errno != ERANGE)
|
||||
return -errno;
|
||||
|
||||
n = fgetxattr(fd, name, NULL, 0);
|
||||
if (n < 0)
|
||||
return -errno;
|
||||
if (n > INT_MAX) /* We couldn't return this as 'int' anymore */
|
||||
return -E2BIG;
|
||||
|
||||
l = (size_t) n;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,3 +234,37 @@ int fd_setcrtime(int fd, usec_t usec) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flistxattr_malloc(int fd, char **ret) {
|
||||
size_t l = 100;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ret);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *v = NULL;
|
||||
ssize_t n;
|
||||
|
||||
v = new(char, l+1);
|
||||
if (!v)
|
||||
return -ENOMEM;
|
||||
|
||||
n = flistxattr(fd, v, l);
|
||||
if (n < 0) {
|
||||
if (errno != ERANGE)
|
||||
return -errno;
|
||||
} else {
|
||||
v[n] = 0; /* NUL terminate */
|
||||
*ret = TAKE_PTR(v);
|
||||
return (int) n;
|
||||
}
|
||||
|
||||
n = flistxattr(fd, NULL, 0);
|
||||
if (n < 0)
|
||||
return -errno;
|
||||
if (n > INT_MAX) /* We couldn't return this as 'int' anymore */
|
||||
return -E2BIG;
|
||||
|
||||
l = (size_t) n;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,3 +23,5 @@ int fd_setcrtime(int fd, usec_t usec);
|
||||
int fd_getcrtime(int fd, usec_t *usec);
|
||||
int path_getcrtime(const char *p, usec_t *usec);
|
||||
int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags);
|
||||
|
||||
int flistxattr_malloc(int fd, char **ret);
|
||||
|
||||
Reference in New Issue
Block a user