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
61
62
63
64
65
66
67
68
|
>From 00160026b80399b962ea0c367aa5b7ec55cbc9a8 Mon Sep 17 00:00:00 2001
From: Sebastian Ramacher <s.ramacher@gmx.at>
Date: Fri, 3 Feb 2012 15:26:27 +0100
Subject: [PATCH] Fix DevURandomRNG to work with Python3's new I/O stack.
---
lib/Crypto/Random/OSRNG/posix.py | 27 +++++++++++++++++++++++++--
1 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/lib/Crypto/Random/OSRNG/posix.py b/lib/Crypto/Random/OSRNG/posix.py
index f88cd77..ca6ac05 100644
--- a/lib/Crypto/Random/OSRNG/posix.py
+++ b/lib/Crypto/Random/OSRNG/posix.py
@@ -25,10 +25,12 @@
__revision__ = "$Id$"
__all__ = ['DevURandomRNG']
+import errno
import os
import stat
from rng_base import BaseRNG
+from Crypto.Util.py3compat import b
class DevURandomRNG(BaseRNG):
@@ -46,7 +48,6 @@ class DevURandomRNG(BaseRNG):
raise TypeError("%r is not a character special device" % (self.name,))
self.__file = f
- self._read = f.read
BaseRNG.__init__(self)
@@ -54,7 +55,29 @@ class DevURandomRNG(BaseRNG):
self.__file.close()
def _read(self, N):
- return self.__file.read(N)
+ # Starting with Python 3 open with buffering=0 returns a FileIO object.
+ # FileIO.read behaves like read(2) and not like fread(3) and thus we
+ # have to handle the case that read returns less data as requested here
+ # more carefully.
+ data = b("")
+ while len(data) < N:
+ try:
+ d = self.__file.read(N - len(data))
+ except IOError, e:
+ # read(2) has been interrupted by a signal; redo the read
+ if e.errno == errno.EINTR:
+ continue
+ raise
+
+ if d is None:
+ # __file is in non-blocking mode and no data is available
+ return data
+ if len(d) == 0:
+ # __file is in blocking mode and arrived at EOF
+ return data
+
+ data += d
+ return data
def new(*args, **kwargs):
return DevURandomRNG(*args, **kwargs)
--
1.7.9
|