@@ -56,6 +56,7 @@ libsupport-routines = \
support_openpty \
support_quote_blob \
support_record_failure \
+ support_random \
support_run_diff \
support_shared_allocate \
support_test_compare_blob \
@@ -161,7 +162,7 @@ tests = \
tst-support_record_failure \
tst-test_compare \
tst-test_compare_blob \
- tst-xreadlink \
+ tst-xreadlink
ifeq ($(run-built-tests),yes)
tests-special = \
new file mode 100644
@@ -0,0 +1,90 @@
+/* Function for pseudo-random number generation.
+ Copyright (C) 2018 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/random.h>
+
+#include <support/support_random.h>
+#include <support/check.h>
+#include <support/xunistd.h>
+
+void
+support_random_seed (support_random_state *state, uint32_t seed)
+{
+ unsigned short int seed16v[3] = { 0 };
+ memcpy (seed16v, &seed, sizeof (seed));
+ seed48_r (seed16v, state);
+}
+
+void
+support_random_rseed (support_random_state *state)
+{
+ unsigned short int buf[3];
+ size_t len = sizeof buf;
+
+ ssize_t ret = getrandom (buf, len, 0);
+ if (ret != len)
+ {
+ int fd = xopen ("/dev/urandom", O_RDONLY, 0);
+ uintptr_t pbuf = (uintptr_t) buf;
+ uintptr_t pend = pbuf + len;
+ while (pbuf < pend)
+ {
+ ret = read (fd, buf, pend - pbuf);
+ if (ret <= 0)
+ FAIL_EXIT1 ("read %zu bytes from /dev/urandom failed: %m",
+ pend - pbuf);
+ pbuf += ret;
+ }
+ close (fd);
+ }
+
+ seed48_r (buf, state);
+}
+
+uint32_t
+support_random_u32 (support_random_state *state)
+{
+ long int rl;
+ mrand48_r (state, &rl);
+ return rl;
+}
+
+void
+support_random_buf (support_random_state *state, void *buf, size_t nbytes)
+{
+ size_t nw = nbytes / sizeof (uint32_t);
+ for (size_t i = 0; i < nw; i++)
+ {
+ uint32_t r = support_random_u32 (state);
+ memcpy (buf, &r, sizeof (uint32_t));
+ buf = (void*)((uintptr_t)buf + sizeof (uint32_t));
+ }
+
+ size_t nb = nbytes % sizeof (uint32_t);
+ if (nb != 0)
+ {
+ uint32_t r = support_random_u32 (state);
+ memcpy (buf, &r, nb);
+ }
+}
new file mode 100644
@@ -0,0 +1,59 @@
+/* Function for pseudo-random number generation.
+ Copyright (C) 2018 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef SUPPORT_MT_RAND_H
+#define SUPPORT_MT_RAND_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+typedef struct drand48_data support_random_state;
+
+void support_random_seed (support_random_state *state, uint32_t seed);
+void support_random_rseed (support_random_state *state);
+
+uint32_t support_random_u32 (support_random_state *state);
+void support_random_buf (support_random_state *state, void *buf,
+ size_t nbytes);
+
+/* Scales the number NUMBER to the uniformly distributed closed internal
+ [min, max]. */
+static inline uint32_t
+support_random_uniform_distribution (support_random_state *state,
+ uint32_t min, uint32_t max)
+{
+ uint32_t ret;
+ uint32_t range = max - min;
+ /* It assumes the input random number RANDOM range is as larger or equal
+ than the RANGE, so the result will either returned or downscaled. */
+ if (range != UINT32_MAX)
+ {
+ uint32_t urange = range + 1; /* range can be 0. */
+ uint32_t scaling = UINT32_MAX / urange;
+ uint32_t past = urange * scaling;
+ do
+ ret = support_random_u32 (state);
+ while (ret >= past);
+ ret /= scaling;
+ }
+ else
+ ret = support_random_u32 (state);
+ return ret + min;
+}
+
+#endif