Omit differences from glibc when the differences don’t matter. * lib/glob.c [_LIBC]: Include shlib-compat.h. (__glob) [!_LIBC]: New macro. All uses of glob changed to __glob. (glob_lstat): New function. (glob_in_dir): Use it. (GLOB_ATTRIBUTE): Define to empty if not already defined. Use changed. --- ChangeLog | 11 +++++++++ lib/glob.c | 68 ++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 54 insertions(+), 25 deletions(-)
diff --git a/ChangeLog b/ChangeLog index 5c8eed1cc..726423133 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2019-11-18 Paul Eggert <egg...@cs.ucla.edu> + + glob: get closer to glibc glob.c + Omit differences from glibc when the differences don’t matter. + * lib/glob.c [_LIBC]: Include shlib-compat.h. + (__glob) [!_LIBC]: New macro. All uses of glob changed to __glob. + (glob_lstat): New function. + (glob_in_dir): Use it. + (GLOB_ATTRIBUTE): Define to empty if not already defined. + Use changed. + 2019-11-18 Bruno Haible <br...@clisp.org> stdint: Define [u]intptr_t correctly on 64-bit native Windows. diff --git a/lib/glob.c b/lib/glob.c index 80233fdec..9ecc5150a 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -67,7 +67,9 @@ # endif # define struct_stat64 struct stat64 # define FLEXIBLE_ARRAY_MEMBER +# include <shlib-compat.h> #else /* !_LIBC */ +# define __glob glob # define __getlogin_r(buf, len) getlogin_r (buf, len) # define __lstat64(fname, buf) lstat (fname, buf) # define __stat64(fname, buf) stat (fname, buf) @@ -191,6 +193,29 @@ convert_dirent64 (const struct dirent64 *source) ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0) #endif +static int +glob_lstat (glob_t *pglob, int flags, const char *fullname) +{ +/* Use on glob-lstat-compat.c to provide a compat symbol which does not + use lstat / gl_lstat. */ +#ifdef GLOB_NO_LSTAT +# define GL_LSTAT gl_stat +# define LSTAT64 __stat64 +#else +# define GL_LSTAT gl_lstat +# define LSTAT64 __lstat64 +#endif + + union + { + struct stat st; + struct_stat64 st64; + } ust; + return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC) + ? pglob->GL_LSTAT (fullname, &ust.st) + : LSTAT64 (fullname, &ust.st64)); +} + /* Set *R = A + B. Return true if the answer is mathematically incorrect due to overflow; in this case, *R is the low order bits of the correct answer. */ @@ -257,6 +282,9 @@ next_brace_sub (const char *cp, int flags) return *cp != '\0' ? cp : NULL; } +#ifndef GLOB_ATTRIBUTE +# define GLOB_ATTRIBUTE +#endif /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. @@ -267,11 +295,9 @@ next_brace_sub (const char *cp, int flags) If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. Otherwise, 'glob' returns zero. */ int -#ifdef GLOB_ATTRIBUTE GLOB_ATTRIBUTE -#endif -glob (const char *pattern, int flags, int (*errfunc) (const char *, int), - glob_t *pglob) +__glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + glob_t *pglob) { const char *filename; char *dirname = NULL; @@ -415,9 +441,10 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), /* Construct the new glob expression. */ mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len); - result = glob (onealt, - ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC)) - | GLOB_APPEND), errfunc, pglob); + result = __glob (onealt, + ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC)) + | GLOB_APPEND), + errfunc, pglob); /* If we got an error, return it. */ if (result && result != GLOB_NOMATCH) @@ -508,7 +535,6 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { char *newp; dirlen = filename - pattern; - #if defined __MSDOS__ || defined WINDOWS32 if (*filename == ':' || (filename > pattern + 1 && filename[-1] == ':')) @@ -567,7 +593,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC); } } - int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob); + int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob); if (val == 0) pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK)); @@ -945,11 +971,10 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), dirs.gl_lstat = pglob->gl_lstat; } - status = glob (dirname, - ((flags & (GLOB_ERR | GLOB_NOESCAPE - | GLOB_ALTDIRFUNC)) - | GLOB_NOSORT | GLOB_ONLYDIR), - errfunc, &dirs); + status = __glob (dirname, + ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC)) + | GLOB_NOSORT | GLOB_ONLYDIR), + errfunc, &dirs); if (status != 0) { if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH) @@ -1147,8 +1172,9 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), return retval; } -#if defined _LIBC && !defined glob -libc_hidden_def (glob) +#if defined _LIBC && !defined __glob +versioned_symbol (libc, __glob, glob, GLIBC_2_27); +libc_hidden_ver (__glob, glob) #endif @@ -1264,11 +1290,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags, } else if (meta == GLOBPAT_NONE) { - union - { - struct stat st; - struct_stat64 st64; - } ust; size_t patlen = strlen (pattern); size_t fullsize; bool alloca_fullname @@ -1287,10 +1308,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), "/", 1), pattern, patlen + 1); - if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) - ? (*pglob->gl_lstat) (fullname, &ust.st) - : __lstat64 (fullname, &ust.st64)) - == 0) + if (glob_lstat (pglob, flags, fullname) == 0 || errno == EOVERFLOW) /* We found this file to be existing. Now tell the rest of the function to copy this name into the result. */ -- 2.23.0