* 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>
+
+ 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.
@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
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:
#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];
}
return read (fd, buffer, length);
+#endif
}
#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
-# 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,
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
])
-# 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,
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])
])
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])
-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)' \
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));