-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGetRandom.xs
More file actions
60 lines (54 loc) · 1.55 KB
/
GetRandom.xs
File metadata and controls
60 lines (54 loc) · 1.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <sys/random.h>
#include <sys/types.h>
#include <errno.h>
#define MY_PKG "Sys::GetRandom"
#ifndef PERL_VERSION_GE
#define PERL_VERSION_GE(R, V, S) (PERL_REVISION > (R) || (PERL_REVISION == (R) && (PERL_VERSION > (V) || (PERL_VERSION == (V) && PERL_SUBVERSION >= (S)))))
#endif
MODULE = Sys::GetRandom PACKAGE = Sys::GetRandom PREFIX = sgr_
PROTOTYPES: ENABLE
BOOT:
{
HV *const stash = gv_stashpvs(MY_PKG, GV_ADD);
newCONSTSUB(stash, "GRND_NONBLOCK", newSVuv(GRND_NONBLOCK));
newCONSTSUB(stash, "GRND_RANDOM", newSVuv(GRND_RANDOM));
}
ssize_t
sgr_getrandom(buffer, length, flags = 0, offset = 0)
SV *buffer
size_t length
unsigned int flags
STRLEN offset
PREINIT:
char *p;
CODE:
if (length >= SSIZE_MAX || length >= (STRLEN)-1 - offset) {
errno = EFAULT;
XSRETURN_UNDEF;
}
if (!SvOK(buffer)) {
#if PERL_VERSION_GE(5, 25, 6)
SvPVCLEAR(buffer);
#else
sv_setpvs(buffer, "");
#endif
} else {
STRLEN curlen;
SvPVbyte_force(buffer, curlen);
(void)curlen;
}
p = offset + SvGROW(buffer, offset + length + 1u);
RETVAL = getrandom(p, length, flags);
if (RETVAL == -1) {
XSRETURN_UNDEF;
}
p[RETVAL] = '\0';
SvCUR_set(buffer, offset + RETVAL);
SvUTF8_off(buffer);
SvSETMAGIC(buffer);
OUTPUT:
RETVAL