path-util: add helper that checks if a path definitely refers to a dir

This commit is contained in:
Lennart Poettering 2024-03-13 23:17:11 +01:00
parent 478dc50266
commit dd92ba8a7a
3 changed files with 40 additions and 0 deletions

View file

@ -1336,6 +1336,20 @@ bool dot_or_dot_dot(const char *path) {
return path[2] == 0;
}
bool path_implies_directory(const char *path) {
/* Sometimes, if we look at a path we already know it must refer to a directory, because it is
* suffixed with a slash, or its last component is "." or ".." */
if (!path)
return false;
if (dot_or_dot_dot(path))
return true;
return ENDSWITH_SET(path, "/", "/.", "/..");
}
bool empty_or_root(const char *path) {
/* For operations relative to some root directory, returns true if the specified root directory is

View file

@ -201,6 +201,8 @@ bool valid_device_allow_pattern(const char *path);
bool dot_or_dot_dot(const char *path);
bool path_implies_directory(const char *path);
static inline const char *skip_dev_prefix(const char *p) {
const char *e;

View file

@ -1305,4 +1305,28 @@ TEST(print_MAX) {
assert_cc(FILENAME_MAX == PATH_MAX);
}
TEST(path_implies_directory) {
assert_se(!path_implies_directory(NULL));
assert_se(!path_implies_directory(""));
assert_se(path_implies_directory("/"));
assert_se(path_implies_directory("////"));
assert_se(path_implies_directory("////.///"));
assert_se(path_implies_directory("////./"));
assert_se(path_implies_directory("////."));
assert_se(path_implies_directory("."));
assert_se(path_implies_directory("./"));
assert_se(path_implies_directory("/."));
assert_se(path_implies_directory(".."));
assert_se(path_implies_directory("../"));
assert_se(path_implies_directory("/.."));
assert_se(!path_implies_directory("a"));
assert_se(!path_implies_directory("ab"));
assert_se(path_implies_directory("ab/"));
assert_se(!path_implies_directory("ab/a"));
assert_se(path_implies_directory("ab/a/"));
assert_se(path_implies_directory("ab/a/.."));
assert_se(path_implies_directory("ab/a/."));
assert_se(path_implies_directory("ab/a//"));
}
DEFINE_TEST_MAIN(LOG_DEBUG);