On Thursday, December 12, 2019 at 3:49:05 PM UTC, Frederick Gotham wrote:
> Also I might have to write it in C also, and so I want the function names to be the same.
I realise that this is a C++ newsgroup, but anyway here's what I've got so far with porting it to C. There's no namespaces so I've put a UUID suffix on all global identifiers.
#ifndef H_INCLUSION_GUARD_COMPANY_PRODUCT_RANDOM
#define H_INCLUSION_GUARD_COMPANY_PRODUCT_RANDOM
#ifdef __cplusplus
# error "This is a C header file but you've included it in a C++ source file (or you've used a C++ compiler on a C source file). You can't do that."
#endif
#include <stdbool.h> /* bool */
#include <stddef.h> /* NULL, size_t */
#include <limits.h> /* INT_MAX */
#include <pthread.h>
// The next two lines are declarations of functions found in
// "libdl.so". (Unfortunately the compiler won't let me put
// these declarations inside the body of a function).
extern void *dlopen(char const *, int);
extern void *dlsym(void *,char const *);
typedef int (*RAND_bytes_t_35466a8ef14e4bc2b50bfc28a6d19b66)(char unsigned *, int);
bool g_random_first_time_35466a8ef14e4bc2b50bfc28a6d19b66 = true;
RAND_bytes_t_35466a8ef14e4bc2b50bfc28a6d19b66 g_ptr_to_RAND_bytes_35466a8ef14e4bc2b50bfc28a6d19b66 = NULL;
pthread_mutex_t g_mutex_35466a8ef14e4bc2b50bfc28a6d19b66 = PTHREAD_MUTEX_INITIALIZER;
inline void Company_Product_Random(void *pvoid, size_t len_bytes) // len_bytes can be 0
{
pthread_mutex_lock(&g_mutex_35466a8ef14e4bc2b50bfc28a6d19b66);
if ( g_random_first_time_35466a8ef14e4bc2b50bfc28a6d19b66 )
{
g_random_first_time_35466a8ef14e4bc2b50bfc28a6d19b66 = false;
void *const handle = dlopen("libcrypto.so", 1); /* 1 == RTLD_LAZY */
if ( NULL == handle )
return;
g_ptr_to_RAND_bytes_35466a8ef14e4bc2b50bfc28a6d19b66 = \
(RAND_bytes_t_35466a8ef14e4bc2b50bfc28a6d19b66)dlsym(handle, "RAND_bytes"); // Linux allows func_pointer = obj_pointer
}
pthread_mutex_unlock(&g_mutex_35466a8ef14e4bc2b50bfc28a6d19b66);
if ( NULL == g_ptr_to_RAND_bytes_35466a8ef14e4bc2b50bfc28a6d19b66 )
return;
while ( 0 != len_bytes )
{
int bytes_this_time; // RAND_bytes unfortunately takes an 'int' for length
if ( len_bytes > (size_t)INT_MAX )
bytes_this_time = INT_MAX;
else
bytes_this_time = len_bytes;
g_ptr_to_RAND_bytes_35466a8ef14e4bc2b50bfc28a6d19b66( (char unsigned *)pvoid, bytes_this_time );
pvoid = (char*)pvoid + bytes_this_time; // Cast to char pointer for arithmetic
len_bytes -= bytes_this_time;
}
}
#endif // ifndef H_INCLUSION_GUARD_COMPANY_PRODUCT_RANDOM