mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
xattr-util: add fgetxattrat_fake_malloc variant
This commit is contained in:
parent
7a6abbe937
commit
5ce46344fd
@ -103,6 +103,43 @@ int fgetxattr_malloc(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note: ret_fn should already be allocated for the usual xsprintf and /proc/self/fd/%i pattern. */
|
||||||
|
static int getxattrat_fake_prepare(
|
||||||
|
int dirfd,
|
||||||
|
const char *filename,
|
||||||
|
int flags,
|
||||||
|
char ret_fn[static STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1],
|
||||||
|
int *ret_fd) {
|
||||||
|
|
||||||
|
_cleanup_close_ int fd = -1;
|
||||||
|
|
||||||
|
assert(ret_fn);
|
||||||
|
assert(ret_fd);
|
||||||
|
|
||||||
|
/* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
|
||||||
|
|
||||||
|
if (flags & ~(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (isempty(filename)) {
|
||||||
|
if (!(flags & AT_EMPTY_PATH))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
snprintf(ret_fn, STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1, "/proc/self/fd/%i", dirfd);
|
||||||
|
} else {
|
||||||
|
fd = openat(dirfd, filename, O_CLOEXEC|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
snprintf(ret_fn, STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1, "/proc/self/fd/%i", fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pass the FD to the caller, since in case we do openat() the filename depends on it. */
|
||||||
|
*ret_fd = TAKE_FD(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int fgetxattrat_fake(
|
int fgetxattrat_fake(
|
||||||
int dirfd,
|
int dirfd,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
@ -114,24 +151,11 @@ int fgetxattrat_fake(
|
|||||||
char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
|
char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
ssize_t l;
|
ssize_t l;
|
||||||
|
int r;
|
||||||
|
|
||||||
/* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
|
r = getxattrat_fake_prepare(dirfd, filename, flags, fn, &fd);
|
||||||
|
if (r < 0)
|
||||||
if (flags & ~(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH))
|
return r;
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (isempty(filename)) {
|
|
||||||
if (!(flags & AT_EMPTY_PATH))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
xsprintf(fn, "/proc/self/fd/%i", dirfd);
|
|
||||||
} else {
|
|
||||||
fd = openat(dirfd, filename, O_CLOEXEC|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
|
|
||||||
if (fd < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
xsprintf(fn, "/proc/self/fd/%i", fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
l = getxattr(fn, attribute, value, size);
|
l = getxattr(fn, attribute, value, size);
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
@ -141,6 +165,24 @@ int fgetxattrat_fake(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fgetxattrat_fake_malloc(
|
||||||
|
int dirfd,
|
||||||
|
const char *filename,
|
||||||
|
const char *attribute,
|
||||||
|
int flags,
|
||||||
|
char **value) {
|
||||||
|
|
||||||
|
char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
|
||||||
|
_cleanup_close_ int fd = -1;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = getxattrat_fake_prepare(dirfd, filename, flags, fn, &fd);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return getxattr_malloc(fn, attribute, value, false);
|
||||||
|
}
|
||||||
|
|
||||||
static int parse_crtime(le64_t le, usec_t *usec) {
|
static int parse_crtime(le64_t le, usec_t *usec) {
|
||||||
uint64_t u;
|
uint64_t u;
|
||||||
|
|
||||||
|
@ -17,6 +17,12 @@ int fgetxattrat_fake(
|
|||||||
void *value, size_t size,
|
void *value, size_t size,
|
||||||
int flags,
|
int flags,
|
||||||
size_t *ret_size);
|
size_t *ret_size);
|
||||||
|
int fgetxattrat_fake_malloc(
|
||||||
|
int dirfd,
|
||||||
|
const char *filename,
|
||||||
|
const char *attribute,
|
||||||
|
int flags,
|
||||||
|
char **value);
|
||||||
|
|
||||||
int fd_setcrtime(int fd, usec_t usec);
|
int fd_setcrtime(int fd, usec_t usec);
|
||||||
|
|
||||||
|
@ -17,12 +17,15 @@
|
|||||||
|
|
||||||
static void test_fgetxattrat_fake(void) {
|
static void test_fgetxattrat_fake(void) {
|
||||||
char t[] = "/var/tmp/xattrtestXXXXXX";
|
char t[] = "/var/tmp/xattrtestXXXXXX";
|
||||||
|
_cleanup_free_ char *value = NULL;
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
const char *x;
|
const char *x;
|
||||||
char v[3];
|
char v[3];
|
||||||
int r;
|
int r;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
assert_se(mkdtemp(t));
|
assert_se(mkdtemp(t));
|
||||||
x = strjoina(t, "/test");
|
x = strjoina(t, "/test");
|
||||||
assert_se(touch(x) >= 0);
|
assert_se(touch(x) >= 0);
|
||||||
@ -45,6 +48,13 @@ static void test_fgetxattrat_fake(void) {
|
|||||||
r = fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0, &size);
|
r = fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0, &size);
|
||||||
assert_se(r == -ENODATA || ERRNO_IS_NOT_SUPPORTED(r));
|
assert_se(r == -ENODATA || ERRNO_IS_NOT_SUPPORTED(r));
|
||||||
|
|
||||||
|
safe_close(fd);
|
||||||
|
fd = open(x, O_PATH|O_CLOEXEC);
|
||||||
|
assert_se(fd >= 0);
|
||||||
|
r = fgetxattrat_fake_malloc(fd, NULL, "user.foo", AT_EMPTY_PATH, &value);
|
||||||
|
assert_se(r == 3);
|
||||||
|
assert_se(streq(value, "bar"));
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
assert_se(unlink(x) >= 0);
|
assert_se(unlink(x) >= 0);
|
||||||
assert_se(rmdir(t) >= 0);
|
assert_se(rmdir(t) >= 0);
|
||||||
@ -56,6 +66,8 @@ static void test_getcrtime(void) {
|
|||||||
usec_t usec, k;
|
usec_t usec, k;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
assert_se(tmp_dir(&vt) >= 0);
|
assert_se(tmp_dir(&vt) >= 0);
|
||||||
|
|
||||||
fd = open_tmpfile_unlinkable(vt, O_RDWR);
|
fd = open_tmpfile_unlinkable(vt, O_RDWR);
|
||||||
|
Loading…
Reference in New Issue
Block a user