diff options
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r-- | Modules/posixmodule.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index beea9e0..2dc6d7b 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -133,6 +133,13 @@ corresponding Unix manual entries for more information on calls."); #include <sys/sysctl.h> #endif +#ifdef HAVE_LINUX_RANDOM_H +# include <linux/random.h> +#endif +#ifdef HAVE_GETRANDOM_SYSCALL +# include <sys/syscall.h> +#endif + #if defined(MS_WINDOWS) # define TERMSIZE_USE_CONIO #elif defined(HAVE_SYS_IOCTL_H) @@ -12421,6 +12428,59 @@ os_fspath_impl(PyObject *module, PyObject *path) return PyOS_FSPath(path); } +#ifdef HAVE_GETRANDOM_SYSCALL +/*[clinic input] +os.getrandom + + size: Py_ssize_t + flags: int=0 + +Obtain a series of random bytes. +[clinic start generated code]*/ + +static PyObject * +os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags) +/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/ +{ + char *buffer; + Py_ssize_t n; + PyObject *bytes; + + if (size < 0) { + errno = EINVAL; + return posix_error(); + } + + buffer = PyMem_Malloc(size); + if (buffer == NULL) { + PyErr_NoMemory(); + return NULL; + } + + while (1) { + n = syscall(SYS_getrandom, buffer, size, flags); + if (n < 0 && errno == EINTR) { + if (PyErr_CheckSignals() < 0) { + return NULL; + } + continue; + } + break; + } + + if (n < 0) { + PyMem_Free(buffer); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + bytes = PyBytes_FromStringAndSize(buffer, n); + PyMem_Free(buffer); + + return bytes; +} +#endif /* HAVE_GETRANDOM_SYSCALL */ + #include "clinic/posixmodule.c.h" /*[clinic input] @@ -12621,6 +12681,7 @@ static PyMethodDef posix_methods[] = { METH_VARARGS | METH_KEYWORDS, posix_scandir__doc__}, OS_FSPATH_METHODDEF + OS_GETRANDOM_METHODDEF {NULL, NULL} /* Sentinel */ }; @@ -13066,6 +13127,11 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1; #endif +#ifdef HAVE_GETRANDOM_SYSCALL + if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1; + if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1; +#endif + return 0; } |