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;
+}
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) {
#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;
int r;
+ log_info("/* %s */", __func__);
+
assert_se(mkdtemp(template));
fn = strjoina(template, "/*");
_cleanup_globfree_ glob_t g = {};
int r;
+ log_info("/* %s */", __func__);
+
assert_se(mkdtemp(template));
fn = strjoina(template, "/*");
(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;
}