public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: DJ Delorie <dj@redhat.com>, libc-alpha@sourceware.org
Subject: Re: posix/glob.c: update from gnulib
Date: Thu, 31 Mar 2022 07:56:29 -0300	[thread overview]
Message-ID: <df2df290-0035-1e0a-3331-5ed3244629f5@linaro.org> (raw)
In-Reply-To: <xn4k3fw1f0.fsf@greed.delorie.com>



On 30/03/2022 18:55, DJ Delorie via Libc-alpha wrote:
> 
> Copied from gnulib/lib/glob.c in order to fix rhbz 1982608
> 
> Used config.h instead of libc-config.h
> 
> The #ifdef around #define dirfd() was changed to #undef due to
> conflicts between glibc's internal and external definitions of
> dirfd().  This has been reported to gnulib.


Could you create a bug report to track this? If I recall correctly from
gnulib discussion, this came from an issue with XFS. Would be possible
to craft a regression test?


> 
> diff --git a/posix/glob.c b/posix/glob.c
> index a2b5aabada..19b876f9f0 100644
> --- a/posix/glob.c
> +++ b/posix/glob.c
> @@ -28,6 +28,7 @@
>  #include <glob.h>
>  
>  #include <errno.h>
> +#include <fcntl.h>
>  #include <sys/types.h>
>  #include <sys/stat.h>
>  #include <stdbool.h>
> @@ -56,6 +57,8 @@
>  # define sysconf(id) __sysconf (id)
>  # define closedir(dir) __closedir (dir)
>  # define opendir(name) __opendir (name)
> +# undef dirfd
> +# define dirfd(str) __dirfd (str)
>  # define readdir(str) __readdir64 (str)
>  # define getpwnam_r(name, bufp, buf, len, res) \
>      __getpwnam_r (name, bufp, buf, len, res)
> @@ -69,11 +72,8 @@
>  # ifndef GLOB_LSTAT
>  #  define GLOB_LSTAT            gl_lstat
>  # endif
> -# ifndef GLOB_STAT64
> -#  define GLOB_STAT64           __stat64
> -# endif
> -# ifndef GLOB_LSTAT64
> -#  define GLOB_LSTAT64          __lstat64
> +# ifndef GLOB_FSTATAT64
> +#  define GLOB_FSTATAT64        __fstatat64
>  # endif
>  # include <shlib-compat.h>
>  #else /* !_LIBC */
> @@ -88,8 +88,7 @@
>  # define struct_stat            struct stat
>  # define struct_stat64          struct stat
>  # define GLOB_LSTAT             gl_lstat
> -# define GLOB_STAT64            stat
> -# define GLOB_LSTAT64           lstat
> +# define GLOB_FSTATAT64         fstatat
>  #endif /* _LIBC */
>  
>  #include <fnmatch.h>
> @@ -215,7 +214,8 @@ glob_lstat (glob_t *pglob, int flags, const char *fullname)
>    } ust;
>    return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
>            ? 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
> @@ -257,7 +257,8 @@ is_dir (char const *filename, int flags, glob_t const *pglob)
>    struct_stat64 st64;
>    return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
>            ? 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.  */
> @@ -747,6 +748,8 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
>        else
>          {
>  #ifndef WINDOWS32
> +          /* Recognize ~user as a shorthand for the specified user's home
> +             directory.  */
>            char *end_name = strchr (dirname, '/');
>            char *user_name;
>            int malloc_user_name = 0;
> @@ -885,7 +888,22 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
>                }
>              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);
>    void *stream = NULL;
> +  struct scratch_buffer s;
> +  scratch_buffer_init (&s);
>  # define GLOBNAMES_MEMBERS(nnames) \
>      struct globnames *next; size_t count; char *name[nnames];
>    struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
> @@ -1337,6 +1357,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
>          }
>        else
>          {
> +          int dfd = dirfd (stream);
>            int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
>                             | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
>            flags |= GLOB_MAGCHAR;
> @@ -1364,8 +1385,32 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
>                if (flags & GLOB_ONLYDIR)
>                  switch (readdir_result_type (d))
>                    {
> -                  case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
>                    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)
> @@ -1497,5 +1542,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
>        __set_errno (save);
>      }
>  
> +  scratch_buffer_free (&s);
>    return result;
>  }
> 

  parent reply	other threads:[~2022-03-31 10:56 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-30 21:55 DJ Delorie
2022-03-30 23:40 ` Paul Eggert
2022-03-30 23:45   ` Paul Eggert
2022-03-30 23:54   ` DJ Delorie
2022-03-31 10:56 ` Adhemerval Zanella [this message]
2022-03-31 17:38   ` DJ Delorie
2022-03-31 17:44     ` Adhemerval Zanella
2022-03-31 19:29       ` DJ Delorie
2022-03-31 19:38         ` Adhemerval Zanella
2022-03-31 20:00       ` [v2] " DJ Delorie
2022-04-01  1:55         ` Paul Eggert
2022-04-04 21:25           ` Carlos O'Donell
2022-04-14 23:40             ` [v3] " DJ Delorie
2022-04-27 21:16               ` Carlos O'Donell
2022-04-27 21:21                 ` DJ Delorie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=df2df290-0035-1e0a-3331-5ed3244629f5@linaro.org \
    --to=adhemerval.zanella@linaro.org \
    --cc=dj@redhat.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).