mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
posix/glob.c: update from gnulib
Copied from gnulib/lib/glob.c in order to fix rhbz 1982608 Also fixes swbz 25659 Reviewed-by: Carlos O'Donell <carlos@redhat.com> Tested-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
70
posix/glob.c
70
posix/glob.c
@ -21,13 +21,14 @@
|
|||||||
optimizes away the pattern == NULL test below. */
|
optimizes away the pattern == NULL test below. */
|
||||||
# define _GL_ARG_NONNULL(params)
|
# define _GL_ARG_NONNULL(params)
|
||||||
|
|
||||||
# include <config.h>
|
# include <libc-config.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -56,6 +57,8 @@
|
|||||||
# define sysconf(id) __sysconf (id)
|
# define sysconf(id) __sysconf (id)
|
||||||
# define closedir(dir) __closedir (dir)
|
# define closedir(dir) __closedir (dir)
|
||||||
# define opendir(name) __opendir (name)
|
# define opendir(name) __opendir (name)
|
||||||
|
# undef dirfd
|
||||||
|
# define dirfd(str) __dirfd (str)
|
||||||
# define readdir(str) __readdir64 (str)
|
# define readdir(str) __readdir64 (str)
|
||||||
# define getpwnam_r(name, bufp, buf, len, res) \
|
# define getpwnam_r(name, bufp, buf, len, res) \
|
||||||
__getpwnam_r (name, bufp, buf, len, res)
|
__getpwnam_r (name, bufp, buf, len, res)
|
||||||
@ -69,11 +72,8 @@
|
|||||||
# ifndef GLOB_LSTAT
|
# ifndef GLOB_LSTAT
|
||||||
# define GLOB_LSTAT gl_lstat
|
# define GLOB_LSTAT gl_lstat
|
||||||
# endif
|
# endif
|
||||||
# ifndef GLOB_STAT64
|
# ifndef GLOB_FSTATAT64
|
||||||
# define GLOB_STAT64 __stat64
|
# define GLOB_FSTATAT64 __fstatat64
|
||||||
# endif
|
|
||||||
# ifndef GLOB_LSTAT64
|
|
||||||
# define GLOB_LSTAT64 __lstat64
|
|
||||||
# endif
|
# endif
|
||||||
# include <shlib-compat.h>
|
# include <shlib-compat.h>
|
||||||
#else /* !_LIBC */
|
#else /* !_LIBC */
|
||||||
@ -88,8 +88,7 @@
|
|||||||
# define struct_stat struct stat
|
# define struct_stat struct stat
|
||||||
# define struct_stat64 struct stat
|
# define struct_stat64 struct stat
|
||||||
# define GLOB_LSTAT gl_lstat
|
# define GLOB_LSTAT gl_lstat
|
||||||
# define GLOB_STAT64 stat
|
# define GLOB_FSTATAT64 fstatat
|
||||||
# define GLOB_LSTAT64 lstat
|
|
||||||
#endif /* _LIBC */
|
#endif /* _LIBC */
|
||||||
|
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
@ -215,7 +214,8 @@ glob_lstat (glob_t *pglob, int flags, const char *fullname)
|
|||||||
} ust;
|
} ust;
|
||||||
return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
|
return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
|
||||||
? pglob->GLOB_LSTAT (fullname, &ust.st)
|
? pglob->GLOB_LSTAT (fullname, &ust.st)
|
||||||
: GLOB_LSTAT64 (fullname, &ust.st64));
|
: GLOB_FSTATAT64 (AT_FDCWD, fullname, &ust.st64,
|
||||||
|
AT_SYMLINK_NOFOLLOW));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set *R = A + B. Return true if the answer is mathematically
|
/* Set *R = A + B. Return true if the answer is mathematically
|
||||||
@ -257,7 +257,8 @@ is_dir (char const *filename, int flags, glob_t const *pglob)
|
|||||||
struct_stat64 st64;
|
struct_stat64 st64;
|
||||||
return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
|
return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
|
||||||
? pglob->gl_stat (filename, &st) == 0 && S_ISDIR (st.st_mode)
|
? pglob->gl_stat (filename, &st) == 0 && S_ISDIR (st.st_mode)
|
||||||
: GLOB_STAT64 (filename, &st64) == 0 && S_ISDIR (st64.st_mode));
|
: (GLOB_FSTATAT64 (AT_FDCWD, filename, &st64, 0) == 0
|
||||||
|
&& S_ISDIR (st64.st_mode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the end of the sub-pattern in a brace expression. */
|
/* Find the end of the sub-pattern in a brace expression. */
|
||||||
@ -747,6 +748,8 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifndef WINDOWS32
|
#ifndef WINDOWS32
|
||||||
|
/* Recognize ~user as a shorthand for the specified user's home
|
||||||
|
directory. */
|
||||||
char *end_name = strchr (dirname, '/');
|
char *end_name = strchr (dirname, '/');
|
||||||
char *user_name;
|
char *user_name;
|
||||||
int malloc_user_name = 0;
|
int malloc_user_name = 0;
|
||||||
@ -885,7 +888,22 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
|
|||||||
}
|
}
|
||||||
scratch_buffer_free (&pwtmpbuf);
|
scratch_buffer_free (&pwtmpbuf);
|
||||||
}
|
}
|
||||||
#endif /* !WINDOWS32 */
|
#else /* WINDOWS32 */
|
||||||
|
/* On native Windows, access to a user's home directory
|
||||||
|
(via GetUserProfileDirectory) or to a user's environment
|
||||||
|
variables (via ExpandEnvironmentStringsForUser) requires
|
||||||
|
the credentials of the user. Therefore we cannot support
|
||||||
|
the ~user syntax on this platform.
|
||||||
|
Handling ~user specially (and treat it like plain ~) if
|
||||||
|
user is getenv ("USERNAME") would not be a good idea,
|
||||||
|
since it would make people think that ~user is supported
|
||||||
|
in general. */
|
||||||
|
if (flags & GLOB_TILDE_CHECK)
|
||||||
|
{
|
||||||
|
retval = GLOB_NOMATCH;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#endif /* WINDOWS32 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1266,6 +1284,8 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
|||||||
{
|
{
|
||||||
size_t dirlen = strlen (directory);
|
size_t dirlen = strlen (directory);
|
||||||
void *stream = NULL;
|
void *stream = NULL;
|
||||||
|
struct scratch_buffer s;
|
||||||
|
scratch_buffer_init (&s);
|
||||||
# define GLOBNAMES_MEMBERS(nnames) \
|
# define GLOBNAMES_MEMBERS(nnames) \
|
||||||
struct globnames *next; size_t count; char *name[nnames];
|
struct globnames *next; size_t count; char *name[nnames];
|
||||||
struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
|
struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
|
||||||
@ -1337,6 +1357,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int dfd = dirfd (stream);
|
||||||
int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
|
int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
|
||||||
| ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
|
| ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
|
||||||
flags |= GLOB_MAGCHAR;
|
flags |= GLOB_MAGCHAR;
|
||||||
@ -1364,8 +1385,32 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
|||||||
if (flags & GLOB_ONLYDIR)
|
if (flags & GLOB_ONLYDIR)
|
||||||
switch (readdir_result_type (d))
|
switch (readdir_result_type (d))
|
||||||
{
|
{
|
||||||
case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
|
|
||||||
default: continue;
|
default: continue;
|
||||||
|
case DT_DIR: break;
|
||||||
|
case DT_LNK: case DT_UNKNOWN:
|
||||||
|
/* The filesystem was too lazy to give us a hint,
|
||||||
|
so we have to do it the hard way. */
|
||||||
|
if (__glibc_unlikely (dfd < 0 || flags & GLOB_ALTDIRFUNC))
|
||||||
|
{
|
||||||
|
size_t namelen = strlen (d.name);
|
||||||
|
size_t need = dirlen + 1 + namelen + 1;
|
||||||
|
if (s.length < need
|
||||||
|
&& !scratch_buffer_set_array_size (&s, need, 1))
|
||||||
|
goto memory_error;
|
||||||
|
char *p = mempcpy (s.data, directory, dirlen);
|
||||||
|
*p = '/';
|
||||||
|
p += p[-1] != '/';
|
||||||
|
memcpy (p, d.name, namelen + 1);
|
||||||
|
if (! is_dir (s.data, flags, pglob))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct_stat64 st64;
|
||||||
|
if (! (GLOB_FSTATAT64 (dfd, d.name, &st64, 0) == 0
|
||||||
|
&& S_ISDIR (st64.st_mode)))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fnmatch (pattern, d.name, fnm_flags) == 0)
|
if (fnmatch (pattern, d.name, fnm_flags) == 0)
|
||||||
@ -1497,5 +1542,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
|||||||
__set_errno (save);
|
__set_errno (save);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scratch_buffer_free (&s);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
# define GLOB_LSTAT gl_lstat
|
# define GLOB_LSTAT gl_lstat
|
||||||
# define GLOB_STAT64 __stat64_time64
|
# define GLOB_STAT64 __stat64_time64
|
||||||
# define GLOB_LSTAT64 __lstat64_time64
|
# define GLOB_LSTAT64 __lstat64_time64
|
||||||
|
# define GLOB_FSTATAT64 __fstatat64_time64
|
||||||
|
|
||||||
# define COMPILE_GLOB64 1
|
# define COMPILE_GLOB64 1
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user