]> Savannah Git Hosting - gnulib.git/commitdiff
getrandom: Override incompatible system function on Solaris 11.
authorBruno Haible <bruno@clisp.org>
Sat, 30 May 2020 15:33:46 +0000 (17:33 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 30 May 2020 15:33:46 +0000 (17:33 +0200)
* lib/sys_random.in.h (getrandom): Override if REPLACE_GETRANDOM is 1.
* lib/getrandom.c (getrandom): When the system has getrandom, just
invoke it.
* m4/getrandom.m4 (gl_FUNC_GETRANDOM): Set REPLACE_GETRANDOM if the
system's getrandom function's prototype is not the expected one.
* m4/sys_random_h.m4 (gl_SYS_RANDOM_H_DEFAULTS): Initialize
REPLACE_GETRANDOM.
* modules/sys_random (Makefile.am): Substitute REPLACE_GETRANDOM.
* modules/getrandom (modules/getrandom): Consider REPLACE_GETRANDOM.
* tests/test-getrandom.c (main): Allow error EINVAL as an alternative to
EAGAIN.
* doc/glibc-functions/getrandom.texi: Mention the new module and the
Solaris problem.

ChangeLog
doc/glibc-functions/getrandom.texi
lib/getrandom.c
lib/sys_random.in.h
m4/getrandom.m4
m4/sys_random_h.m4
modules/getrandom
modules/sys_random
tests/test-getrandom.c

index c5a3bd58682b8b595146a321d324b093b4b846a1..bf5762435119b06e46ed1a3f6a0a3bc7eb251498 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2020-05-30  Bruno Haible  <bruno@clisp.org>
+
+       getrandom: Override incompatible system function on Solaris 11.
+       * lib/sys_random.in.h (getrandom): Override if REPLACE_GETRANDOM is 1.
+       * lib/getrandom.c (getrandom): When the system has getrandom, just
+       invoke it.
+       * m4/getrandom.m4 (gl_FUNC_GETRANDOM): Set REPLACE_GETRANDOM if the
+       system's getrandom function's prototype is not the expected one.
+       * m4/sys_random_h.m4 (gl_SYS_RANDOM_H_DEFAULTS): Initialize
+       REPLACE_GETRANDOM.
+       * modules/sys_random (Makefile.am): Substitute REPLACE_GETRANDOM.
+       * modules/getrandom (modules/getrandom): Consider REPLACE_GETRANDOM.
+       * tests/test-getrandom.c (main): Allow error EINVAL as an alternative to
+       EAGAIN.
+       * doc/glibc-functions/getrandom.texi: Mention the new module and the
+       Solaris problem.
+
 2020-05-30  Bruno Haible  <bruno@clisp.org>
 
        sys_random: Add C++ tests.
index 2f4debcfefb55a2a85e5db94c86542289c95a0d0..2d935565372a0360ec5b60e6abc01ceeb9847c8d 100644 (file)
@@ -15,7 +15,7 @@ Documentation:
 @uref{https://www.kernel.org/doc/man-pages/online/pages/man2/getrandom.2.html,,man getrandom}.
 @end itemize
 
-Gnulib module: ---
+Gnulib module: getrandom
 
 Portability problems fixed by Gnulib:
 @itemize
@@ -23,6 +23,9 @@ Portability problems fixed by Gnulib:
 This function is missing on some platforms:
 glibc 2.24, Mac OS X 10.5, FreeBSD 11.0, NetBSD 5.0, OpenBSD 3.8,
 Solaris 11.0, Android 9.0.
+@item
+This function has a different return type on some platforms:
+Solaris 11.4.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index 9b6ecb43be3e9f7b0643feb6749009f07eeeb341..f20ffe01127c512c1e0ce7bc13d6ee7ef29c923a 100644 (file)
 
 #include <sys/random.h>
 
-#include "minmax.h"
 #include <fcntl.h>
 #include <stdbool.h>
 #include <unistd.h>
 
+#include "minmax.h"
+
 /* Set BUFFER (of size LENGTH) to random bytes under the control of FLAGS.
    Return the number of bytes written, or -1 on error.  */
 ssize_t
 getrandom (void *buffer, size_t length, unsigned int flags)
+#undef getrandom
 {
+#if HAVE_GETRANDOM
+  return getrandom (buffer, length, flags);
+#else
   static int randfd[2] = { -1, -1 };
   bool devrandom = (flags & GRND_RANDOM) != 0;
   int fd = randfd[devrandom];
@@ -49,4 +54,5 @@ getrandom (void *buffer, size_t length, unsigned int flags)
     }
 
   return read (fd, buffer, length);
+#endif
 }
index 3997cf4c3bb34d2bcca0b02b5ebffb66fa97408b..4d12db95eab4dcd0f4ddca96b38f5e667716823b 100644 (file)
 
 #if @GNULIB_GETRANDOM@
 /* Fill a buffer with random bytes.  */
-# if !@HAVE_GETRANDOM@
+# if @REPLACE_GETRANDOM@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef getrandom
+#   define getrandom rpl_getrandom
+#  endif
+_GL_FUNCDECL_RPL (getrandom, ssize_t,
+                  (void *buffer, size_t length, unsigned int flags)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (getrandom, ssize_t,
+                  (void *buffer, size_t length, unsigned int flags));
+# else
+#  if !@HAVE_GETRANDOM@
 _GL_FUNCDECL_SYS (getrandom, ssize_t,
                   (void *buffer, size_t length, unsigned int flags)
                   _GL_ARG_NONNULL ((1)));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (getrandom, ssize_t,
                   (void *buffer, size_t length, unsigned int flags));
+# endif
 _GL_CXXALIASWARN (getrandom);
 #elif defined GNULIB_POSIXCHECK
 # undef getrandom
index 79e5520931a9be8dcf633a8edf2f7ce86b889c5e..9fee059e43aae3d0af8f3c3520ed38ccd659cf59 100644 (file)
@@ -1,4 +1,4 @@
-# getrandom.m4 serial 2
+# getrandom.m4 serial 3
 dnl Copyright 2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -12,5 +12,23 @@ AC_DEFUN([gl_FUNC_GETRANDOM],
   AC_CHECK_FUNCS_ONCE([getrandom])
   if test "$ac_cv_func_getrandom" != yes; then
     HAVE_GETRANDOM=0
+  else
+    dnl On Solaris 11.4 the return type is 'int', not 'ssize_t'.
+    AC_CACHE_CHECK([whether getrandom is compatible with its GNU+BSD signature],
+      [gl_cv_func_getrandom_ok],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM(
+            [[#include <sys/random.h>
+              #include <sys/types.h>
+              ssize_t getrandom (void *, size_t, unsigned int);
+            ]],
+            [[]])
+         ],
+         [gl_cv_func_getrandom_ok=yes],
+         [gl_cv_func_getrandom_ok=no])
+      ])
+    if test $gl_cv_func_getrandom_ok = no; then
+      REPLACE_GETRANDOM=1
+    fi
   fi
 ])
index d78307f53b30cd5fcf10902d82c91e474b0a73ff..2ab96ef88ef4fc0b6a6570c13dc09452d9c40b16 100644 (file)
@@ -1,4 +1,4 @@
-# sys_random_h.m4 serial 1
+# sys_random_h.m4 serial 2
 dnl Copyright (C) 2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -40,4 +40,5 @@ AC_DEFUN([gl_SYS_RANDOM_H_DEFAULTS],
   GNULIB_GETRANDOM=0;     AC_SUBST([GNULIB_GETRANDOM])
   dnl Assume proper GNU behavior unless another module says otherwise.
   HAVE_GETRANDOM=1;       AC_SUBST([HAVE_GETRANDOM])
+  REPLACE_GETRANDOM=1;    AC_SUBST([REPLACE_GETRANDOM])
 ])
index f7b3ff9e29b1ccfa73b775c73c892164bf592db8..e94686d6ff9bdc800dfeed73a7b33c314970a49e 100644 (file)
@@ -8,13 +8,13 @@ m4/getrandom.m4
 Depends-on:
 sys_random
 crypto/gc-random    [test $HAVE_GETRANDOM = 0]
-fcntl-h             [test $HAVE_GETRANDOM = 0]
-minmax              [test $HAVE_GETRANDOM = 0]
-open                [test $HAVE_GETRANDOM = 0]
+fcntl-h             [test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1]
+minmax              [test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1]
+open                [test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1]
 
 configure.ac:
 gl_FUNC_GETRANDOM
-if test $HAVE_GETRANDOM = 0; then
+if test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1; then
   AC_LIBOBJ([getrandom])
 fi
 gl_SYS_RANDOM_MODULE_INDICATOR([getrandom])
index 1d0eb7ce01ebd2d28d0da425c091cbd659eb3ce1..b88507bb92cbf20f772913021dfefe6711914c29 100644 (file)
@@ -32,6 +32,7 @@ sys/random.h: sys_random.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_N
              -e 's|@''HAVE_SYS_RANDOM_H''@|$(HAVE_SYS_RANDOM_H)|g' \
              -e 's/@''GNULIB_GETRANDOM''@/$(GNULIB_GETRANDOM)/g' \
              -e 's/@''HAVE_GETRANDOM''@/$(HAVE_GETRANDOM)/g' \
+             -e 's/@''REPLACE_GETRANDOM''@/$(REPLACE_GETRANDOM)/g' \
              -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
              -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
              -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
index 3c84f871ef183100f7e44b2eda504875f4d34f36..8b2595866548d668409a2e52225bd0274ff434e7 100644 (file)
@@ -75,7 +75,8 @@ main (void)
   ret = getrandom (large_buf, sizeof (large_buf), GRND_RANDOM | GRND_NONBLOCK);
   /* It is very unlikely that so many truly random bytes were ready.  */
   if (ret < 0)
-    ASSERT (errno == ENOSYS || errno == EAGAIN);
+    ASSERT (errno == ENOSYS || errno == EAGAIN
+            || errno == EINVAL /* Solaris */);
   else
     ASSERT (ret > 0 && ret < sizeof (large_buf));