glob: add glob_first(), returns first match

Note that which match is returned depends on the system and is
not guaranteed to be stable
This commit is contained in:
Luca Boccassi
2022-08-03 14:20:41 +01:00
parent d4f38ff036
commit f52faaf923
3 changed files with 37 additions and 3 deletions

View File

@@ -47,17 +47,28 @@ int safe_glob(const char *path, int flags, glob_t *pglob) {
return 0;
}
int glob_exists(const char *path) {
int glob_first(const char *path, char **ret_first) {
_cleanup_globfree_ glob_t g = {};
int k;
assert(path);
k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
if (k == -ENOENT)
if (k == -ENOENT) {
if (ret_first)
*ret_first = NULL;
return false;
}
if (k < 0)
return k;
if (ret_first) {
char *first = strdup(g.gl_pathv[0]);
if (!first)
return log_oom_debug();
*ret_first = first;
}
return true;
}

View File

@@ -10,7 +10,9 @@
/* Note: this function modifies pglob to set various functions. */
int safe_glob(const char *path, int flags, glob_t *pglob);
int glob_exists(const char *path);
/* Note: which match is returned depends on the implementation/system and not guaranteed to be stable */
int glob_first(const char *path, char **ret_first);
#define glob_exists(path) glob_first(path, NULL)
int glob_extend(char ***strv, const char *path, int flags);
int glob_non_glob_prefix(const char *path, char **ret);

View File

@@ -13,6 +13,27 @@
#include "tests.h"
#include "tmpfile-util.h"
TEST(glob_first) {
char *first, name[] = "/tmp/test-glob_first.XXXXXX";
int fd = -1;
int r;
fd = mkostemp_safe(name);
assert_se(fd >= 0);
close(fd);
r = glob_first("/tmp/test-glob_first*", &first);
assert_se(r == 1);
assert_se(streq(name, first));
first = mfree(first);
r = unlink(name);
assert_se(r == 0);
r = glob_first("/tmp/test-glob_first*", &first);
assert_se(r == 0);
assert_se(first == NULL);
}
TEST(glob_exists) {
char name[] = "/tmp/test-glob_exists.XXXXXX";
int fd = -1;