mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 21:32:31 +00:00
Perform build and magnum tuning
Building o//third_party/python now takes 5 seconds on my PC This change works towards modifying Python to use runtime dispatching when appropriate. For example, when loading the magnums in the socket module, it's a good idea to check if the magnum is zero, because that means the local system platform doesn't support it.
This commit is contained in:
parent
ee7e296339
commit
d26d7ae0e4
1028 changed files with 6576 additions and 172777 deletions
166
third_party/python/Python/random.c
vendored
166
third_party/python/Python/random.c
vendored
|
@ -1,28 +1,6 @@
|
|||
#include "Python.h"
|
||||
#ifdef MS_WINDOWS
|
||||
# include <windows.h>
|
||||
/* All sample MSDN wincrypt programs include the header below. It is at least
|
||||
* required with Min GW. */
|
||||
# include <wincrypt.h>
|
||||
#else
|
||||
# include <fcntl.h>
|
||||
# ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h>
|
||||
# endif
|
||||
# ifdef HAVE_LINUX_RANDOM_H
|
||||
# include <linux/random.h>
|
||||
# endif
|
||||
# if defined(HAVE_SYS_RANDOM_H) && (defined(HAVE_GETRANDOM) || defined(HAVE_GETENTROPY))
|
||||
# include <sys/random.h>
|
||||
# endif
|
||||
# if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL)
|
||||
# include <sys/syscall.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _Py_MEMORY_SANITIZER
|
||||
# include <sanitizer/msan_interface.h>
|
||||
#endif
|
||||
/* clang-format off */
|
||||
#include "libc/sysv/consts/grnd.h"
|
||||
#include "third_party/python/Include/Python.h"
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
int _Py_HashSecret_Initialized = 0;
|
||||
|
@ -30,59 +8,6 @@ int _Py_HashSecret_Initialized = 0;
|
|||
static int _Py_HashSecret_Initialized = 0;
|
||||
#endif
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
static HCRYPTPROV hCryptProv = 0;
|
||||
|
||||
static int
|
||||
win32_urandom_init(int raise)
|
||||
{
|
||||
/* Acquire context */
|
||||
if (!CryptAcquireContext(&hCryptProv, NULL, NULL,
|
||||
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (raise) {
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
|
||||
API. Return 0 on success, or raise an exception and return -1 on error. */
|
||||
static int
|
||||
win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
|
||||
{
|
||||
Py_ssize_t chunk;
|
||||
|
||||
if (hCryptProv == 0)
|
||||
{
|
||||
if (win32_urandom_init(raise) == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
chunk = size > INT_MAX ? INT_MAX : size;
|
||||
if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer))
|
||||
{
|
||||
/* CryptGenRandom() failed */
|
||||
if (raise) {
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
buffer += chunk;
|
||||
size -= chunk;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !MS_WINDOWS */
|
||||
|
||||
#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
|
||||
#define PY_GETRANDOM 1
|
||||
|
||||
|
@ -195,80 +120,6 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_GETENTROPY)
|
||||
#define PY_GETENTROPY 1
|
||||
|
||||
/* Fill buffer with size pseudo-random bytes generated by getentropy():
|
||||
|
||||
- Return 1 on success
|
||||
- Return 0 if getentropy() syscall is not available (failed with ENOSYS or
|
||||
EPERM).
|
||||
- Raise an exception (if raise is non-zero) and return -1 on error:
|
||||
if getentropy() failed with EINTR, raise is non-zero and the Python signal
|
||||
handler raised an exception, or if getentropy() failed with a different
|
||||
error.
|
||||
|
||||
getentropy() is retried if it failed with EINTR: interrupted by a signal. */
|
||||
static int
|
||||
py_getentropy(char *buffer, Py_ssize_t size, int raise)
|
||||
{
|
||||
/* Is getentropy() supported by the running kernel? Set to 0 if
|
||||
getentropy() failed with ENOSYS or EPERM. */
|
||||
static int getentropy_works = 1;
|
||||
|
||||
if (!getentropy_works) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
/* getentropy() is limited to returning up to 256 bytes. Call it
|
||||
multiple times if more bytes are requested. */
|
||||
Py_ssize_t len = Py_MIN(size, 256);
|
||||
int res;
|
||||
|
||||
if (raise) {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
res = getentropy(buffer, len);
|
||||
Py_END_ALLOW_THREADS
|
||||
}
|
||||
else {
|
||||
res = getentropy(buffer, len);
|
||||
}
|
||||
|
||||
if (res < 0) {
|
||||
/* ENOSYS: the syscall is not supported by the running kernel.
|
||||
EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
|
||||
or something else. */
|
||||
if (errno == ENOSYS || errno == EPERM) {
|
||||
getentropy_works = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (errno == EINTR) {
|
||||
if (raise) {
|
||||
if (PyErr_CheckSignals()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* retry getentropy() if it was interrupted by a signal */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (raise) {
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer += len;
|
||||
size -= len;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */
|
||||
|
||||
|
||||
static struct {
|
||||
int fd;
|
||||
dev_t st_dev;
|
||||
|
@ -437,12 +288,9 @@ lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
|
|||
- Return 0 on success
|
||||
- Raise an exception (if raise is non-zero) and return -1 on error
|
||||
|
||||
Used sources of entropy ordered by preference, preferred source first:
|
||||
Used sources of entropy ordered by preference:
|
||||
|
||||
- CryptGenRandom() on Windows
|
||||
- getrandom() function (ex: Linux and Solaris): call py_getrandom()
|
||||
- getentropy() function (ex: OpenBSD): call py_getentropy()
|
||||
- /dev/urandom device
|
||||
- getrandom()
|
||||
|
||||
Read from the /dev/urandom device if getrandom() or getentropy() function
|
||||
is not available or does not work.
|
||||
|
@ -499,11 +347,7 @@ pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise)
|
|||
#else
|
||||
|
||||
#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
|
||||
#ifdef PY_GETRANDOM
|
||||
res = py_getrandom(buffer, size, blocking, raise);
|
||||
#else
|
||||
res = py_getentropy(buffer, size, raise);
|
||||
#endif
|
||||
if (res < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue