[m-rev.] for review: implement the system RNG on Windows
Julien Fischer
jfischer at opturion.com
Sat Feb 13 03:54:24 AEDT 2021
For review by anyone.
---------------------
Implement the system RNG on Windows.
On Windows we implement the system RNG by calling the CRT's rand_s() function.
library/random.system_rng.m:
Implement the system RNG on Windows using rand_s().
runtime/mercury_std.h:
On Windows define the macro _CRT_RAND_S before the initial
inclusion of stdlib.h -- we must do this otherwise the declaration
of rand_s() will not be visible.
Julien.
diff --git a/library/random.system_rng.m b/library/random.system_rng.m
index 59dd1d0c4..776dde439 100644
--- a/library/random.system_rng.m
+++ b/library/random.system_rng.m
@@ -119,6 +119,9 @@
#include <errno.h>
#include <stdint.h>
+
+// On Windows we need to ensure that _CRT_RAND_S is defined before stdlib.h
+// is included but this must be done in runtime/mercury_std.h.
#include <stdlib.h>
// The following macros define if the system random number exists on this
@@ -169,6 +172,8 @@
#else
#define ML_SYSRAND_IMPL_URANDOM
#endif
+#elif defined(MR_WIN32)
+ #define ML_SYSRAND_IMPL_RAND_S
#else
#define ML_SYSRAND_IMPL_NONE
#endif
@@ -675,6 +680,51 @@ ML_random_generate_bytes(ML_SystemRandomHandle handle,
return MR_TRUE;
}
+#elif defined(ML_SYSRAND_IMPL_RAND_S)
+
+ML_SystemRandomHandle
+ML_random_open(MR_Bool *succeeded, MR_String *err_msg)
+{
+ *succeeded = MR_TRUE;
+ *err_msg = MR_make_string_const(\"\");
+ return 0;
+}
+
+MR_Bool
+ML_random_close(ML_SystemRandomHandle handle, MR_String *err_msg)
+{
+ *err_msg = MR_make_string_const(\"\");
+ return MR_TRUE;
+}
+
+MR_Bool
+ML_random_generate_bytes(ML_SystemRandomHandle handle,
+ unsigned char *buffer, size_t len, MR_String *err_msg)
+{
+ int err;
+ unsigned int n;
+ unsigned char *bytes = (unsigned char *) &n;
+ size_t num_to_read = len;
+ size_t i;
+
+ while (num_to_read > 0) {
+ err = rand_s(&n);
+ if (err != 0) {
+ *err_msg = MR_make_string_const(\"rand_s failed\");
+ return MR_FALSE;
+ }
+ for (i = 0; i < 4; i++) {
+ buffer[num_to_read - 1] = bytes[i];
+ num_to_read--;
+ if (num_to_read == 0) {
+ break;
+ }
+ }
+ }
+
+ return MR_TRUE;
+}
+
#else // ML_SYSRAND_IMPL_NONE
ML_SystemRandomHandle
diff --git a/runtime/mercury_std.h b/runtime/mercury_std.h
index e34d0df36..5cdb77434 100644
--- a/runtime/mercury_std.h
+++ b/runtime/mercury_std.h
@@ -1,7 +1,7 @@
// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 1993-1995, 1997-2005, 2011-2012 The University of Melbourne.
-// Copyright (C) 2014, 2016-2018 The Mercury team.
+// Copyright (C) 2014, 2016-2019, 2021 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// std.h - "standard" [sic] definitions for C:
@@ -22,7 +22,14 @@
#error "Mercury requires a system that provides stdint.h"
#endif
+// On Windows we need to define _CRT_RAND_S *before* stdlib.h is included,
+// otherwise the declaration for rand_s() will not be visible.
+//
+#if defined(MR_WIN32) && !defined(_CRT_RAND_S)
+ #define _CRT_RAND_S
+#endif
#include <stdlib.h> // for size_t
+
#include <assert.h> // for assert()
#include <errno.h> // for EINTR
#include <ctype.h> // for isalnum(), etc.
More information about the reviews
mailing list