]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/glob-util: add helper to strip the glob part from a glob
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 2 Jun 2021 14:01:40 +0000 (16:01 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 4 Jun 2021 10:21:19 +0000 (12:21 +0200)
src/basic/glob-util.c
src/basic/glob-util.h
src/test/test-glob-util.c

index bc0278e57f5d491052e84f73c7bdb602766ba98f..e026b29478e2fae333040429743711d426a98aa5 100644 (file)
@@ -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;
+}
index d2f8718d5a800b327546fb7e54e4814b476d1459..fc86e990dd74979014a2b353311f1e8fec9f3554 100644 (file)
@@ -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) {
index df6444c43384c3e8954114cb80691089b5f1447c..50b492467915eb09216c4b82cf639d1073bd503f 100644 (file)
@@ -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;
 }