File Coverage

GetRandom.xs
Criterion Covered Total %
statement 14 17 82.3
branch 9 14 64.2
condition n/a
subroutine n/a
pod n/a
total 23 31 74.1


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #include
7             #include
8             #ifdef __OpenBSD__
9             #include
10             #define GRND_NONBLOCK 1u
11             #define GRND_RANDOM 2u
12             #else
13             #include
14             #endif
15              
16             #define MY_PKG "Sys::GetRandom"
17              
18             #ifndef PERL_VERSION_GE
19             #define PERL_VERSION_GE(R, V, S) (PERL_REVISION > (R) || (PERL_REVISION == (R) && (PERL_VERSION > (V) || (PERL_VERSION == (V) && PERL_SUBVERSION >= (S)))))
20             #endif
21              
22             MODULE = Sys::GetRandom PACKAGE = Sys::GetRandom PREFIX = sgr_
23             PROTOTYPES: ENABLE
24              
25             BOOT:
26             {
27 2           HV *const stash = gv_stashpvs(MY_PKG, GV_ADD);
28 2           newCONSTSUB(stash, "GRND_NONBLOCK", newSVuv(GRND_NONBLOCK));
29 2           newCONSTSUB(stash, "GRND_RANDOM", newSVuv(GRND_RANDOM));
30             }
31              
32             ssize_t
33             sgr_getrandom(buffer, length, flags = 0, offset = 0)
34             SV *buffer
35             size_t length
36             unsigned int flags
37             STRLEN offset
38             PREINIT:
39             char *p;
40             CODE:
41             #ifdef __OpenBSD__
42             if (flags & ~(GRND_NONBLOCK | GRND_RANDOM)) {
43             errno = EINVAL;
44             XSRETURN_UNDEF;
45             }
46             #endif
47 20 50         if (length >= SSIZE_MAX || length >= (STRLEN)-1 - offset) {
    50          
48 0           errno = EFAULT;
49 0           XSRETURN_UNDEF;
50             }
51 20 100         if (!SvOK(buffer)) {
52             #if PERL_VERSION_GE(5, 25, 6)
53 3           SvPVCLEAR(buffer);
54             #else
55             sv_setpvs(buffer, "");
56             #endif
57             } else {
58             STRLEN curlen;
59 17           SvPVbyte_force(buffer, curlen);
60             (void)curlen;
61             }
62 20 50         p = offset + SvGROW(buffer, offset + length + 1u);
    100          
63             #ifdef __OpenBSD__
64             {
65             int r = getentropy(p, length);
66             assert(r == -1 || r == 0);
67             RETVAL = r == -1 ? r : length;
68             }
69             #else
70 20           RETVAL = getrandom(p, length, flags);
71             #endif
72 20 50         if (RETVAL == -1) {
73 0           XSRETURN_UNDEF;
74             }
75 20           p[RETVAL] = '\0';
76 20           SvCUR_set(buffer, offset + RETVAL);
77 20           SvUTF8_off(buffer);
78 20 50         SvSETMAGIC(buffer);
79             OUTPUT:
80             RETVAL