]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/glob-util.c
tree-wide: drop dirent.h when dirent-util.h is included
[thirdparty/systemd.git] / src / basic / glob-util.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
7d50b32a 2
11c3a366 3#include <errno.h>
7d50b32a 4#include <glob.h>
48d7c648 5#include <sys/types.h>
ca78ad1d
ZJS
6#include <sys/stat.h>
7#include <unistd.h>
7d50b32a 8
48d7c648 9#include "dirent-util.h"
66855de7 10#include "errno-util.h"
7d50b32a 11#include "glob-util.h"
11c3a366 12#include "macro.h"
48d7c648 13#include "path-util.h"
7d50b32a 14#include "strv.h"
7d50b32a 15
46dcfbbd 16static void closedir_wrapper(void* v) {
1fe10174
ZJS
17 (void) closedir(v);
18}
19
48d7c648 20int safe_glob(const char *path, int flags, glob_t *pglob) {
7d50b32a
LP
21 int k;
22
48d7c648
ZJS
23 /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */
24 assert(!(flags & GLOB_ALTDIRFUNC));
25
26 if (!pglob->gl_closedir)
46dcfbbd 27 pglob->gl_closedir = closedir_wrapper;
48d7c648
ZJS
28 if (!pglob->gl_readdir)
29 pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot;
30 if (!pglob->gl_opendir)
31 pglob->gl_opendir = (void *(*)(const char *)) opendir;
32 if (!pglob->gl_lstat)
33 pglob->gl_lstat = lstat;
34 if (!pglob->gl_stat)
35 pglob->gl_stat = stat;
7d50b32a
LP
36
37 errno = 0;
48d7c648 38 k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob);
7d50b32a 39 if (k == GLOB_NOMATCH)
48d7c648 40 return -ENOENT;
7d50b32a
LP
41 if (k == GLOB_NOSPACE)
42 return -ENOMEM;
43 if (k != 0)
66855de7 44 return errno_or_else(EIO);
48d7c648
ZJS
45 if (strv_isempty(pglob->gl_pathv))
46 return -ENOENT;
7d50b32a 47
48d7c648 48 return 0;
7d50b32a
LP
49}
50
48d7c648 51int glob_exists(const char *path) {
7d50b32a
LP
52 _cleanup_globfree_ glob_t g = {};
53 int k;
7d50b32a 54
48d7c648 55 assert(path);
7d50b32a 56
48d7c648
ZJS
57 k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
58 if (k == -ENOENT)
59 return false;
60 if (k < 0)
61 return k;
62 return true;
63}
64
65int glob_extend(char ***strv, const char *path) {
66 _cleanup_globfree_ glob_t g = {};
67 int k;
7d50b32a 68
48d7c648
ZJS
69 k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
70 if (k < 0)
71 return k;
7d50b32a 72
48d7c648 73 return strv_extend_strv(strv, g.gl_pathv, false);
7d50b32a 74}