diff options
author | Sebastian Ramacher <s.ramacher@gmx.at> | 2012-02-03 15:26:27 +0100 |
---|---|---|
committer | Dwayne C. Litzenberger <dlitz@dlitz.net> | 2012-04-21 12:59:49 -0400 |
commit | 95d65366e9ac7e194bf8317d69785c9a5b877790 (patch) | |
tree | 52777b4b2ffbc677d4b28d044f0ad78adb6d040c | |
parent | 5f1d0abf8d615dcf8bdcf17f310f9644c8c06305 (diff) | |
download | pycrypto-95d65366e9ac7e194bf8317d69785c9a5b877790.tar.gz |
Fix DevURandomRNG to work with Python3's new I/O stack.
-rw-r--r-- | 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) |