From: Lennart Poettering Date: Wed, 13 Mar 2024 22:17:11 +0000 (+0100) Subject: path-util: add helper that checks if a path definitely refers to a dir X-Git-Tag: v256-rc1~531^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd92ba8a7a69016116e14d309829efff1e3c3d34;p=thirdparty%2Fsystemd.git path-util: add helper that checks if a path definitely refers to a dir --- diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 6810bf66aa3..05a21f8f8e2 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -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 diff --git a/src/basic/path-util.h b/src/basic/path-util.h index 39b6714525e..052bbd7031b 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -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; diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index f5a425689a3..ca11bf3a29c 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -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);