Skip to content

Commit 605ee2e

Browse files
committed
Issue #29157: enhance py_getrandom() documentation
1 parent 006857a commit 605ee2e

1 file changed

Lines changed: 20 additions & 13 deletions

File tree

Python/random.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,18 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
8282
#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
8383
#define PY_GETRANDOM 1
8484

85-
/* Call getrandom()
85+
/* Call getrandom() to get random bytes:
86+
8687
- Return 1 on success
87-
- Return 0 if getrandom() syscall is not available (failed with ENOSYS or
88-
EPERM) or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom
89-
not initialized yet) and raise=0.
88+
- Return 0 if getrandom() is not available (failed with ENOSYS or EPERM),
89+
or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not
90+
initialized yet) and raise=0.
9091
- Raise an exception (if raise is non-zero) and return -1 on error:
91-
getrandom() failed with EINTR and the Python signal handler raised an
92-
exception, or getrandom() failed with a different error. */
92+
if getrandom() failed with EINTR, raise is non-zero and the Python signal
93+
handler raised an exception, or if getrandom() failed with a different
94+
error.
95+
96+
getrandom() is retried if it failed with EINTR: interrupted by a signal. */
9397
static int
9498
py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
9599
{
@@ -110,7 +114,8 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
110114
while (0 < size) {
111115
#ifdef sun
112116
/* Issue #26735: On Solaris, getrandom() is limited to returning up
113-
to 1024 bytes */
117+
to 1024 bytes. Call it multiple times if more bytes are
118+
requested. */
114119
n = Py_MIN(size, 1024);
115120
#else
116121
n = Py_MIN(size, LONG_MAX);
@@ -141,18 +146,19 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
141146
#endif
142147

143148
if (n < 0) {
144-
/* ENOSYS: getrandom() syscall not supported by the kernel (but
145-
* maybe supported by the host which built Python). EPERM:
146-
* getrandom() syscall blocked by SECCOMP or something else. */
149+
/* ENOSYS: the syscall is not supported by the kernel.
150+
EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
151+
or something else. */
147152
if (errno == ENOSYS || errno == EPERM) {
148153
getrandom_works = 0;
149154
return 0;
150155
}
151156

152157
/* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom
153-
is not initialiazed yet. For _PyRandom_Init(), we ignore their
158+
is not initialiazed yet. For _PyRandom_Init(), we ignore the
154159
error and fall back on reading /dev/urandom which never blocks,
155-
even if the system urandom is not initialized yet. */
160+
even if the system urandom is not initialized yet:
161+
see the PEP 524. */
156162
if (errno == EAGAIN && !raise && !blocking) {
157163
return 0;
158164
}
@@ -313,9 +319,10 @@ dev_urandom(char *buffer, Py_ssize_t size, int raise)
313319
fd = _Py_open("/dev/urandom", O_RDONLY);
314320
if (fd < 0) {
315321
if (errno == ENOENT || errno == ENXIO ||
316-
errno == ENODEV || errno == EACCES)
322+
errno == ENODEV || errno == EACCES) {
317323
PyErr_SetString(PyExc_NotImplementedError,
318324
"/dev/urandom (or equivalent) not found");
325+
}
319326
/* otherwise, keep the OSError exception raised by _Py_open() */
320327
return -1;
321328
}

0 commit comments

Comments
 (0)