mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 17:33:38 +00:00
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.
This commit is contained in:
@@ -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
|
||||
@@ -136,7 +139,7 @@
|
||||
// PRNG, such as ChaCha20; it should _not_ be enabled on systems where
|
||||
// arc4random() still uses RC4.
|
||||
//
|
||||
// ML_SYSRAND_IMPL_RAND_S (NYI)
|
||||
// ML_SYSRAND_IMPL_RAND_S
|
||||
// the system RNG is implemented by calling the rand_s() function
|
||||
// (Windows only).
|
||||
//
|
||||
@@ -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,58 @@ 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;
|
||||
size_t num_to_read = len;
|
||||
|
||||
while (num_to_read > 0) {
|
||||
if (num_to_read < 4) {
|
||||
err = rand_s(&n);
|
||||
if (err != 0) {
|
||||
goto rand_s_failure_handler;
|
||||
}
|
||||
MR_memcpy(buffer, (unsigned char *) &n, num_to_read);
|
||||
break;
|
||||
} else {
|
||||
err = rand_s((unsigned int *) buffer);
|
||||
if (err != 0) {
|
||||
goto rand_s_failure_handler;
|
||||
}
|
||||
num_to_read -= 4;
|
||||
buffer += 4;
|
||||
}
|
||||
}
|
||||
|
||||
*err_msg = MR_make_string_const(\"\");
|
||||
return MR_TRUE;
|
||||
|
||||
rand_s_failure_handler:
|
||||
|
||||
*err_msg = MR_make_string_const(\"rand_s failed\");
|
||||
return MR_FALSE;
|
||||
}
|
||||
|
||||
#else // ML_SYSRAND_IMPL_NONE
|
||||
|
||||
ML_SystemRandomHandle
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user