diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2017-01-06 10:39:15 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2017-01-06 10:39:15 (GMT) |
commit | b27df6faa5e5b92674cdf629615595cecd33d875 (patch) | |
tree | 9181010a11b8f0197011ed075095033c86cb1632 /Python/random.c | |
parent | de2f1ea12457780bfa4dac0f2d1ed2c8f02d591e (diff) | |
download | cpython-b27df6faa5e5b92674cdf629615595cecd33d875.zip cpython-b27df6faa5e5b92674cdf629615595cecd33d875.tar.gz cpython-b27df6faa5e5b92674cdf629615595cecd33d875.tar.bz2 |
Issue #29157: enhance py_getrandom() documentation
Diffstat (limited to 'Python/random.c')
-rw-r--r-- | Python/random.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/Python/random.c b/Python/random.c index bc96226..c97d5e7 100644 --- a/Python/random.c +++ b/Python/random.c @@ -82,14 +82,18 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) #if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL) #define PY_GETRANDOM 1 -/* Call getrandom() +/* Call getrandom() to get random bytes: + - Return 1 on success - - Return 0 if getrandom() syscall is not available (failed with ENOSYS or - EPERM) or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom - not initialized yet) and raise=0. + - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM), + or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not + initialized yet) and raise=0. - Raise an exception (if raise is non-zero) and return -1 on error: - getrandom() failed with EINTR and the Python signal handler raised an - exception, or getrandom() failed with a different error. */ + if getrandom() failed with EINTR, raise is non-zero and the Python signal + handler raised an exception, or if getrandom() failed with a different + error. + + getrandom() is retried if it failed with EINTR: interrupted by a signal. */ static int py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) { @@ -110,7 +114,8 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) while (0 < size) { #ifdef sun /* Issue #26735: On Solaris, getrandom() is limited to returning up - to 1024 bytes */ + to 1024 bytes. Call it multiple times if more bytes are + requested. */ n = Py_MIN(size, 1024); #else n = Py_MIN(size, LONG_MAX); @@ -141,18 +146,19 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) #endif if (n < 0) { - /* ENOSYS: getrandom() syscall not supported by the kernel (but - * maybe supported by the host which built Python). EPERM: - * getrandom() syscall blocked by SECCOMP or something else. */ + /* ENOSYS: the syscall is not supported by the kernel. + EPERM: the syscall is blocked by a security policy (ex: SECCOMP) + or something else. */ if (errno == ENOSYS || errno == EPERM) { getrandom_works = 0; return 0; } /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom - is not initialiazed yet. For _PyRandom_Init(), we ignore their + is not initialiazed yet. For _PyRandom_Init(), we ignore the error and fall back on reading /dev/urandom which never blocks, - even if the system urandom is not initialized yet. */ + even if the system urandom is not initialized yet: + see the PEP 524. */ if (errno == EAGAIN && !raise && !blocking) { return 0; } @@ -313,9 +319,10 @@ dev_urandom(char *buffer, Py_ssize_t size, int raise) fd = _Py_open("/dev/urandom", O_RDONLY); if (fd < 0) { if (errno == ENOENT || errno == ENXIO || - errno == ENODEV || errno == EACCES) + errno == ENODEV || errno == EACCES) { PyErr_SetString(PyExc_NotImplementedError, "/dev/urandom (or equivalent) not found"); + } /* otherwise, keep the OSError exception raised by _Py_open() */ return -1; } |