|
Message-Id: <20190730200114.21078-1-ismael@iodev.co.uk> Date: Tue, 30 Jul 2019 22:01:14 +0200 From: Ismael Luceno <ismael@...ev.co.uk> To: musl@...ts.openwall.com Cc: Ismael Luceno <ismael@...ev.co.uk> Subject: [RFC PATCH] glob: implement GLOB_ALTDIRFUNC et al Signed-off-by: Ismael Luceno <ismael@...ev.co.uk> --- include/glob.h | 8 +++++++- src/regex/glob.c | 31 ++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/include/glob.h b/include/glob.h index 0ff70bdfeef2..0db4780f6a00 100644 --- a/include/glob.h +++ b/include/glob.h @@ -16,7 +16,12 @@ typedef struct { char **gl_pathv; size_t gl_offs; int __dummy1; - void *__dummy2[5]; + + void (*gl_closedir)(void *); + struct dirent *(*gl_readdir)(void *); + void *(*gl_opendir)(const char *); + int (*gl_lstat)(const char *__restrict, struct stat *__restrict); + int (*gl_stat)(const char *__restrict, struct stat *__restrict); } glob_t; int glob(const char *__restrict, int, int (*)(const char *, int), glob_t *__restrict); @@ -31,6 +36,7 @@ void globfree(glob_t *); #define GLOB_NOESCAPE 0x40 #define GLOB_PERIOD 0x80 +#define GLOB_ALTDIRFUNC 0x0200 #define GLOB_NOMAGIC 0x0800 #define GLOB_TILDE 0x1000 #define GLOB_TILDE_CHECK 0x4000 diff --git a/src/regex/glob.c b/src/regex/glob.c index 0ccd9759c5e7..a79454223236 100644 --- a/src/regex/glob.c +++ b/src/regex/glob.c @@ -1,7 +1,7 @@ #define _BSD_SOURCE +#include <sys/stat.h> #include <glob.h> #include <fnmatch.h> -#include <sys/stat.h> #include <dirent.h> #include <limits.h> #include <string.h> @@ -32,7 +32,7 @@ static int append(struct match **tail, const char *name, size_t len, int mark) return 0; } -static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (*errfunc)(const char *path, int err), struct match **tail) +static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (*errfunc)(const char *path, int err), glob_t *restrict g, struct match **tail) { /* If GLOB_MARK is unused, we don't care about type. */ if (!type && !(flags & GLOB_MARK)) type = DT_REG; @@ -96,7 +96,7 @@ static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (* * determine its type. */ struct stat st; if ((flags & GLOB_MARK) && type==DT_LNK) type = 0; - if (!type && stat(buf, &st)) { + if (!type && g->gl_stat(buf, &st)) { if (errno!=ENOENT && (errfunc(buf, errno) || (flags & GLOB_ERR))) return GLOB_ABORTED; return 0; @@ -117,7 +117,7 @@ static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (* saved_sep = '\\'; } } - DIR *dir = opendir(pos ? buf : "."); + DIR *dir = g->gl_opendir(pos ? buf : "."); if (!dir) { if (errfunc(buf, errno) || (flags & GLOB_ERR)) return GLOB_ABORTED; @@ -125,7 +125,7 @@ static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (* } int old_errno = errno; struct dirent *de; - while (errno=0, de=readdir(dir)) { + while (errno=0, de=g->gl_readdir(dir)) { /* Quickly skip non-directories when there's pattern left. */ if (p2 && de->d_type && de->d_type!=DT_DIR && de->d_type!=DT_LNK) continue; @@ -150,15 +150,15 @@ static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (* memcpy(buf+pos, de->d_name, l+1); if (p2) *p2 = saved_sep; - int r = do_glob(buf, pos+l, de->d_type, p2 ? p2 : "", flags, errfunc, tail); + int r = do_glob(buf, pos+l, de->d_type, p2 ? p2 : "", flags, errfunc, g, tail); if (r) { - closedir(dir); + g->gl_closedir(dir); return r; } } int readerr = errno; if (p2) *p2 = saved_sep; - closedir(dir); + g->gl_closedir(dir); if (readerr && (errfunc(buf, errno) || (flags & GLOB_ERR))) return GLOB_ABORTED; errno = old_errno; @@ -217,6 +217,11 @@ static int expand_tilde(char **pat, char *buf, size_t *pos) return 0; } +static void __gl_closedir(void *p) +{ + closedir(p); +} + int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, int err), glob_t *restrict g) { struct match head = { .next = NULL }, *tail = &head; @@ -227,6 +232,14 @@ int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, i if (!errfunc) errfunc = ignore_err; + if (!(flags & GLOB_ALTDIRFUNC)) { + g->gl_opendir = (void *(*)(const char *))opendir; + g->gl_readdir = (struct dirent *(*)(void *))readdir; + g->gl_closedir = __gl_closedir; + g->gl_lstat = lstat; + g->gl_stat = stat; + } + if (!(flags & GLOB_APPEND)) { g->gl_offs = offs; g->gl_pathc = 0; @@ -242,7 +255,7 @@ int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, i if ((flags & (GLOB_TILDE | GLOB_TILDE_CHECK)) && *p == '~') error = expand_tilde(&s, buf, &pos); if (!error) - error = do_glob(buf, pos, 0, s, flags, errfunc, &tail); + error = do_glob(buf, pos, 0, s, flags, errfunc, g, &tail); free(p); } -- 2.22.0
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.