summaryrefslogtreecommitdiffstats
path: root/Python/random.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-01-06 10:39:15 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2017-01-06 10:39:15 (GMT)
commitb27df6faa5e5b92674cdf629615595cecd33d875 (patch)
tree9181010a11b8f0197011ed075095033c86cb1632 /Python/random.c
parentde2f1ea12457780bfa4dac0f2d1ed2c8f02d591e (diff)
downloadcpython-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.c33
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;
}