vpick: take separate root_fd and dir_fd arguments
Mirror how chaseat() works these days: instead of a single toplevel_fd that serves as both the root (chroot) boundary and the directory that resolution starts from, path_pick() now takes a separate root_fd and dir_fd. This lets callers resolve a path relative to a specific directory fd while confining symlink and absolute-path resolution to a root directory fd. All existing callers are updated to pass the same fd for both, preserving their current behaviour.
This commit is contained in:
@@ -3719,8 +3719,9 @@ static int pin_rootfs(
|
||||
if (context->root_image) {
|
||||
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
||||
|
||||
r = path_pick(/* toplevel_path= */ NULL,
|
||||
/* toplevel_fd= */ AT_FDCWD,
|
||||
r = path_pick(/* root_path= */ NULL,
|
||||
/* root_fd= */ AT_FDCWD,
|
||||
/* dir_fd= */ AT_FDCWD,
|
||||
context->root_image,
|
||||
pick_filter_image_raw,
|
||||
ELEMENTSOF(pick_filter_image_raw),
|
||||
@@ -3760,8 +3761,9 @@ static int pin_rootfs(
|
||||
if (context->root_directory) {
|
||||
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
||||
|
||||
r = path_pick(/* toplevel_path= */ NULL,
|
||||
/* toplevel_fd= */ AT_FDCWD,
|
||||
r = path_pick(/* root_path= */ NULL,
|
||||
/* root_fd= */ AT_FDCWD,
|
||||
/* dir_fd= */ AT_FDCWD,
|
||||
context->root_directory,
|
||||
pick_filter_image_dir,
|
||||
ELEMENTSOF(pick_filter_image_dir),
|
||||
@@ -3789,8 +3791,9 @@ static int pin_rootfs(
|
||||
if (context->root_mstack) {
|
||||
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
||||
|
||||
r = path_pick(/* toplevel_path= */ NULL,
|
||||
/* toplevel_fd= */ AT_FDCWD,
|
||||
r = path_pick(/* root_path= */ NULL,
|
||||
/* root_fd= */ AT_FDCWD,
|
||||
/* dir_fd= */ AT_FDCWD,
|
||||
context->root_mstack,
|
||||
pick_filter_image_mstack,
|
||||
/* n_filters= */ 1,
|
||||
|
||||
@@ -564,8 +564,9 @@ static int append_extensions(
|
||||
_cleanup_free_ char *mount_point = NULL;
|
||||
const MountImage *m = mount_images + i;
|
||||
|
||||
r = path_pick(/* toplevel_path= */ NULL,
|
||||
/* toplevel_fd= */ AT_FDCWD,
|
||||
r = path_pick(/* root_path= */ NULL,
|
||||
/* root_fd= */ AT_FDCWD,
|
||||
/* dir_fd= */ AT_FDCWD,
|
||||
m->source,
|
||||
pick_filter_image_raw,
|
||||
ELEMENTSOF(pick_filter_image_raw),
|
||||
@@ -636,8 +637,9 @@ static int append_extensions(
|
||||
if (startswith(e, "+"))
|
||||
e++;
|
||||
|
||||
r = path_pick(/* toplevel_path= */ NULL,
|
||||
/* toplevel_fd= */ AT_FDCWD,
|
||||
r = path_pick(/* root_path= */ NULL,
|
||||
/* root_fd= */ AT_FDCWD,
|
||||
/* dir_fd= */ AT_FDCWD,
|
||||
e,
|
||||
pick_filter_image_dir,
|
||||
ELEMENTSOF(pick_filter_image_dir),
|
||||
|
||||
@@ -821,8 +821,9 @@ static int extract_image_and_extensions(
|
||||
/* If we get a path, then check if it can be resolved with vpick. We need this as we might just
|
||||
* get a simple image name, which would make vpick error out. */
|
||||
if (path_is_absolute(name_or_path)) {
|
||||
r = path_pick(/* toplevel_path= */ NULL,
|
||||
/* toplevel_fd= */ AT_FDCWD,
|
||||
r = path_pick(/* root_path= */ NULL,
|
||||
/* root_fd= */ AT_FDCWD,
|
||||
/* dir_fd= */ AT_FDCWD,
|
||||
name_or_path,
|
||||
pick_filter_image_any,
|
||||
ELEMENTSOF(pick_filter_image_any),
|
||||
@@ -860,8 +861,9 @@ static int extract_image_and_extensions(
|
||||
const char *path = *p;
|
||||
|
||||
if (path_is_absolute(*p)) {
|
||||
r = path_pick(/* toplevel_path= */ NULL,
|
||||
/* toplevel_fd= */ AT_FDCWD,
|
||||
r = path_pick(/* root_path= */ NULL,
|
||||
/* root_fd= */ AT_FDCWD,
|
||||
/* dir_fd= */ AT_FDCWD,
|
||||
*p,
|
||||
pick_filter_image_any,
|
||||
ELEMENTSOF(pick_filter_image_any),
|
||||
@@ -2201,8 +2203,9 @@ static bool marker_matches_images(const char *marker, const char *name_or_path,
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to extract image name from %s, ignoring: %m", image);
|
||||
|
||||
r = path_pick(/* toplevel_path= */ NULL,
|
||||
/* toplevel_fd= */ AT_FDCWD,
|
||||
r = path_pick(/* root_path= */ NULL,
|
||||
/* root_fd= */ AT_FDCWD,
|
||||
/* dir_fd= */ AT_FDCWD,
|
||||
*image_name_or_path,
|
||||
pick_filter_image_any,
|
||||
ELEMENTSOF(pick_filter_image_any),
|
||||
|
||||
@@ -956,6 +956,7 @@ int image_find(RuntimeScope scope,
|
||||
|
||||
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
||||
r = path_pick(root,
|
||||
rfd,
|
||||
rfd,
|
||||
fname_path, /* This has to be the unresolved entry with the .v suffix */
|
||||
&filter,
|
||||
@@ -1177,6 +1178,7 @@ int image_discover(
|
||||
|
||||
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
||||
r = path_pick(root,
|
||||
rfd,
|
||||
rfd,
|
||||
fname_path, /* This has to be the unresolved entry with the .v suffix */
|
||||
&filter,
|
||||
|
||||
+1
-1
@@ -139,7 +139,7 @@ static int mstack_load_one(MStack *mstack, const char *dir, int dir_fd, const ch
|
||||
};
|
||||
|
||||
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
||||
r = path_pick(dir, dir_fd, fname, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE, &result);
|
||||
r = path_pick(dir, dir_fd, dir_fd, fname, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE, &result);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to resolve '%s' directory: %m", fname);
|
||||
if (r == 0)
|
||||
|
||||
+52
-38
@@ -176,8 +176,9 @@ static int errno_from_mode(uint32_t type_mask, mode_t found) {
|
||||
}
|
||||
|
||||
static int pin_choice(
|
||||
const char *toplevel_path,
|
||||
int toplevel_fd,
|
||||
const char *root_path,
|
||||
int root_fd,
|
||||
int dir_fd,
|
||||
const char *inode_path,
|
||||
int _inode_fd, /* we always take ownership of the fd, even on failure */
|
||||
unsigned tries_left,
|
||||
@@ -190,14 +191,15 @@ static int pin_choice(
|
||||
_cleanup_free_ char *resolved_path = NULL;
|
||||
int r;
|
||||
|
||||
assert(wildcard_fd_is_valid(toplevel_fd));
|
||||
assert(wildcard_fd_is_valid(root_fd));
|
||||
assert(wildcard_fd_is_valid(dir_fd));
|
||||
assert(inode_path);
|
||||
assert(filter);
|
||||
assert(ret);
|
||||
|
||||
if (inode_fd < 0 || FLAGS_SET(flags, PICK_RESOLVE)) {
|
||||
r = chaseat(toplevel_fd,
|
||||
toplevel_fd,
|
||||
r = chaseat(root_fd,
|
||||
dir_fd,
|
||||
inode_path,
|
||||
/* flags= */ 0,
|
||||
FLAGS_SET(flags, PICK_RESOLVE) ? &resolved_path : NULL,
|
||||
@@ -212,11 +214,11 @@ static int pin_choice(
|
||||
struct stat st;
|
||||
if (fstat(inode_fd, &st) < 0)
|
||||
return log_debug_errno(errno, "Failed to stat discovered inode '%s%s': %m",
|
||||
empty_to_root(toplevel_path), skip_leading_slash(inode_path));
|
||||
empty_to_root(root_path), skip_leading_slash(inode_path));
|
||||
|
||||
if (filter->type_mask != 0 && !BIT_SET(filter->type_mask, IFTODT(st.st_mode))) {
|
||||
log_debug("Inode '%s/%s' has wrong type, found '%s'.",
|
||||
empty_to_root(toplevel_path), skip_leading_slash(inode_path),
|
||||
empty_to_root(root_path), skip_leading_slash(inode_path),
|
||||
inode_type_to_string(st.st_mode));
|
||||
*ret = PICK_RESULT_NULL;
|
||||
return 0;
|
||||
@@ -311,8 +313,9 @@ static bool architecture_matches(const PickFilter *filter, Architecture a) {
|
||||
}
|
||||
|
||||
static int make_choice(
|
||||
const char *toplevel_path,
|
||||
int toplevel_fd,
|
||||
const char *root_path,
|
||||
int root_fd,
|
||||
int dir_fd,
|
||||
const char *inode_path,
|
||||
int _inode_fd, /* we always take ownership of the fd, even on failure */
|
||||
const PickFilter *filter,
|
||||
@@ -322,13 +325,14 @@ static int make_choice(
|
||||
_cleanup_close_ int inode_fd = TAKE_FD(_inode_fd);
|
||||
int r;
|
||||
|
||||
assert(wildcard_fd_is_valid(toplevel_fd));
|
||||
assert(wildcard_fd_is_valid(root_fd));
|
||||
assert(wildcard_fd_is_valid(dir_fd));
|
||||
assert(inode_path);
|
||||
assert(filter);
|
||||
assert(ret);
|
||||
|
||||
if (inode_fd < 0) {
|
||||
r = chaseat(toplevel_fd, toplevel_fd, inode_path, /* flags= */ 0, NULL, &inode_fd);
|
||||
r = chaseat(root_fd, dir_fd, inode_path, /* flags= */ 0, NULL, &inode_fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -345,18 +349,19 @@ static int make_choice(
|
||||
return log_oom_debug();
|
||||
|
||||
_cleanup_close_ int object_fd = -EBADF;
|
||||
r = chaseat(toplevel_fd, toplevel_fd, p, /* flags= */ 0, &object_path, &object_fd);
|
||||
r = chaseat(root_fd, dir_fd, p, /* flags= */ 0, &object_path, &object_fd);
|
||||
if (r == -ENOENT) {
|
||||
*ret = PICK_RESULT_NULL;
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to open '%s/%s': %m",
|
||||
empty_to_root(toplevel_path), skip_leading_slash(p));
|
||||
empty_to_root(root_path), skip_leading_slash(p));
|
||||
|
||||
return pin_choice(
|
||||
toplevel_path,
|
||||
toplevel_fd,
|
||||
root_path,
|
||||
root_fd,
|
||||
dir_fd,
|
||||
FLAGS_SET(flags, PICK_RESOLVE) ? object_path : p,
|
||||
TAKE_FD(object_fd), /* unconditionally pass ownership of the fd */
|
||||
/* tries_left= */ UINT_MAX,
|
||||
@@ -371,16 +376,16 @@ static int make_choice(
|
||||
/* Underspecified, so we do our enumeration dance */
|
||||
|
||||
/* Convert O_PATH to a regular directory fd */
|
||||
_cleanup_close_ int dir_fd = fd_reopen(inode_fd, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
|
||||
if (dir_fd < 0)
|
||||
return log_debug_errno(dir_fd, "Failed to reopen '%s/%s' as directory: %m",
|
||||
empty_to_root(toplevel_path), skip_leading_slash(inode_path));
|
||||
_cleanup_close_ int enumerate_fd = fd_reopen(inode_fd, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
|
||||
if (enumerate_fd < 0)
|
||||
return log_debug_errno(enumerate_fd, "Failed to reopen '%s/%s' as directory: %m",
|
||||
empty_to_root(root_path), skip_leading_slash(inode_path));
|
||||
|
||||
_cleanup_free_ DirectoryEntries *de = NULL;
|
||||
r = readdir_all(dir_fd, 0, &de);
|
||||
r = readdir_all(enumerate_fd, 0, &de);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to read directory '%s/%s': %m",
|
||||
empty_to_root(toplevel_path), skip_leading_slash(inode_path));
|
||||
empty_to_root(root_path), skip_leading_slash(inode_path));
|
||||
|
||||
_cleanup_(pick_result_done) PickResult best = PICK_RESULT_NULL;
|
||||
|
||||
@@ -457,8 +462,9 @@ static int make_choice(
|
||||
return log_oom_debug();
|
||||
|
||||
_cleanup_(pick_result_done) PickResult found = PICK_RESULT_NULL;
|
||||
r = pin_choice(toplevel_path,
|
||||
toplevel_fd,
|
||||
r = pin_choice(root_path,
|
||||
root_fd,
|
||||
dir_fd,
|
||||
p,
|
||||
/* _inode_fd= */ -EBADF,
|
||||
found_tries_left,
|
||||
@@ -501,8 +507,9 @@ static int make_choice(
|
||||
}
|
||||
|
||||
static int path_pick_one(
|
||||
const char *toplevel_path,
|
||||
int toplevel_fd,
|
||||
const char *root_path,
|
||||
int root_fd,
|
||||
int dir_fd,
|
||||
const char *path,
|
||||
const PickFilter *filter,
|
||||
PickFlags flags,
|
||||
@@ -513,7 +520,8 @@ static int path_pick_one(
|
||||
uint32_t filter_type_mask;
|
||||
int r;
|
||||
|
||||
assert(wildcard_fd_is_valid(toplevel_fd));
|
||||
assert(wildcard_fd_is_valid(root_fd));
|
||||
assert(wildcard_fd_is_valid(dir_fd));
|
||||
assert(path);
|
||||
assert(filter);
|
||||
assert(ret);
|
||||
@@ -537,8 +545,9 @@ static int path_pick_one(
|
||||
/* Explicit basename specified, then shortcut things and do .v mode regardless of the path name. */
|
||||
if (filter->basename)
|
||||
return make_choice(
|
||||
toplevel_path,
|
||||
toplevel_fd,
|
||||
root_path,
|
||||
root_fd,
|
||||
dir_fd,
|
||||
path,
|
||||
/* inode_fd= */ -EBADF,
|
||||
filter,
|
||||
@@ -623,8 +632,9 @@ static int path_pick_one(
|
||||
}
|
||||
|
||||
return make_choice(
|
||||
toplevel_path,
|
||||
toplevel_fd,
|
||||
root_path,
|
||||
root_fd,
|
||||
dir_fd,
|
||||
enumeration_path,
|
||||
/* inode_fd= */ -EBADF,
|
||||
&(const PickFilter) {
|
||||
@@ -640,8 +650,9 @@ static int path_pick_one(
|
||||
bypass:
|
||||
/* Don't make any choice, but just use the passed path literally */
|
||||
return pin_choice(
|
||||
toplevel_path,
|
||||
toplevel_fd,
|
||||
root_path,
|
||||
root_fd,
|
||||
dir_fd,
|
||||
path,
|
||||
/* inode_fd= */ -EBADF,
|
||||
/* tries_left= */ UINT_MAX,
|
||||
@@ -651,8 +662,9 @@ bypass:
|
||||
ret);
|
||||
}
|
||||
|
||||
int path_pick(const char *toplevel_path,
|
||||
int toplevel_fd,
|
||||
int path_pick(const char *root_path,
|
||||
int root_fd,
|
||||
int dir_fd,
|
||||
const char *path,
|
||||
const PickFilter filters[],
|
||||
size_t n_filters,
|
||||
@@ -662,7 +674,8 @@ int path_pick(const char *toplevel_path,
|
||||
_cleanup_(pick_result_done) PickResult best = PICK_RESULT_NULL;
|
||||
int r;
|
||||
|
||||
assert(wildcard_fd_is_valid(toplevel_fd));
|
||||
assert(wildcard_fd_is_valid(root_fd));
|
||||
assert(wildcard_fd_is_valid(dir_fd));
|
||||
assert(path);
|
||||
assert(filters || n_filters == 0);
|
||||
assert(ret);
|
||||
@@ -671,7 +684,7 @@ int path_pick(const char *toplevel_path,
|
||||
for (size_t i = 0; i < n_filters; i++) {
|
||||
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
||||
|
||||
r = path_pick_one(toplevel_path, toplevel_fd, path, &filters[i], flags, &result);
|
||||
r = path_pick_one(root_path, root_fd, dir_fd, path, &filters[i], flags, &result);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
@@ -717,8 +730,9 @@ int path_pick_update_warn(
|
||||
|
||||
/* This updates the first argument if needed! */
|
||||
|
||||
r = path_pick(/* toplevel_path= */ NULL,
|
||||
/* toplevel_fd= */ AT_FDCWD,
|
||||
r = path_pick(/* root_path= */ NULL,
|
||||
/* root_fd= */ AT_FDCWD,
|
||||
/* dir_fd= */ AT_FDCWD,
|
||||
*path,
|
||||
filters,
|
||||
n_filters,
|
||||
|
||||
+3
-2
@@ -45,8 +45,9 @@ void pick_result_done(PickResult *p);
|
||||
|
||||
int pick_result_compare(const PickResult *a, const PickResult *b, PickFlags flags);
|
||||
|
||||
int path_pick(const char *toplevel_path,
|
||||
int toplevel_fd,
|
||||
int path_pick(const char *root_path,
|
||||
int root_fd,
|
||||
int dir_fd,
|
||||
const char *path,
|
||||
const PickFilter filters[],
|
||||
size_t n_filters,
|
||||
|
||||
+24
-24
@@ -48,7 +48,7 @@ TEST(path_pick) {
|
||||
};
|
||||
|
||||
if (IN_SET(native_architecture(), ARCHITECTURE_X86, ARCHITECTURE_X86_64)) {
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_TRUE(S_ISREG(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "99");
|
||||
ASSERT_EQ(result.architecture, ARCHITECTURE_X86);
|
||||
@@ -58,7 +58,7 @@ TEST(path_pick) {
|
||||
}
|
||||
|
||||
filter.architecture = ARCHITECTURE_X86_64;
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_TRUE(S_ISREG(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "55");
|
||||
ASSERT_EQ(result.architecture, ARCHITECTURE_X86_64);
|
||||
@@ -66,7 +66,7 @@ TEST(path_pick) {
|
||||
pick_result_done(&result);
|
||||
|
||||
filter.architecture = ARCHITECTURE_IA64;
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_TRUE(S_ISREG(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "5");
|
||||
ASSERT_EQ(result.architecture, ARCHITECTURE_IA64);
|
||||
@@ -75,7 +75,7 @@ TEST(path_pick) {
|
||||
|
||||
filter.architecture = _ARCHITECTURE_INVALID;
|
||||
filter.version = "5";
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_TRUE(S_ISREG(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "5");
|
||||
if (native_architecture() != ARCHITECTURE_IA64) {
|
||||
@@ -85,7 +85,7 @@ TEST(path_pick) {
|
||||
pick_result_done(&result);
|
||||
|
||||
filter.architecture = ARCHITECTURE_IA64;
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_TRUE(S_ISREG(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "5");
|
||||
ASSERT_EQ(result.architecture, ARCHITECTURE_IA64);
|
||||
@@ -93,7 +93,7 @@ TEST(path_pick) {
|
||||
pick_result_done(&result);
|
||||
|
||||
filter.architecture = ARCHITECTURE_CRIS;
|
||||
ASSERT_OK_ZERO(path_pick(NULL, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_OK_ZERO(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_EQ(result.st.st_mode, MODE_INVALID);
|
||||
ASSERT_NULL(result.version);
|
||||
ASSERT_LT(result.architecture, 0);
|
||||
@@ -104,7 +104,7 @@ TEST(path_pick) {
|
||||
filter.architecture = _ARCHITECTURE_INVALID;
|
||||
filter.version = NULL;
|
||||
if (IN_SET(native_architecture(), ARCHITECTURE_X86_64, ARCHITECTURE_X86)) {
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_TRUE(S_ISREG(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "55");
|
||||
|
||||
@@ -123,7 +123,7 @@ TEST(path_pick) {
|
||||
pp = ASSERT_NOT_NULL(path_join(p, "foo.v/foo___.raw"));
|
||||
|
||||
if (IN_SET(native_architecture(), ARCHITECTURE_X86, ARCHITECTURE_X86_64)) {
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_TRUE(S_ISREG(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "55");
|
||||
ASSERT_EQ(result.architecture, native_architecture());
|
||||
@@ -137,10 +137,10 @@ TEST(path_pick) {
|
||||
pp = ASSERT_NOT_NULL(path_join(p, "foo.v/foo_5.raw"));
|
||||
|
||||
filter.type_mask = UINT32_C(1) << DT_DIR;
|
||||
ASSERT_OK_ZERO(path_pick(NULL, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_OK_ZERO(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
|
||||
filter.type_mask = UINT32_C(1) << DT_REG;
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_TRUE(S_ISREG(result.st.st_mode));
|
||||
ASSERT_NULL(result.version);
|
||||
ASSERT_EQ(result.architecture, _ARCHITECTURE_INVALID);
|
||||
@@ -153,7 +153,7 @@ TEST(path_pick) {
|
||||
filter.architecture = ARCHITECTURE_S390;
|
||||
filter.basename = "quux";
|
||||
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, &filter, /* n_filters= */ 1, PICK_ARCHITECTURE|PICK_TRIES, &result));
|
||||
ASSERT_TRUE(S_ISREG(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "2");
|
||||
ASSERT_EQ(result.tries_left, 4U);
|
||||
@@ -209,7 +209,7 @@ TEST(pick_filter_image_any) {
|
||||
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
||||
|
||||
/* Test pick_filter_image_any: should pick the highest version, which is the directory test_5 */
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_TRUE(S_ISDIR(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "5");
|
||||
ASSERT_TRUE(endswith(result.path, "/test_5"));
|
||||
@@ -219,14 +219,14 @@ TEST(pick_filter_image_any) {
|
||||
ASSERT_OK(unlinkat(sub_dfd, "test_4", AT_REMOVEDIR));
|
||||
ASSERT_OK(unlinkat(sub_dfd, "test_5", AT_REMOVEDIR));
|
||||
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_TRUE(S_ISREG(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "3");
|
||||
ASSERT_TRUE(endswith(result.path, "/test_3.raw"));
|
||||
pick_result_done(&result);
|
||||
|
||||
/* Verify that pick_filter_image_raw only matches .raw files */
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_raw, ELEMENTSOF(pick_filter_image_raw), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_raw, ELEMENTSOF(pick_filter_image_raw), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_TRUE(S_ISREG(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "3");
|
||||
ASSERT_TRUE(endswith(result.path, "/test_3.raw"));
|
||||
@@ -239,12 +239,12 @@ TEST(pick_filter_image_any) {
|
||||
ASSERT_OK(unlinkat(sub_dfd, "test_3.raw", 0));
|
||||
|
||||
/* Now only test_10.txt, test_11.img, and test_12 remain - none should match */
|
||||
ASSERT_OK_ZERO(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_OK_ZERO(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE, &result));
|
||||
|
||||
/* But if we add a directory, it should be picked */
|
||||
ASSERT_OK(mkdirat(sub_dfd, "test_6", 0755));
|
||||
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_TRUE(S_ISDIR(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "6");
|
||||
ASSERT_TRUE(endswith(result.path, "/test_6"));
|
||||
@@ -263,7 +263,7 @@ TEST(pick_filter_image_any) {
|
||||
|
||||
pick_result_done(&result);
|
||||
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_dir, ELEMENTSOF(pick_filter_image_dir), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_dir, ELEMENTSOF(pick_filter_image_dir), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_TRUE(S_ISDIR(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "2");
|
||||
ASSERT_TRUE(endswith(result.path, "/myimage_2"));
|
||||
@@ -273,7 +273,7 @@ TEST(pick_filter_image_any) {
|
||||
ASSERT_OK(unlinkat(sub_dfd, "myimage_1", AT_REMOVEDIR));
|
||||
ASSERT_OK(unlinkat(sub_dfd, "myimage_2", AT_REMOVEDIR));
|
||||
|
||||
ASSERT_OK_ZERO(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_dir, ELEMENTSOF(pick_filter_image_dir), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_OK_ZERO(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_dir, ELEMENTSOF(pick_filter_image_dir), PICK_ARCHITECTURE, &result));
|
||||
}
|
||||
|
||||
TEST(path_pick_resolve) {
|
||||
@@ -294,26 +294,26 @@ TEST(path_pick_resolve) {
|
||||
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
||||
|
||||
/* Test without PICK_RESOLVE - should return the symlink path */
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_STREQ(result.version, "2");
|
||||
ASSERT_TRUE(endswith(result.path, "/resolve_2.raw"));
|
||||
pick_result_done(&result);
|
||||
|
||||
/* Test with PICK_RESOLVE - should return the resolved (target) path */
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE|PICK_RESOLVE, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_any, ELEMENTSOF(pick_filter_image_any), PICK_ARCHITECTURE|PICK_RESOLVE, &result));
|
||||
ASSERT_STREQ(result.version, "2");
|
||||
ASSERT_TRUE(endswith(result.path, "/target_file.raw"));
|
||||
pick_result_done(&result);
|
||||
|
||||
/* Test pick_filter_image_dir without PICK_RESOLVE */
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_dir, ELEMENTSOF(pick_filter_image_dir), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_dir, ELEMENTSOF(pick_filter_image_dir), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_TRUE(S_ISDIR(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "1");
|
||||
ASSERT_TRUE(endswith(result.path, "/resolve_1"));
|
||||
pick_result_done(&result);
|
||||
|
||||
/* Test pick_filter_image_dir with PICK_RESOLVE */
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_dir, ELEMENTSOF(pick_filter_image_dir), PICK_ARCHITECTURE|PICK_RESOLVE, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_dir, ELEMENTSOF(pick_filter_image_dir), PICK_ARCHITECTURE|PICK_RESOLVE, &result));
|
||||
ASSERT_TRUE(S_ISDIR(result.st.st_mode));
|
||||
ASSERT_STREQ(result.version, "1");
|
||||
ASSERT_TRUE(endswith(result.path, "/target_dir"));
|
||||
@@ -323,12 +323,12 @@ TEST(path_pick_resolve) {
|
||||
ASSERT_OK(symlinkat("target_file.raw", dfd, "intermediate_link.raw"));
|
||||
ASSERT_OK(symlinkat("../intermediate_link.raw", sub_dfd, "resolve_3.raw"));
|
||||
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_raw, ELEMENTSOF(pick_filter_image_raw), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_raw, ELEMENTSOF(pick_filter_image_raw), PICK_ARCHITECTURE, &result));
|
||||
ASSERT_STREQ(result.version, "3");
|
||||
ASSERT_TRUE(endswith(result.path, "/resolve_3.raw"));
|
||||
pick_result_done(&result);
|
||||
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, pp, pick_filter_image_raw, ELEMENTSOF(pick_filter_image_raw), PICK_ARCHITECTURE|PICK_RESOLVE, &result));
|
||||
ASSERT_OK_POSITIVE(path_pick(NULL, AT_FDCWD, AT_FDCWD, pp, pick_filter_image_raw, ELEMENTSOF(pick_filter_image_raw), PICK_ARCHITECTURE|PICK_RESOLVE, &result));
|
||||
ASSERT_STREQ(result.version, "3");
|
||||
/* The chain should be fully resolved to target_file.raw */
|
||||
ASSERT_TRUE(endswith(result.path, "/target_file.raw"));
|
||||
|
||||
@@ -237,8 +237,9 @@ static int run(int argc, char *argv[]) {
|
||||
return log_error_errno(r, "Failed to make path '%s' absolute: %m", *i);
|
||||
|
||||
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
||||
r = path_pick(/* toplevel_path= */ NULL,
|
||||
/* toplevel_fd= */ AT_FDCWD,
|
||||
r = path_pick(/* root_path= */ NULL,
|
||||
/* root_fd= */ AT_FDCWD,
|
||||
/* dir_fd= */ AT_FDCWD,
|
||||
p,
|
||||
&(PickFilter) {
|
||||
.basename = arg_filter_basename,
|
||||
|
||||
Reference in New Issue
Block a user