diff options
author | Gregory P. Smith <greg@krypto.org> | 2017-01-22 17:29:44 -0800 |
---|---|---|
committer | Gregory P. Smith <greg@krypto.org> | 2017-01-22 17:29:44 -0800 |
commit | d71a238820a6e746c7bb1995d8f236b40904924d (patch) | |
tree | 1da08aa6698b4a9dcaa5e90d9541b78ac11e1650 /Modules/_randommodule.c | |
parent | d49be132fb4eb2d302592ebd84fafc4a1c98e531 (diff) | |
parent | 424881df2c661ba4238f9f56f273a5f4974f74d4 (diff) | |
download | cpython-d71a238820a6e746c7bb1995d8f236b40904924d.tar.gz |
Issue #29335: Fix subprocess.Popen.wait() when the child process has
exited to a stopped instead of terminated state (ex: when under ptrace).
Diffstat (limited to 'Modules/_randommodule.c')
-rw-r--r-- | Modules/_randommodule.c | 101 |
1 files changed, 68 insertions, 33 deletions
diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 95ad4a429a..0d3282db8f 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -68,9 +68,8 @@ #include "Python.h" #include <time.h> /* for seeding to current time */ - -#ifndef PY_UINT32_T -# error "Failed to find an exact-width 32-bit integer type" +#ifdef HAVE_PROCESS_H +# include <process.h> /* needed for getpid() */ #endif /* Period parameters -- These are all magic. Don't change. */ @@ -83,7 +82,7 @@ typedef struct { PyObject_HEAD int index; - PY_UINT32_T state[N]; + uint32_t state[N]; } RandomObject; static PyTypeObject Random_Type; @@ -95,13 +94,13 @@ static PyTypeObject Random_Type; /* generates a random number on [0,0xffffffff]-interval */ -static PY_UINT32_T +static uint32_t genrand_int32(RandomObject *self) { - PY_UINT32_T y; - static PY_UINT32_T mag01[2]={0x0U, MATRIX_A}; + uint32_t y; + static const uint32_t mag01[2] = {0x0U, MATRIX_A}; /* mag01[x] = x * MATRIX_A for x=0,1 */ - PY_UINT32_T *mt; + uint32_t *mt; mt = self->state; if (self->index >= N) { /* generate N words at one time */ @@ -136,21 +135,21 @@ genrand_int32(RandomObject *self) * optimize the division away at compile-time. 67108864 is 2**26. In * effect, a contains 27 random bits shifted left 26, and b fills in the * lower 26 bits of the 53-bit numerator. - * The orginal code credited Isaku Wada for this algorithm, 2002/01/09. + * The original code credited Isaku Wada for this algorithm, 2002/01/09. */ static PyObject * random_random(RandomObject *self) { - PY_UINT32_T a=genrand_int32(self)>>5, b=genrand_int32(self)>>6; + uint32_t a=genrand_int32(self)>>5, b=genrand_int32(self)>>6; return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0)); } /* initializes mt[N] with a seed */ static void -init_genrand(RandomObject *self, PY_UINT32_T s) +init_genrand(RandomObject *self, uint32_t s) { int mti; - PY_UINT32_T *mt; + uint32_t *mt; mt = self->state; mt[0]= s; @@ -169,11 +168,11 @@ init_genrand(RandomObject *self, PY_UINT32_T s) /* initialize by an array with array-length */ /* init_key is the array for initializing keys */ /* key_length is its length */ -static PyObject * -init_by_array(RandomObject *self, PY_UINT32_T init_key[], size_t key_length) +static void +init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length) { size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */ - PY_UINT32_T *mt; + uint32_t *mt; mt = self->state; init_genrand(self, 19650218U); @@ -181,21 +180,19 @@ init_by_array(RandomObject *self, PY_UINT32_T init_key[], size_t key_length) k = (N>key_length ? N : key_length); for (; k; k--) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525U)) - + init_key[j] + (PY_UINT32_T)j; /* non linear */ + + init_key[j] + (uint32_t)j; /* non linear */ i++; j++; if (i>=N) { mt[0] = mt[N-1]; i=1; } if (j>=key_length) j=0; } for (k=N-1; k; k--) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941U)) - - (PY_UINT32_T)i; /* non linear */ + - (uint32_t)i; /* non linear */ i++; if (i>=N) { mt[0] = mt[N-1]; i=1; } } mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ - Py_INCREF(Py_None); - return Py_None; } /* @@ -203,12 +200,43 @@ init_by_array(RandomObject *self, PY_UINT32_T init_key[], size_t key_length) * Twister download. */ +static int +random_seed_urandom(RandomObject *self) +{ + PY_UINT32_T key[N]; + + if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) { + return -1; + } + init_by_array(self, key, Py_ARRAY_LENGTH(key)); + return 0; +} + +static void +random_seed_time_pid(RandomObject *self) +{ + _PyTime_t now; + uint32_t key[5]; + + now = _PyTime_GetSystemClock(); + key[0] = (PY_UINT32_T)(now & 0xffffffffU); + key[1] = (PY_UINT32_T)(now >> 32); + + key[2] = (PY_UINT32_T)getpid(); + + now = _PyTime_GetMonotonicClock(); + key[3] = (PY_UINT32_T)(now & 0xffffffffU); + key[4] = (PY_UINT32_T)(now >> 32); + + init_by_array(self, key, Py_ARRAY_LENGTH(key)); +} + static PyObject * random_seed(RandomObject *self, PyObject *args) { PyObject *result = NULL; /* guilty until proved innocent */ PyObject *n = NULL; - PY_UINT32_T *key = NULL; + uint32_t *key = NULL; size_t bits, keyused; int res; PyObject *arg = NULL; @@ -216,14 +244,17 @@ random_seed(RandomObject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "seed", 0, 1, &arg)) return NULL; - if (arg == NULL || arg == Py_None) { - time_t now; + if (arg == NULL || arg == Py_None) { + if (random_seed_urandom(self) < 0) { + PyErr_Clear(); - time(&now); - init_genrand(self, (PY_UINT32_T)now); - Py_INCREF(Py_None); - return Py_None; + /* Reading system entropy failed, fall back on the worst entropy: + use the current time and process identifier. */ + random_seed_time_pid(self); + } + Py_RETURN_NONE; } + /* This algorithm relies on the number being unsigned. * So: if the arg is a PyLong, use its absolute value. * Otherwise use its hash value, cast to unsigned. @@ -248,7 +279,7 @@ random_seed(RandomObject *self, PyObject *args) keyused = bits == 0 ? 1 : (bits - 1) / 32 + 1; /* Convert seed to byte sequence. */ - key = (PY_UINT32_T *)PyMem_Malloc((size_t)4 * keyused); + key = (uint32_t *)PyMem_Malloc((size_t)4 * keyused); if (key == NULL) { PyErr_NoMemory(); goto Done; @@ -267,13 +298,17 @@ random_seed(RandomObject *self, PyObject *args) size_t i, j; /* Reverse an array. */ for (i = 0, j = keyused - 1; i < j; i++, j--) { - PY_UINT32_T tmp = key[i]; + uint32_t tmp = key[i]; key[i] = key[j]; key[j] = tmp; } } #endif - result = init_by_array(self, key, keyused); + init_by_array(self, key, keyused); + + Py_INCREF(Py_None); + result = Py_None; + Done: Py_XDECREF(n); PyMem_Free(key); @@ -329,7 +364,7 @@ random_setstate(RandomObject *self, PyObject *state) element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i)); if (element == (unsigned long)-1 && PyErr_Occurred()) return NULL; - self->state[i] = (PY_UINT32_T)element; + self->state[i] = (uint32_t)element; } index = PyLong_AsLong(PyTuple_GET_ITEM(state, i)); @@ -349,8 +384,8 @@ static PyObject * random_getrandbits(RandomObject *self, PyObject *args) { int k, i, words; - PY_UINT32_T r; - PY_UINT32_T *wordarray; + uint32_t r; + uint32_t *wordarray; PyObject *result; if (!PyArg_ParseTuple(args, "i:getrandbits", &k)) @@ -366,7 +401,7 @@ random_getrandbits(RandomObject *self, PyObject *args) return PyLong_FromUnsignedLong(genrand_int32(self) >> (32 - k)); words = (k - 1) / 32 + 1; - wordarray = (PY_UINT32_T *)PyMem_Malloc(words * 4); + wordarray = (uint32_t *)PyMem_Malloc(words * 4); if (wordarray == NULL) { PyErr_NoMemory(); return NULL; |