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