From 1e472a6ce4747a1f10954fb239df73580c8e7411 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 2 Jun 2021 16:01:40 +0200 Subject: [PATCH] basic/glob-util: add helper to strip the glob part from a glob --- src/basic/glob-util.c | 19 +++++++++++++++++++ src/basic/glob-util.h | 2 ++ src/test/test-glob-util.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/src/basic/glob-util.c b/src/basic/glob-util.c index bc0278e57f5..e026b29478e 100644 --- a/src/basic/glob-util.c +++ b/src/basic/glob-util.c @@ -71,3 +71,22 @@ int glob_extend(char ***strv, const char *path, int flags) { return strv_extend_strv(strv, g.gl_pathv, false); } + +int glob_non_glob_prefix(const char *path, char **ret) { + /* Return the path of the path that has no glob characters. */ + + size_t n = strcspn(path, GLOB_CHARS); + + if (path[n] != '\0') + while (n > 0 && path[n-1] != '/') + n--; + + if (n == 0) + return -ENOENT; + + char *ans = strndup(path, n); + if (!ans) + return -ENOMEM; + *ret = ans; + return 0; +} diff --git a/src/basic/glob-util.h b/src/basic/glob-util.h index d2f8718d5a8..fc86e990dd7 100644 --- a/src/basic/glob-util.h +++ b/src/basic/glob-util.h @@ -13,6 +13,8 @@ int safe_glob(const char *path, int flags, glob_t *pglob); int glob_exists(const char *path); int glob_extend(char ***strv, const char *path, int flags); +int glob_non_glob_prefix(const char *path, char **ret); + #define _cleanup_globfree_ _cleanup_(globfree) _pure_ static inline bool string_is_glob(const char *p) { diff --git a/src/test/test-glob-util.c b/src/test/test-glob-util.c index df6444c4338..50b49246791 100644 --- a/src/test/test-glob-util.c +++ b/src/test/test-glob-util.c @@ -13,6 +13,8 @@ #include "tmpfile-util.h" static void test_glob_exists(void) { + log_info("/* %s */", __func__); + char name[] = "/tmp/test-glob_exists.XXXXXX"; int fd = -1; int r; @@ -48,6 +50,8 @@ static void test_glob_no_dot(void) { int r; + log_info("/* %s */", __func__); + assert_se(mkdtemp(template)); fn = strjoina(template, "/*"); @@ -68,6 +72,8 @@ static void test_safe_glob(void) { _cleanup_globfree_ glob_t g = {}; int r; + log_info("/* %s */", __func__); + assert_se(mkdtemp(template)); fn = strjoina(template, "/*"); @@ -93,10 +99,32 @@ static void test_safe_glob(void) { (void) rm_rf(template, REMOVE_ROOT|REMOVE_PHYSICAL); } +static void test_glob_non_glob_prefix_one(const char *path, const char *expected) { + _cleanup_free_ char *t; + + assert_se(glob_non_glob_prefix(path, &t) == 0); + assert_se(streq(t, expected)); +} + +static void test_glob_non_glob(void) { + log_info("/* %s */", __func__); + + test_glob_non_glob_prefix_one("/tmp/.X11-*", "/tmp/"); + test_glob_non_glob_prefix_one("/tmp/*", "/tmp/"); + test_glob_non_glob_prefix_one("/tmp*", "/"); + test_glob_non_glob_prefix_one("/tmp/*/whatever", "/tmp/"); + test_glob_non_glob_prefix_one("/tmp/*/whatever?", "/tmp/"); + test_glob_non_glob_prefix_one("/?", "/"); + + char *x; + assert_se(glob_non_glob_prefix("?", &x) == -ENOENT); +} + int main(void) { test_glob_exists(); test_glob_no_dot(); test_safe_glob(); + test_glob_non_glob(); return 0; } -- 2.47.3