emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 42d5826 2/2: Update Gnulib.


From: Paul Eggert
Subject: master 42d5826 2/2: Update Gnulib.
Date: Fri, 25 Dec 2020 05:36:20 -0500 (EST)

branch: master
commit 42d58264db165d265cba68d6dbebc53a50738355
Author: Paul Eggert <eggert@cs.ucla.edu>
Commit: Paul Eggert <eggert@cs.ucla.edu>

    Update Gnulib.
    
    All changes in this commit are autogenerated by running
    admin/merge-gnulib.
---
 build-aux/config.guess  |   5 +-
 lib/canonicalize-lgpl.c | 213 +++++++++++++++++++++++++++++++++++-------------
 lib/careadlinkat.c      |  12 +--
 lib/eloop-threshold.h   |  83 +++++++++++++++++++
 lib/euidaccess.c        |   9 +-
 lib/faccessat.c         |  14 +++-
 lib/gnulib.mk.in        |  14 +++-
 lib/mini-gmp.c          |  58 +++++++------
 lib/mini-gmp.h          |   5 +-
 lib/symlink.c           |   2 +-
 m4/canonicalize.m4      |  10 ++-
 m4/faccessat.m4         |  33 +++++++-
 m4/gnulib-comp.m4       |  32 ++++----
 13 files changed, 369 insertions(+), 121 deletions(-)

diff --git a/build-aux/config.guess b/build-aux/config.guess
index 699b3a1..7f74817 100755
--- a/build-aux/config.guess
+++ b/build-aux/config.guess
@@ -2,7 +2,7 @@
 # Attempt to guess a canonical system name.
 #   Copyright 1992-2020 Free Software Foundation, Inc.
 
-timestamp='2020-11-19'
+timestamp='2020-12-22'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -996,6 +996,9 @@ EOF
     k1om:Linux:*:*)
        echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
+    loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+       exit ;;
     m32r*:Linux:*:*)
        echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index 584fce1..650d510 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 
 #include <errno.h>
+#include <fcntl.h>
 #include <limits.h>
 #include <stdbool.h>
 #include <stddef.h>
@@ -36,23 +37,26 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include <eloop-threshold.h>
+#include <filename.h>
+#include <idx.h>
 #include <scratch_buffer.h>
 
 #ifdef _LIBC
-# include <eloop-threshold.h>
 # include <shlib-compat.h>
-typedef ptrdiff_t idx_t;
-# define IDX_MAX PTRDIFF_MAX
-# define FILE_SYSTEM_PREFIX_LEN(name) 0
-# define IS_ABSOLUTE_FILE_NAME(name) ISSLASH(*(name))
-# define ISSLASH(c) ((c) == '/')
-# define freea(p) ((void) (p))
+# include <sysdep.h>
+# ifdef __ASSUME_FACCESSAT2
+#  define FACCESSAT_NEVER_EOVERFLOWS __ASSUME_FACCESSAT2
+# else
+#  define FACCESSAT_NEVER_EOVERFLOWS true
+# endif
+# define GCC_LINT 1
+# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
 #else
 # define __canonicalize_file_name canonicalize_file_name
 # define __realpath realpath
-# include "idx.h"
 # include "pathmax.h"
-# include "filename.h"
+# define __faccessat faccessat
 # if defined _WIN32 && !defined __CYGWIN__
 #  define __getcwd _getcwd
 # elif HAVE_GETCWD
@@ -77,22 +81,95 @@ typedef ptrdiff_t idx_t;
 # define __pathconf pathconf
 # define __rawmemchr rawmemchr
 # define __readlink readlink
-# ifndef MAXSYMLINKS
-#  ifdef SYMLOOP_MAX
-#   define MAXSYMLINKS SYMLOOP_MAX
-#  else
-#   define MAXSYMLINKS 20
-#  endif
-# endif
-# define __eloop_threshold() MAXSYMLINKS
+# define __stat stat
+#endif
+
+/* Suppress bogus GCC -Wmaybe-uninitialized warnings.  */
+#if defined GCC_LINT || defined lint
+# define IF_LINT(Code) Code
+#else
+# define IF_LINT(Code) /* empty */
 #endif
 
 #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
-# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
+# define DOUBLE_SLASH_IS_DISTINCT_ROOT false
+#endif
+#ifndef FACCESSAT_NEVER_EOVERFLOWS
+# define FACCESSAT_NEVER_EOVERFLOWS false
 #endif
 
 #if !FUNC_REALPATH_WORKS || defined _LIBC
 
+/* Return true if FILE's existence can be shown, false (setting errno)
+   otherwise.  Follow symbolic links.  */
+static bool
+file_accessible (char const *file)
+{
+# if defined _LIBC || HAVE_FACCESSAT
+  int r = __faccessat (AT_FDCWD, file, F_OK, AT_EACCESS);
+# else
+  struct stat st;
+  int r = __stat (file, &st);
+# endif
+
+  return ((!FACCESSAT_NEVER_EOVERFLOWS && r < 0 && errno == EOVERFLOW)
+          || r == 0);
+}
+
+/* True if concatenating END as a suffix to a file name means that the
+   code needs to check that the file name is that of a searchable
+   directory, since the canonicalize_filename_mode_stk code won't
+   check this later anyway when it checks an ordinary file name
+   component within END.  END must either be empty, or start with a
+   slash.  */
+
+static bool _GL_ATTRIBUTE_PURE
+suffix_requires_dir_check (char const *end)
+{
+  /* If END does not start with a slash, the suffix is OK.  */
+  while (ISSLASH (*end))
+    {
+      /* Two or more slashes act like a single slash.  */
+      do
+        end++;
+      while (ISSLASH (*end));
+
+      switch (*end++)
+        {
+        default: return false;  /* An ordinary file name component is OK.  */
+        case '\0': return true; /* Trailing "/" is trouble.  */
+        case '.': break;        /* Possibly "." or "..".  */
+        }
+      /* Trailing "/.", or "/.." even if not trailing, is trouble.  */
+      if (!*end || (*end == '.' && (!end[1] || ISSLASH (end[1]))))
+        return true;
+    }
+
+  return false;
+}
+
+/* Append this to a file name to test whether it is a searchable directory.
+   On POSIX platforms "/" suffices, but "/./" is sometimes needed on
+   macOS 10.13 <https://bugs.gnu.org/30350>, and should also work on
+   platforms like AIX 7.2 that need at least "/.".  */
+
+#if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK
+static char const dir_suffix[] = "/";
+#else
+static char const dir_suffix[] = "/./";
+#endif
+
+/* Return true if DIR is a searchable dir, false (setting errno) otherwise.
+   DIREND points to the NUL byte at the end of the DIR string.
+   Store garbage into DIREND[0 .. strlen (dir_suffix)].  */
+
+static bool
+dir_check (char *dir, char *dirend)
+{
+  strcpy (dirend, dir_suffix);
+  return file_accessible (dir);
+}
+
 static idx_t
 get_path_max (void)
 {
@@ -111,19 +188,27 @@ get_path_max (void)
   return path_max < 0 ? 1024 : path_max <= IDX_MAX ? path_max : IDX_MAX;
 }
 
-/* Return the canonical absolute name of file NAME.  A canonical name
-   does not contain any ".", ".." components nor any repeated file name
-   separators ('/') or symlinks.  All file name components must exist.  If
-   RESOLVED is null, the result is malloc'd; otherwise, if the
-   canonical name is PATH_MAX chars or more, returns null with 'errno'
-   set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars,
-   returns the name in RESOLVED.  If the name cannot be resolved and
-   RESOLVED is non-NULL, it contains the name of the first component
-   that cannot be resolved.  If the name can be resolved, RESOLVED
-   holds the same value as the value returned.  */
-
-char *
-__realpath (const char *name, char *resolved)
+/* Act like __realpath (see below), with an additional argument
+   rname_buf that can be used as temporary storage.
+
+   If GCC_LINT is defined, do not inline this function with GCC 10.1
+   and later, to avoid creating a pointer to the stack that GCC
+   -Wreturn-local-addr incorrectly complains about.  See:
+   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644
+   Although the noinline attribute can hurt performance a bit, no better way
+   to pacify GCC is known; even an explicit #pragma does not pacify GCC.
+   When the GCC bug is fixed this workaround should be limited to the
+   broken GCC versions.  */
+#if __GNUC_PREREQ (10, 1)
+# if defined GCC_LINT || defined lint
+__attribute__ ((__noinline__))
+# elif __OPTIMIZE__ && !__NO_INLINE__
+#  define GCC_BOGUS_WRETURN_LOCAL_ADDR
+# endif
+#endif
+static char *
+realpath_stk (const char *name, char *resolved,
+              struct scratch_buffer *rname_buf)
 {
   char *dest;
   char const *start;
@@ -149,8 +234,6 @@ __realpath (const char *name, char *resolved)
     }
 
   struct scratch_buffer extra_buffer, link_buffer;
-  struct scratch_buffer rname_buffer;
-  struct scratch_buffer *rname_buf = &rname_buffer;
   scratch_buffer_init (&extra_buffer);
   scratch_buffer_init (&link_buffer);
   scratch_buffer_init (rname_buf);
@@ -208,7 +291,9 @@ __realpath (const char *name, char *resolved)
          name ends in '/'.  */
       idx_t startlen = end - start;
 
-      if (startlen == 1 && start[0] == '.')
+      if (startlen == 0)
+        break;
+      else if (startlen == 1 && start[0] == '.')
         /* nothing */;
       else if (startlen == 2 && start[0] == '.' && start[1] == '.')
         {
@@ -226,7 +311,8 @@ __realpath (const char *name, char *resolved)
           if (!ISSLASH (dest[-1]))
             *dest++ = '/';
 
-          while (rname + rname_buf->length - dest <= startlen)
+          while (rname + rname_buf->length - dest
+                 < startlen + sizeof dir_suffix)
             {
               idx_t dest_offset = dest - rname;
               if (!scratch_buffer_grow_preserve (rname_buf))
@@ -238,28 +324,19 @@ __realpath (const char *name, char *resolved)
           dest = __mempcpy (dest, start, startlen);
           *dest = '\0';
 
-          /* If STARTLEN == 0, RNAME ends in '/'; use stat rather than
-             readlink, because readlink might fail with EINVAL without
-             checking whether RNAME sans '/' is valid.  */
-          struct stat st;
-          char *buf = NULL;
+          char *buf;
           ssize_t n;
-          if (startlen != 0)
+          while (true)
             {
-              while (true)
-                {
-                  buf = link_buffer.data;
-                  idx_t bufsize = link_buffer.length;
-                  n = __readlink (rname, buf, bufsize - 1);
-                  if (n < bufsize - 1)
-                    break;
-                  if (!scratch_buffer_grow (&link_buffer))
-                    goto error_nomem;
-                }
-              if (n < 0)
-                buf = NULL;
+              buf = link_buffer.data;
+              idx_t bufsize = link_buffer.length;
+              n = __readlink (rname, buf, bufsize - 1);
+              if (n < bufsize - 1)
+                break;
+              if (!scratch_buffer_grow (&link_buffer))
+                goto error_nomem;
             }
-          if (buf)
+          if (0 <= n)
             {
               if (++num_links > __eloop_threshold ())
                 {
@@ -270,7 +347,7 @@ __realpath (const char *name, char *resolved)
               buf[n] = '\0';
 
               char *extra_buf = extra_buffer.data;
-              idx_t end_idx;
+              idx_t end_idx IF_LINT (= 0);
               if (end_in_extra_buffer)
                 end_idx = end - extra_buf;
               idx_t len = strlen (end);
@@ -315,8 +392,8 @@ __realpath (const char *name, char *resolved)
                     dest++;
                 }
             }
-          else if (! (startlen == 0
-                      ? stat (rname, &st) == 0 || errno == EOVERFLOW
+          else if (! (suffix_requires_dir_check (end)
+                      ? dir_check (rname, dest)
                       : errno == EINVAL))
             goto error;
         }
@@ -355,6 +432,28 @@ error_nomem:
   char *result = realloc (rname, rname_size);
   return result != NULL ? result : rname;
 }
+
+/* Return the canonical absolute name of file NAME.  A canonical name
+   does not contain any ".", ".." components nor any repeated file name
+   separators ('/') or symlinks.  All file name components must exist.  If
+   RESOLVED is null, the result is malloc'd; otherwise, if the
+   canonical name is PATH_MAX chars or more, returns null with 'errno'
+   set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars,
+   returns the name in RESOLVED.  If the name cannot be resolved and
+   RESOLVED is non-NULL, it contains the name of the first component
+   that cannot be resolved.  If the name can be resolved, RESOLVED
+   holds the same value as the value returned.  */
+
+char *
+__realpath (const char *name, char *resolved)
+{
+  #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR
+   #warning "GCC might issue a bogus -Wreturn-local-addr warning here."
+   #warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>."
+  #endif
+  struct scratch_buffer rname_buffer;
+  return realpath_stk (name, resolved, &rname_buffer);
+}
 libc_hidden_def (__realpath)
 versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
 #endif /* !FUNC_REALPATH_WORKS || defined _LIBC */
diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c
index 26fe84d..6aaa712 100644
--- a/lib/careadlinkat.c
+++ b/lib/careadlinkat.c
@@ -55,8 +55,7 @@ enum { STACK_BUF_SIZE = 1024 };
 # if defined GCC_LINT || defined lint
 __attribute__ ((__noinline__))
 # elif __OPTIMIZE__ && !__NO_INLINE__
-#  warning "GCC might issue a bogus -Wreturn-local-addr warning here."
-#  warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>."
+#  define GCC_BOGUS_WRETURN_LOCAL_ADDR
 # endif
 #endif
 static char *
@@ -180,10 +179,11 @@ careadlinkat (int fd, char const *filename,
   /* Allocate the initial buffer on the stack.  This way, in the
      common case of a symlink of small size, we get away with a
      single small malloc instead of a big malloc followed by a
-     shrinking realloc.
-
-     If GCC -Wreturn-local-addr warns about this buffer, the warning
-     is bogus; see readlink_stk.  */
+     shrinking realloc.  */
+  #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR
+   #warning "GCC might issue a bogus -Wreturn-local-addr warning here."
+   #warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>."
+  #endif
   char stack_buf[STACK_BUF_SIZE];
   return readlink_stk (fd, filename, buffer, buffer_size, alloc,
                        preadlinkat, stack_buf);
diff --git a/lib/eloop-threshold.h b/lib/eloop-threshold.h
new file mode 100644
index 0000000..5953a4c
--- /dev/null
+++ b/lib/eloop-threshold.h
@@ -0,0 +1,83 @@
+/* Threshold at which to diagnose ELOOP.  Generic version.
+   Copyright (C) 2012-2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _ELOOP_THRESHOLD_H
+#define _ELOOP_THRESHOLD_H      1
+
+#include <limits.h>
+#ifdef _LIBC
+# include <sys/param.h>
+# define _GL_ATTRIBUTE_CONST __attribute__ ((const))
+#else
+# include <unistd.h>
+# include "minmax.h"
+# define __sysconf sysconf
+# if (!defined SYMLOOP_MAX \
+      && ! (defined _SC_SYMLOOP_MAX && defined _POSIX_SYMLOOP_MAX))
+#  define SYMLOOP_MAX 8
+# endif
+#endif
+
+/* POSIX specifies SYMLOOP_MAX as the "Maximum number of symbolic
+   links that can be reliably traversed in the resolution of a
+   pathname in the absence of a loop."  This makes it a minimum that
+   we should certainly accept.  But it leaves open the possibility
+   that more might sometimes work--just not "reliably".
+
+   For example, Linux implements a complex policy whereby there is a
+   small limit on the number of direct symlink traversals (a symlink
+   to a symlink to a symlink), but larger limit on the total number of
+   symlink traversals overall.  Hence the SYMLOOP_MAX number should be
+   the small one, but the limit library functions enforce on users
+   should be the larger one.
+
+   So, we use the larger of the reported SYMLOOP_MAX (if any) and our
+   own constant MIN_ELOOP_THRESHOLD, below.  This constant should be
+   large enough that it never rules out a file name and directory tree
+   that the underlying system (i.e. calls to 'open' et al) would
+   resolve successfully.  It should be small enough that actual loops
+   are detected without a huge number of iterations.  */
+
+#ifndef MIN_ELOOP_THRESHOLD
+# define MIN_ELOOP_THRESHOLD    40
+#endif
+
+/* Return the maximum number of symlink traversals to permit
+   before diagnosing ELOOP.  */
+static inline unsigned int _GL_ATTRIBUTE_CONST
+__eloop_threshold (void)
+{
+#ifdef SYMLOOP_MAX
+  const int symloop_max = SYMLOOP_MAX;
+#else
+  /* The function is marked 'const' even though we use memory and
+     call a function, because sysconf is required to return the
+     same value in every call and so it must always be safe to
+     call __eloop_threshold exactly once and reuse the value.  */
+  static long int sysconf_symloop_max;
+  if (sysconf_symloop_max == 0)
+    sysconf_symloop_max = __sysconf (_SC_SYMLOOP_MAX);
+  const unsigned int symloop_max = (sysconf_symloop_max <= 0
+                                    ? _POSIX_SYMLOOP_MAX
+                                    : sysconf_symloop_max);
+#endif
+
+  return MAX (symloop_max, MIN_ELOOP_THRESHOLD);
+}
+
+#endif  /* eloop-threshold.h */
diff --git a/lib/euidaccess.c b/lib/euidaccess.c
index b352123..a32e336 100644
--- a/lib/euidaccess.c
+++ b/lib/euidaccess.c
@@ -107,7 +107,10 @@ euidaccess (const char *file, int mode)
      safe.  */
 
   if (mode == F_OK)
-    return stat (file, &stats);
+    {
+      int result = stat (file, &stats);
+      return result != 0 && errno == EOVERFLOW ? 0 : result;
+    }
   else
     {
       int result;
@@ -142,8 +145,8 @@ euidaccess (const char *file, int mode)
     /* If we are not set-uid or set-gid, access does the same.  */
     return access (file, mode);
 
-  if (stat (file, &stats) != 0)
-    return -1;
+  if (stat (file, &stats) == -1)
+    return mode == F_OK && errno == EOVERFLOW ? 0 : -1;
 
   /* The super-user can read and write any file, and execute any file
      that anyone can execute.  */
diff --git a/lib/faccessat.c b/lib/faccessat.c
index 9f6a11b..330c54a 100644
--- a/lib/faccessat.c
+++ b/lib/faccessat.c
@@ -32,6 +32,13 @@
 #include <sys/stat.h>
 #undef _GL_INCLUDING_UNISTD_H
 
+#ifndef FACCESSAT_NEVER_EOVERFLOWS
+# define FACCESSAT_NEVER_EOVERFLOWS 0
+#endif
+#ifndef LSTAT_FOLLOWS_SLASHED_SYMLINK
+# define LSTAT_FOLLOWS_SLASHED_SYMLINK 0
+#endif
+
 #if HAVE_FACCESSAT
 static int
 orig_faccessat (int fd, char const *name, int mode, int flag)
@@ -59,7 +66,12 @@ rpl_faccessat (int fd, char const *file, int mode, int flag)
 {
   int result = orig_faccessat (fd, file, mode, flag);
 
-  if (result == 0 && file[strlen (file) - 1] == '/')
+  if (result != 0)
+    {
+      if (!FACCESSAT_NEVER_EOVERFLOWS && mode == F_OK && errno == EOVERFLOW)
+        return 0;
+    }
+  else if (!LSTAT_FOLLOWS_SLASHED_SYMLINK && file[strlen (file) - 1] == '/')
     {
       struct stat st;
       result = fstatat (fd, file, &st, 0);
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index df533fa..a37f927 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -103,6 +103,7 @@
 #  filevercmp \
 #  flexmember \
 #  fpieee \
+#  free-posix \
 #  fstatat \
 #  fsusage \
 #  fsync \
@@ -1528,6 +1529,17 @@ EXTRA_libgnu_a_SOURCES += dup2.c
 endif
 ## end   gnulib module dup2
 
+## begin gnulib module eloop-threshold
+ifeq (,$(OMIT_GNULIB_MODULE_eloop-threshold))
+
+ifneq (,$(gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c))
+
+endif
+EXTRA_DIST += eloop-threshold.h
+
+endif
+## end   gnulib module eloop-threshold
+
 ## begin gnulib module errno
 ifeq (,$(OMIT_GNULIB_MODULE_errno))
 
@@ -1750,9 +1762,7 @@ endif
 ## begin gnulib module free-posix
 ifeq (,$(OMIT_GNULIB_MODULE_free-posix))
 
-ifneq (,$(gl_GNULIB_ENABLED_ef07dc4b3077c11ea9cef586db4e5955))
 
-endif
 EXTRA_DIST += free.c
 
 EXTRA_libgnu_a_SOURCES += free.c
diff --git a/lib/mini-gmp.c b/lib/mini-gmp.c
index 2e0301b..d34fe52 100644
--- a/lib/mini-gmp.c
+++ b/lib/mini-gmp.c
@@ -32,7 +32,7 @@ see https://www.gnu.org/licenses/.  */
 
 /* NOTE: All functions in this file which are not declared in
    mini-gmp.h are internal, and are not intended to be compatible
-   neither with GMP nor with future versions of mini-gmp. */
+   with GMP or with future versions of mini-gmp. */
 
 /* Much of the material copied from GMP files, including: gmp-impl.h,
    longlong.h, mpn/generic/add_n.c, mpn/generic/addmul_1.c,
@@ -1331,29 +1331,26 @@ mpn_set_str_bits (mp_ptr rp, const unsigned char *sp, 
size_t sn,
                  unsigned bits)
 {
   mp_size_t rn;
-  size_t j;
+  mp_limb_t limb;
   unsigned shift;
 
-  for (j = sn, rn = 0, shift = 0; j-- > 0; )
+  for (limb = 0, rn = 0, shift = 0; sn-- > 0; )
     {
-      if (shift == 0)
-       {
-         rp[rn++] = sp[j];
-         shift += bits;
-       }
-      else
+      limb |= (mp_limb_t) sp[sn] << shift;
+      shift += bits;
+      if (shift >= GMP_LIMB_BITS)
        {
-         rp[rn-1] |= (mp_limb_t) sp[j] << shift;
-         shift += bits;
-         if (shift >= GMP_LIMB_BITS)
-           {
-             shift -= GMP_LIMB_BITS;
-             if (shift > 0)
-               rp[rn++] = (mp_limb_t) sp[j] >> (bits - shift);
-           }
+         shift -= GMP_LIMB_BITS;
+         rp[rn++] = limb;
+         /* Next line is correct also if shift == 0,
+            bits == 8, and mp_limb_t == unsigned char. */
+         limb = (unsigned int) sp[sn] >> (bits - shift);
        }
     }
-  rn = mpn_normalized_size (rp, rn);
+  if (limb != 0)
+    rp[rn++] = limb;
+  else
+    rn = mpn_normalized_size (rp, rn);
   return rn;
 }
 
@@ -2723,7 +2720,7 @@ mpz_make_odd (mpz_t r)
 
   assert (r->_mp_size > 0);
   /* Count trailing zeros, equivalent to mpn_scan1, because we know that there 
is a 1 */
-  shift = mpn_common_scan (r->_mp_d[0], 0, r->_mp_d, 0, 0);
+  shift = mpn_scan1 (r->_mp_d, 0);
   mpz_tdiv_q_2exp (r, r, shift);
 
   return shift;
@@ -2780,9 +2777,13 @@ mpz_gcd (mpz_t g, const mpz_t u, const mpz_t v)
 
        if (tv->_mp_size == 1)
          {
-           mp_limb_t vl = tv->_mp_d[0];
-           mp_limb_t ul = mpz_tdiv_ui (tu, vl);
-           mpz_set_ui (g, mpn_gcd_11 (ul, vl));
+           mp_limb_t *gp;
+
+           mpz_tdiv_r (tu, tu, tv);
+           gp = MPZ_REALLOC (g, 1); /* gp = mpz_limbs_modify (g, 1); */
+           *gp = mpn_gcd_11 (tu->_mp_d[0], tv->_mp_d[0]);
+
+           g->_mp_size = *gp != 0; /* mpz_limbs_finish (g, 1); */
            break;
          }
        mpz_sub (tu, tu, tv);
@@ -2871,7 +2872,6 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, 
const mpz_t v)
    * s0 = 0,    s1 = 2^vz
    */
 
-  mpz_setbit (t0, uz);
   mpz_tdiv_qr (t1, tu, tu, tv);
   mpz_mul_2exp (t1, t1, uz);
 
@@ -2882,8 +2882,7 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, 
const mpz_t v)
     {
       mp_bitcnt_t shift;
       shift = mpz_make_odd (tu);
-      mpz_mul_2exp (t0, t0, shift);
-      mpz_mul_2exp (s0, s0, shift);
+      mpz_setbit (t0, uz + shift);
       power += shift;
 
       for (;;)
@@ -2921,6 +2920,8 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, 
const mpz_t v)
          power += shift;
        }
     }
+  else
+    mpz_setbit (t0, uz);
 
   /* Now tv = odd part of gcd, and -s0 and t0 are corresponding
      cofactors. */
@@ -3604,7 +3605,8 @@ mpz_probab_prime_p (const mpz_t n, int reps)
   /* Find q and k, where q is odd and n = 1 + 2**k * q.  */
   mpz_abs (nm1, n);
   nm1->_mp_d[0] -= 1;
-  k = mpz_scan1 (nm1, 0);
+  /* Count trailing zeros, equivalent to mpn_scan1, because we know that there 
is a 1 */
+  k = mpn_scan1 (nm1->_mp_d, 0);
   mpz_tdiv_q_2exp (q, nm1, k);
 
   /* BPSW test */
@@ -4301,7 +4303,7 @@ mpz_get_str (char *sp, int base, const mpz_t u)
 ret:
   sp[sn] = '\0';
   if (osn && osn != sn + 1)
-    sp = gmp_realloc(sp, osn, sn + 1);
+    sp = (char*) gmp_realloc (sp, osn, sn + 1);
   return sp;
 }
 
@@ -4425,6 +4427,8 @@ mpz_out_str (FILE *stream, int base, const mpz_t x)
   size_t len, n;
 
   str = mpz_get_str (NULL, base, x);
+  if (!str)
+    return 0;
   len = strlen (str);
   n = fwrite (str, 1, len, stream);
   gmp_free (str, len + 1);
diff --git a/lib/mini-gmp.h b/lib/mini-gmp.h
index c00568c..59a37e6 100644
--- a/lib/mini-gmp.h
+++ b/lib/mini-gmp.h
@@ -1,6 +1,6 @@
 /* mini-gmp, a minimalistic implementation of a GNU GMP subset.
 
-Copyright 2011-2015, 2017, 2019 Free Software Foundation, Inc.
+Copyright 2011-2015, 2017, 2019-2020 Free Software Foundation, Inc.
 
 This file is part of the GNU MP Library.
 
@@ -295,7 +295,8 @@ int mpz_init_set_str (mpz_t, const char *, int);
   || defined (_MSL_STDIO_H)           /* Metrowerks */          \
   || defined (_STDIO_H_INCLUDED)      /* QNX4 */               \
   || defined (_ISO_STDIO_ISO_H)       /* Sun C++ */            \
-  || defined (__STDIO_LOADED)         /* VMS */
+  || defined (__STDIO_LOADED)         /* VMS */                        \
+  || defined (__DEFINED_FILE)         /* musl */
 size_t mpz_out_str (FILE *, int, const mpz_t);
 #endif
 
diff --git a/lib/symlink.c b/lib/symlink.c
index e7dbd18..b1196b9 100644
--- a/lib/symlink.c
+++ b/lib/symlink.c
@@ -36,7 +36,7 @@ rpl_symlink (char const *contents, char const *name)
   if (len && name[len - 1] == '/')
     {
       struct stat st;
-      if (lstat (name, &st) == 0)
+      if (lstat (name, &st) == 0 || errno == EOVERFLOW)
         errno = EEXIST;
       return -1;
     }
diff --git a/m4/canonicalize.m4 b/m4/canonicalize.m4
index 14ea3e1..c8da4df 100644
--- a/m4/canonicalize.m4
+++ b/m4/canonicalize.m4
@@ -1,4 +1,4 @@
-# canonicalize.m4 serial 33
+# canonicalize.m4 serial 34
 
 dnl Copyright (C) 2003-2007, 2009-2020 Free Software Foundation, Inc.
 
@@ -11,7 +11,9 @@ dnl with or without modifications, as long as this notice is 
preserved.
 AC_DEFUN([gl_FUNC_CANONICALIZE_FILENAME_MODE],
 [
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
-  AC_CHECK_FUNCS_ONCE([canonicalize_file_name])
+  AC_REQUIRE([gl_FUNC_FACCESSAT_EOVERFLOW])
+  AC_REQUIRE([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK])
+  AC_CHECK_FUNCS_ONCE([canonicalize_file_name faccessat])
   AC_REQUIRE([gl_DOUBLE_SLASH_ROOT])
   AC_REQUIRE([gl_FUNC_REALPATH_WORKS])
   if test $ac_cv_func_canonicalize_file_name = no; then
@@ -56,7 +58,9 @@ AC_DEFUN([gl_CANONICALIZE_LGPL],
 AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE],
 [
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
-  AC_CHECK_FUNCS_ONCE([canonicalize_file_name readlink])
+  AC_REQUIRE([gl_FUNC_FACCESSAT_EOVERFLOW])
+  AC_REQUIRE([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK])
+  AC_CHECK_FUNCS_ONCE([canonicalize_file_name faccessat])
 
   dnl On native Windows, we use _getcwd(), regardless whether getcwd() is
   dnl available through the linker option '-loldnames'.
diff --git a/m4/faccessat.m4 b/m4/faccessat.m4
index 7a8b979..a4ad31a 100644
--- a/m4/faccessat.m4
+++ b/m4/faccessat.m4
@@ -1,4 +1,4 @@
-# serial 8
+# serial 9
 # See if we need to provide faccessat replacement.
 
 dnl Copyright (C) 2009-2020 Free Software Foundation, Inc.
@@ -8,6 +8,31 @@ dnl with or without modifications, as long as this notice is 
preserved.
 
 # Written by Eric Blake.
 
+AC_DEFUN([gl_FUNC_FACCESSAT_EOVERFLOW],
+[
+  AC_CHECK_FUNCS_ONCE([faccessat])
+  if test "$ac_cv_func_faccessat" = yes; then
+    AC_CACHE_CHECK([whether faccessat works when stat would EOVERFLOW],
+      [gl_cv_func_faccessat_never_eoverflows],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM([],
+            [[#ifdef __linux__
+               #include <linux/version.h>
+               #if (! (KERNEL_VERSION (5, 8, 0) <= LINUX_VERSION_CODE \
+                    && 2 < (__GLIBC__ + (33 <= __GLIBC_MINOR__))))
+                #error "faccessat might fail with EOVERFLOW"
+               #endif
+              #endif
+            ]])],
+         [gl_cv_func_faccessat_never_eoverflows=yes],
+         [gl_cv_func_faccessat_never_eoverflows=no])])
+    if test "$gl_cv_func_faccessat_never_eoverflows" = yes; then
+      AC_DEFINE([FACCESSAT_NEVER_EOVERFLOWS], 1,
+        [Define to 1 if faccessat is EOVERFLOW-free.])
+    fi
+  fi
+])
+
 AC_DEFUN([gl_FUNC_FACCESSAT],
 [
   AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
@@ -16,12 +41,14 @@ AC_DEFUN([gl_FUNC_FACCESSAT],
   dnl Persuade glibc <unistd.h> to declare faccessat().
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
 
+  AC_REQUIRE([gl_FUNC_FACCESSAT_EOVERFLOW])
+
   AC_CHECK_FUNCS_ONCE([faccessat])
   if test $ac_cv_func_faccessat = no; then
     HAVE_FACCESSAT=0
   else
-    case "$gl_cv_func_lstat_dereferences_slashed_symlink" in
-      *yes) ;;
+    case 
$gl_cv_func_lstat_dereferences_slashed_symlink,$gl_cv_func_faccessat_never_eoverflows
 in
+      *yes,*yes) ;;
       *)    REPLACE_FACCESSAT=1 ;;
     esac
   fi
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index beb9817..0971636 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -75,6 +75,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module dtoastr:
   # Code from module dtotimespec:
   # Code from module dup2:
+  # Code from module eloop-threshold:
   # Code from module environ:
   # Code from module errno:
   # Code from module euidaccess:
@@ -291,6 +292,12 @@ AC_DEFUN([gl_INIT],
   if test $gl_cv_func___fpending = no; then
     AC_LIBOBJ([fpending])
   fi
+  gl_FUNC_FREE
+  if test $REPLACE_FREE = 1; then
+    AC_LIBOBJ([free])
+    gl_PREREQ_FREE
+  fi
+  gl_STDLIB_MODULE_INDICATOR([free-posix])
   gl_FUNC_FSTATAT
   if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then
     AC_LIBOBJ([fstatat])
@@ -510,8 +517,8 @@ AC_DEFUN([gl_INIT],
   gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false
   gl_gnulib_enabled_cloexec=false
   gl_gnulib_enabled_dirfd=false
+  gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c=false
   gl_gnulib_enabled_euidaccess=false
-  gl_gnulib_enabled_ef07dc4b3077c11ea9cef586db4e5955=false
   gl_gnulib_enabled_getdtablesize=false
   gl_gnulib_enabled_getgroups=false
   gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false
@@ -557,6 +564,12 @@ AC_DEFUN([gl_INIT],
       gl_gnulib_enabled_dirfd=true
     fi
   }
+  func_gl_gnulib_m4code_925677f0343de64b89a9f0c790b4104c ()
+  {
+    if ! $gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c; then
+      gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c=true
+    fi
+  }
   func_gl_gnulib_m4code_euidaccess ()
   {
     if ! $gl_gnulib_enabled_euidaccess; then
@@ -573,18 +586,6 @@ AC_DEFUN([gl_INIT],
       func_gl_gnulib_m4code_6099e9737f757db36c47fa9d9f02e88c
     fi
   }
-  func_gl_gnulib_m4code_ef07dc4b3077c11ea9cef586db4e5955 ()
-  {
-    if ! $gl_gnulib_enabled_ef07dc4b3077c11ea9cef586db4e5955; then
-      gl_FUNC_FREE
-      if test $REPLACE_FREE = 1; then
-        AC_LIBOBJ([free])
-        gl_PREREQ_FREE
-      fi
-      gl_STDLIB_MODULE_INDICATOR([free-posix])
-      gl_gnulib_enabled_ef07dc4b3077c11ea9cef586db4e5955=true
-    fi
-  }
   func_gl_gnulib_m4code_getdtablesize ()
   {
     if ! $gl_gnulib_enabled_getdtablesize; then
@@ -734,7 +735,7 @@ AC_DEFUN([gl_INIT],
     fi
   }
   if test $HAVE_CANONICALIZE_FILE_NAME = 0 || test 
$REPLACE_CANONICALIZE_FILE_NAME = 1; then
-    func_gl_gnulib_m4code_ef07dc4b3077c11ea9cef586db4e5955
+    func_gl_gnulib_m4code_925677f0343de64b89a9f0c790b4104c
   fi
   if test $HAVE_CANONICALIZE_FILE_NAME = 0 || test 
$REPLACE_CANONICALIZE_FILE_NAME = 1; then
     func_gl_gnulib_m4code_idx
@@ -818,8 +819,8 @@ AC_DEFUN([gl_INIT],
   AM_CONDITIONAL([gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b], 
[$gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_cloexec], [$gl_gnulib_enabled_cloexec])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_dirfd], [$gl_gnulib_enabled_dirfd])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c], 
[$gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_euidaccess], 
[$gl_gnulib_enabled_euidaccess])
-  AM_CONDITIONAL([gl_GNULIB_ENABLED_ef07dc4b3077c11ea9cef586db4e5955], 
[$gl_gnulib_enabled_ef07dc4b3077c11ea9cef586db4e5955])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_getdtablesize], 
[$gl_gnulib_enabled_getdtablesize])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_getgroups], [$gl_gnulib_enabled_getgroups])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], 
[$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36])
@@ -1020,6 +1021,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/dtoastr.c
   lib/dtotimespec.c
   lib/dup2.c
+  lib/eloop-threshold.h
   lib/errno.in.h
   lib/euidaccess.c
   lib/execinfo.c



reply via email to

[Prev in Thread] Current Thread [Next in Thread]