dev_urandom_python() retries read() if it fails with EINTR, but Python signal handlers are not called: PyErr_CheckSignals() is not called. It's important be able to interrupt a function by a signal, especially if it's blocking.
We need maybe a new _Py_read() function which would retry on EINTR. The code can be based on posix_read(). For open(), there is already _Py_open() which retries on EINTR (since the changeset ed25e945cdc2, issue #23694). It can be useful for FileIO.read().
dev_urandom_noraise() retries on EINTR without calling PyErr_CheckSignals(). It may be acceptable since this function is only called by _PyRandom_Init() at an early stage of Python initialization. Or maybe EINTR should call Py_FatalError()?
On Linux 3.18 (Fedora 21 with kernel 3.18.7-200.fc21.x86_64), reading 1 GB from /dev/urandom or getrandom() returns 0x1ffffff bytes (32 MB). It's not an issue, os.urandom() continues to read until it gets enough data.
I tried to interrupt os.urandom() on Python 3.4 (read) and Python 3.5 (getrandom): reading from /dev/urandom using a file descriptor or getrandom() have the same behaviour, none fail with EINTR. I checked syscalls using strace.
It looks like getrandom() only fails with EINTR when flags=GRND_RANDOM. So this issue is maybe more theoric. |