Skip to content
Snippets Groups Projects
Commit a7fa6ff6 authored by Simon McVittie's avatar Simon McVittie
Browse files

resolve-in-sysroot: Add SRT_RESOLVE_FLAGS_DIRECTORY

parent 82725bfc
No related branches found
No related tags found
1 merge request!139Move resolve-in-sysroot into the shared library
......@@ -32,6 +32,8 @@
* the path is a symlink, fail with %G_IO_ERROR_TOO_MANY_LINKS.
* @SRT_RESOLVE_FLAGS_READABLE: Open the last component of the path
* for reading, instead of just as `O_PATH`.
* @SRT_RESOLVE_FLAGS_DIRECTORY: Open the last component of the path
* for reading, and it must be a directory.
* @SRT_RESOLVE_FLAGS_NONE: No special behaviour.
*
* Flags affecting how _srt_resolve_in_sysroot() behaves.
......@@ -42,6 +44,7 @@ typedef enum
SRT_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK = (1 << 1),
SRT_RESOLVE_FLAGS_REJECT_SYMLINKS = (1 << 2),
SRT_RESOLVE_FLAGS_READABLE = (1 << 3),
SRT_RESOLVE_FLAGS_DIRECTORY = (1 << 4),
SRT_RESOLVE_FLAGS_NONE = 0
} SrtResolveFlags;
......
......@@ -303,15 +303,23 @@ _srt_resolve_in_sysroot (int sysroot,
}
}
if (flags & SRT_RESOLVE_FLAGS_READABLE)
if (flags & (SRT_RESOLVE_FLAGS_READABLE|SRT_RESOLVE_FLAGS_DIRECTORY))
{
g_autofree char *proc_fd_name = g_strdup_printf ("/proc/self/fd/%d",
g_array_index (fds, int,
fds->len - 1));
glnx_autofd int fd = -1;
if (!glnx_openat_rdonly (-1, proc_fd_name, TRUE, &fd, error))
return -1;
if (flags & SRT_RESOLVE_FLAGS_DIRECTORY)
{
if (!glnx_opendirat (-1, proc_fd_name, TRUE, &fd, error))
return -1;
}
else
{
if (!glnx_openat_rdonly (-1, proc_fd_name, TRUE, &fd, error))
return -1;
}
if (real_path_out != NULL)
*real_path_out = g_string_free (g_steal_pointer (&current_path), FALSE);
......
......@@ -110,6 +110,10 @@ test_resolve_in_sysroot (Fixture *f,
"a/b/c/d/e",
"a/b2/c2/d2/e2",
};
static const char * const prepare_files[] =
{
"a/b/c/file",
};
static const Symlink prepare_symlinks[] =
{
{ "a/b/symlink_to_c", "c" },
......@@ -137,6 +141,21 @@ test_resolve_in_sysroot (Fixture *f,
{ NULL, G_IO_ERROR_NOT_FOUND }
},
{ { "a/b/c/d", SRT_RESOLVE_FLAGS_MKDIR_P }, { "a/b/c/d" } },
{ { "a/b/c/d", SRT_RESOLVE_FLAGS_READABLE }, { "a/b/c/d" } },
{ { "a/b/c/d", SRT_RESOLVE_FLAGS_DIRECTORY }, { "a/b/c/d" } },
{
{ "a/b/c/d", SRT_RESOLVE_FLAGS_READABLE|SRT_RESOLVE_FLAGS_DIRECTORY },
{ "a/b/c/d" }
},
{ { "a/b/c/file", SRT_RESOLVE_FLAGS_READABLE }, { "a/b/c/file" } },
{
{ "a/b/c/file", SRT_RESOLVE_FLAGS_DIRECTORY },
{ NULL, G_IO_ERROR_NOT_DIRECTORY }
},
{
{ "a/b/c/file", SRT_RESOLVE_FLAGS_READABLE|SRT_RESOLVE_FLAGS_DIRECTORY },
{ NULL, G_IO_ERROR_NOT_DIRECTORY }
},
{ { "a/b///////.////./././///././c/d" }, { "a/b/c/d" } },
{ { "/a/b///////.////././../b2////././c2/d2" }, { "a/b2/c2/d2" } },
{ { "a/b/c/d/e/f" }, { NULL, G_IO_ERROR_NOT_FOUND } },
......@@ -193,6 +212,16 @@ test_resolve_in_sysroot (Fixture *f,
g_assert_no_error (error);
}
for (i = 0; i < G_N_ELEMENTS (prepare_files); i++)
{
const char *it = prepare_files[i];
glnx_file_replace_contents_at (tmpdir.fd, it,
(guint8 *) "hello", 5,
0, NULL, &error);
g_assert_no_error (error);
}
for (i = 0; i < G_N_ELEMENTS (prepare_symlinks); i++)
{
const Symlink *it = &prepare_symlinks[i];
......@@ -221,6 +250,12 @@ test_resolve_in_sysroot (Fixture *f,
if (it->call.flags & SRT_RESOLVE_FLAGS_REJECT_SYMLINKS)
g_string_append (description, " (not following any symlink)");
if (it->call.flags & SRT_RESOLVE_FLAGS_DIRECTORY)
g_string_append (description, " (must be a directory)");
if (it->call.flags & SRT_RESOLVE_FLAGS_READABLE)
g_string_append (description, " (open for reading)");
g_test_message ("%" G_GSIZE_FORMAT ": Resolving %s%s",
i, it->call.path, description->str);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment