File Coverage

blib/lib/Sys/GetRandom/PP.pm
Criterion Covered Total %
statement 38 41 92.6
branch 8 16 50.0
condition 3 9 33.3
subroutine 7 7 100.0
pod 2 2 100.0
total 58 75 77.3


line stmt bran cond sub pod time code
1             package Sys::GetRandom::PP;
2 1     1   182597 use strict;
  1         1  
  1         27  
3 1     1   3 use warnings;
  1         5  
  1         39  
4              
5 1     1   3 use Exporter qw(import);
  1         1  
  1         21  
6 1     1   3 use Carp qw(croak);
  1         2  
  1         252  
7              
8 1         2 use constant do {
9 1         5 my %bits_getrandom = (
10             'dragonfly' => 550,
11             'freebsd' => 563,
12             'midnightbsd' => 563,
13             'netbsd' => 91,
14             'solaris' => 126,
15             'aarch64-linux' => 278,
16             'armv6l-linux' => 384,
17             'i686-linux' => 355,
18             'x86_64-linux' => 318,
19             );
20 1   33     5 my $getrandom = $bits_getrandom{$^O} || do {
21             require Config;
22             my ($arch) = $Config::Config{archname} =~ m{^(\w+-\w+)};
23             $bits_getrandom{$arch} || die "Unsupported platform: $arch"
24             };
25             +{
26 1         388 _SYS_getrandom => $getrandom,
27             GRND_NONBLOCK => 1,
28             GRND_RANDOM => 2,
29             }
30 1     1   5 };
  1         1  
31              
32             our $VERSION = '0.06';
33              
34             our @EXPORT_OK = qw(
35             GRND_RANDOM
36             GRND_NONBLOCK
37             getrandom
38             random_bytes
39             );
40              
41             sub getrandom ($$;$) {
42 4 50 33 4 1 142935 if (@_ < 2 || @_ > 3) {
43 0         0 croak 'Usage: ' . __PACKAGE__ . '::getrandom($buffer, $length, $flags = 0)';
44             }
45 4         8 my $bufref = \$_[0];
46 4         9 my (undef, $length, $flags) = @_;
47 4         9 $length |= 0;
48 4         6 $flags |= 0;
49 4         13 $$bufref .= '';
50 4         16 utf8::downgrade $$bufref;
51 4         8 my $dlen = $length - length $$bufref;
52 4 100       16 $$bufref .= $dlen > 0 ? "\0" x $dlen : '';
53 4         40 my $r = syscall _SYS_getrandom, $$bufref, $length, $flags;
54 4 50       11 if ($r == -1) {
55 0 0       0 substr($$bufref, -$dlen) = '' if $dlen > 0;
56 0         0 return undef;
57             }
58 4         9 substr($$bufref, $r) = '';
59 4         25 $r
60             }
61              
62             sub random_bytes {
63 1     1 1 4 my ($n) = @_;
64 1         8 $n |= 0;
65 1 50 33     9 $n >= 0 && $n <= 256
66             or croak "Argument to random_bytes() must be an integer between 0 and 256, not $n";
67 1 50       4 return '' if $n == 0;
68 1 50       29 defined(my $r = getrandom(my $buf, $n))
69             or die "Internal error: getrandom(\$buf, $n) failed: $!";
70 1 50       4 $r == $n
71             or die "Internal error: getrandom(\$buf, $n) returned $r";
72 1         7 $buf
73             }
74              
75             1
76             __END__