diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-06-02 16:01:40 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-06-04 12:21:19 +0200 |
commit | 1e472a6ce4747a1f10954fb239df73580c8e7411 (patch) | |
tree | e513d195ef02c9c0b67a453911a878065c4398fa | |
parent | 16eff8271b402f2705d4329fa4cf5a0435e65996 (diff) | |
download | systemd-1e472a6ce4747a1f10954fb239df73580c8e7411.tar.gz |
basic/glob-util: add helper to strip the glob part from a glob
-rw-r--r-- | src/basic/glob-util.c | 19 | ||||
-rw-r--r-- | src/basic/glob-util.h | 2 | ||||
-rw-r--r-- | src/test/test-glob-util.c | 28 |
3 files changed, 49 insertions, 0 deletions
diff --git a/src/basic/glob-util.c b/src/basic/glob-util.c index bc0278e57f..e026b29478 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 d2f8718d5a..fc86e990dd 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 df6444c433..50b4924679 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; } |