1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
8 #include "dirent-util.h"
9 #include "errno-util.h"
10 #include "glob-util.h"
12 #include "path-util.h"
15 static void closedir_wrapper(void* v
) {
19 int safe_glob(const char *path
, int flags
, glob_t
*pglob
) {
22 /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */
23 assert(!(flags
& GLOB_ALTDIRFUNC
));
25 if (!pglob
->gl_closedir
)
26 pglob
->gl_closedir
= closedir_wrapper
;
27 if (!pglob
->gl_readdir
)
28 pglob
->gl_readdir
= (struct dirent
*(*)(void *)) readdir_no_dot
;
29 if (!pglob
->gl_opendir
)
30 pglob
->gl_opendir
= (void *(*)(const char *)) opendir
;
32 pglob
->gl_lstat
= lstat
;
34 pglob
->gl_stat
= stat
;
37 k
= glob(path
, flags
| GLOB_ALTDIRFUNC
, NULL
, pglob
);
38 if (k
== GLOB_NOMATCH
)
40 if (k
== GLOB_NOSPACE
)
43 return errno_or_else(EIO
);
44 if (strv_isempty(pglob
->gl_pathv
))
50 int glob_exists(const char *path
) {
51 _cleanup_globfree_ glob_t g
= {};
56 k
= safe_glob(path
, GLOB_NOSORT
|GLOB_BRACE
, &g
);
64 int glob_extend(char ***strv
, const char *path
, int flags
) {
65 _cleanup_globfree_ glob_t g
= {};
68 k
= safe_glob(path
, GLOB_NOSORT
|GLOB_BRACE
|flags
, &g
);
72 return strv_extend_strv(strv
, g
.gl_pathv
, false);
75 int glob_non_glob_prefix(const char *path
, char **ret
) {
76 /* Return the path of the path that has no glob characters. */
78 size_t n
= strcspn(path
, GLOB_CHARS
);
81 while (n
> 0 && path
[n
-1] != '/')
87 char *ans
= strndup(path
, n
);