File Coverage

blib/lib/Crypt/SysRandom.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 20 20 100.0


line stmt bran cond sub pod time code
1             package Crypt::SysRandom;
2             $Crypt::SysRandom::VERSION = '0.007';
3 2     2   215368 use strict;
  2         3  
  2         74  
4 2     2   10 use warnings;
  2         5  
  2         153  
5              
6 2     2   9 use Exporter 'import';
  2         3  
  2         82  
7             our @EXPORT_OK = 'random_bytes';
8              
9 2     2   8 use Carp ();
  2         4  
  2         20  
10 2     2   362 use Errno ();
  2         1429  
  2         651  
11              
12             if (eval { require Crypt::SysRandom::XS }) {
13             *random_bytes = \&Crypt::SysRandom::XS::random_bytes;
14             } elsif (eval { require Win32::API }) {
15             my $genrand = Win32::API->new('advapi32', 'INT SystemFunction036(PVOID RandomBuffer, ULONG RandomBufferLength)')
16             or die "Could not import SystemFunction036: $^E";
17             sub random_bytes_win32 {
18             my ($count) = @_;
19             return '' if $count == 0;
20             my $buffer = chr(0) x $count;
21             $genrand->Call($buffer, $count) or Carp::croak("Could not read random bytes");
22             return $buffer;
23             }
24             *random_bytes = \&random_bytes_win32;
25             } elsif (-e '/dev/urandom') {
26             open my $fh, '<:raw', '/dev/urandom' or die "Couldn't open /dev/urandom: $!";
27             sub random_bytes_urandom {
28             my ($count) = @_;
29             my ($result, $offset) = ('', 0);
30             while ($offset < $count) {
31             my $read = sysread $fh, $result, $count - $offset, $offset;
32             next if not defined $read and $!{EINTR};
33             Carp::croak("Could not read random bytes") if not defined $read or $read == 0;
34             $offset += $read;
35             }
36             return $result;
37             }
38             *random_bytes = \&random_bytes_urandom;
39             } else {
40             die "No source of randomness found";
41             }
42              
43             delete @Crypt::SysRandom::{qw(random_bytes_win32 random_bytes_urandom)};
44              
45             1;
46              
47             # ABSTRACT: Perl interface to system randomness
48              
49             __END__