--- glob.c-bsd Wed Oct 17 20:33:39 2012 +++ glob.c-ill Wed Oct 31 09:06:10 2012 @@ -1,3 +1,28 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2012 Gary Mills + */ + /* $OpenBSD: glob.c,v 1.39 2012/01/20 07:09:42 tedu Exp $ */ /* * Copyright (c) 1989, 1993 @@ -148,19 +173,24 @@ static Char *g_strchr(const Char *, int); static int g_strncmp(const Char *, const char *, size_t); static int g_stat(Char *, struct stat *, glob_t *); -static int glob0(const Char *, glob_t *, struct glob_lim *); -static int glob1(Char *, Char *, glob_t *, struct glob_lim *); +static int glob0(const Char *, glob_t *, struct glob_lim *, + int (*)(const char *, int)); +static int glob1(Char *, Char *, glob_t *, struct glob_lim *, + int (*)(const char *, int)); static int glob2(Char *, Char *, Char *, Char *, Char *, Char *, - glob_t *, struct glob_lim *); + glob_t *, struct glob_lim *, + int (*)(const char *, int)); static int glob3(Char *, Char *, Char *, Char *, Char *, - Char *, Char *, glob_t *, struct glob_lim *); + Char *, Char *, glob_t *, struct glob_lim *, + int (*)(const char *, int)); static int globextend(const Char *, glob_t *, struct glob_lim *, struct stat *); static const Char * globtilde(const Char *, Char *, size_t, glob_t *); -static int globexp1(const Char *, glob_t *, struct glob_lim *); +static int globexp1(const Char *, glob_t *, struct glob_lim *, + int (*)(const char *, int)); static int globexp2(const Char *, const Char *, glob_t *, - struct glob_lim *); + struct glob_lim *, int (*)(const char *, int)); static int match(Char *, Char *, Char *, int); #ifdef DEBUG static void qprintf(const char *, Char *); @@ -182,12 +212,12 @@ if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; - pglob->gl_statv = NULL; + if ((flags & GLOB_KEEPSTAT) != 0) + pglob->gl_statv = NULL; if (!(flags & GLOB_DOOFFS)) pglob->gl_offs = 0; } pglob->gl_flags = flags & ~GLOB_MAGCHAR; - pglob->gl_errfunc = errfunc; pglob->gl_matchc = 0; if (pglob->gl_offs < 0 || pglob->gl_pathc < 0 || @@ -215,9 +245,9 @@ *bufnext = EOS; if (flags & GLOB_BRACE) - return globexp1(patbuf, pglob, &limit); + return globexp1(patbuf, pglob, &limit, errfunc); else - return glob0(patbuf, pglob, &limit); + return glob0(patbuf, pglob, &limit, errfunc); } /* @@ -226,18 +256,19 @@ * characters */ static int -globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) +globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp, + int (*errfunc)(const char *, int)) { const Char* ptr = pattern; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) - return glob0(pattern, pglob, limitp); + return glob0(pattern, pglob, limitp, errfunc); if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL) - return globexp2(ptr, pattern, pglob, limitp); + return globexp2(ptr, pattern, pglob, limitp, errfunc); - return glob0(pattern, pglob, limitp); + return glob0(pattern, pglob, limitp, errfunc); } @@ -248,7 +279,7 @@ */ static int globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, - struct glob_lim *limitp) + struct glob_lim *limitp, int (*errfunc)(const char *, int)) { int i, rv; Char *lm, *ls; @@ -284,7 +315,7 @@ /* Non matching braces; just glob the pattern */ if (i != 0 || *pe == EOS) - return glob0(patbuf, pglob, limitp); + return glob0(patbuf, pglob, limitp, errfunc); for (i = 0, pl = pm = ptr; pm <= pe; pm++) { switch (*pm) { @@ -330,7 +361,7 @@ #ifdef DEBUG qprintf("globexp2:", patbuf); #endif - rv = globexp1(patbuf, pglob, limitp); + rv = globexp1(patbuf, pglob, limitp, errfunc); if (rv && rv != GLOB_NOMATCH) return rv; @@ -458,7 +489,8 @@ * to find no matches. */ static int -glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) +glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp, + int (*errfunc)(const char *, int)) { const Char *qpatnext; int c, err, oldpathc; @@ -534,7 +566,8 @@ qprintf("glob0:", patbuf); #endif - if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp)) != 0) + if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp, errfunc)) + != 0) return(err); /* @@ -596,7 +629,8 @@ } static int -glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) +glob1(Char *pattern, Char *pattern_last, glob_t *pglob, + struct glob_lim *limitp, int (*errfunc)(const char *, int)) { Char pathbuf[MAXPATHLEN]; @@ -605,7 +639,7 @@ return(0); return(glob2(pathbuf, pathbuf+MAXPATHLEN-1, pathbuf, pathbuf+MAXPATHLEN-1, - pattern, pattern_last, pglob, limitp)); + pattern, pattern_last, pglob, limitp, errfunc)); } /* @@ -615,7 +649,8 @@ */ static int glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, - Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) + Char *pattern, Char *pattern_last, glob_t *pglob, + struct glob_lim *limitp, int (*errfunc)(const char *, int)) { struct stat sb; Char *p, *q; @@ -676,7 +711,7 @@ /* Need expansion, recurse. */ return(glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, p, pattern_last, - pglob, limitp)); + pglob, limitp, errfunc)); } /* NOTREACHED */ } @@ -684,21 +719,14 @@ static int glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob, - struct glob_lim *limitp) + struct glob_lim *limitp, int (*errfunc)(const char *, int)) { struct dirent *dp; DIR *dirp; int err; char buf[MAXPATHLEN]; + struct dirent *(*readdirfunc)(DIR *); - /* - * The readdirfunc declaration can't be prototyped, because it is - * assigned, below, to two functions which are prototyped in glob.h - * and dirent.h as taking pointers to differently typed opaque - * structures. - */ - struct dirent *(*readdirfunc)(void *); - if (pathend > pathend_last) return (1); *pathend = EOS; @@ -706,10 +734,10 @@ if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { /* TODO: don't call for ENOENT or ENOTDIR? */ - if (pglob->gl_errfunc) { + if (errfunc) { if (g_Ctoc(pathbuf, buf, sizeof(buf))) return(GLOB_ABORTED); - if (pglob->gl_errfunc(buf, errno) || + if (errfunc(buf, errno) || pglob->gl_flags & GLOB_ERR) return(GLOB_ABORTED); } @@ -722,7 +750,7 @@ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = pglob->gl_readdir; else - readdirfunc = (struct dirent *(*)(void *))readdir; + readdirfunc = readdir; while ((dp = (*readdirfunc)(dirp))) { u_char *sc; Char *dc; @@ -754,7 +782,8 @@ continue; } err = glob2(pathbuf, pathbuf_last, --dc, pathend_last, - restpattern, restpattern_last, pglob, limitp); + restpattern, restpattern_last, pglob, limitp, + errfunc); if (err) break; } @@ -810,7 +839,8 @@ free(pglob->gl_pathv); pglob->gl_pathv = NULL; } - if (pglob->gl_statv) { + if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 && + pglob->gl_statv) { free(pglob->gl_statv); pglob->gl_statv = NULL; } @@ -959,7 +989,8 @@ free(pglob->gl_pathv); pglob->gl_pathv = NULL; } - if (pglob->gl_statv != NULL) { + if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 && + pglob->gl_statv != NULL) { for (i = 0; i < pglob->gl_pathc; i++) { if (pglob->gl_statv[i] != NULL) free(pglob->gl_statv[i]);