diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2013-12-21 14:51:54 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2013-12-21 14:51:54 (GMT) |
commit | 712cb734bda0227861630b365a97dfec88798c3b (patch) | |
tree | f0e79f0b144395b5a02d32de09dca263e669ee53 /Modules/_io | |
parent | 5255b86fba38a5e22a0991772a3c1bbf3edd66cc (diff) | |
download | cpython-712cb734bda0227861630b365a97dfec88798c3b.zip cpython-712cb734bda0227861630b365a97dfec88798c3b.tar.gz cpython-712cb734bda0227861630b365a97dfec88798c3b.tar.bz2 |
Issue #20037: Avoid crashes when doing text I/O late at interpreter shutdown.
Diffstat (limited to 'Modules/_io')
-rw-r--r-- | Modules/_io/_iomodule.c | 14 | ||||
-rw-r--r-- | Modules/_io/_iomodule.h | 3 | ||||
-rw-r--r-- | Modules/_io/bufferedio.c | 4 | ||||
-rw-r--r-- | Modules/_io/fileio.c | 6 | ||||
-rw-r--r-- | Modules/_io/iobase.c | 4 | ||||
-rw-r--r-- | Modules/_io/textio.c | 9 |
6 files changed, 33 insertions, 7 deletions
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 9866fbe..be0464c 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -539,6 +539,20 @@ _PyIO_ConvertSsize_t(PyObject *obj, void *result) { } +_PyIO_State * +_PyIO_get_module_state(void) +{ + PyObject *mod = PyState_FindModule(&_PyIO_Module); + _PyIO_State *state; + if (mod == NULL || (state = IO_MOD_STATE(mod)) == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "could not find io module state " + "(interpreter shutdown?)"); + return NULL; + } + return state; +} + PyObject * _PyIO_get_locale_module(_PyIO_State *state) { diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index b90a658..8927864 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -135,8 +135,9 @@ typedef struct { } _PyIO_State; #define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod)) -#define IO_STATE IO_MOD_STATE(PyState_FindModule(&_PyIO_Module)) +#define IO_STATE() _PyIO_get_module_state() +extern _PyIO_State *_PyIO_get_module_state(void); extern PyObject *_PyIO_get_locale_module(_PyIO_State *); extern PyObject *_PyIO_str_close; diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index a04b48d..34c2bb9 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -91,7 +91,9 @@ bufferediobase_readinto(PyObject *self, PyObject *args) static PyObject * bufferediobase_unsupported(const char *message) { - PyErr_SetString(IO_STATE->unsupported_operation, message); + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); return NULL; } diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 0e1e709..cbb2daf 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -493,8 +493,10 @@ err_closed(void) static PyObject * err_mode(char *action) { - PyErr_Format(IO_STATE->unsupported_operation, - "File not open for %s", action); + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_Format(state->unsupported_operation, + "File not open for %s", action); return NULL; } diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 1b7cb0f..e372990 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -69,7 +69,9 @@ _Py_IDENTIFIER(read); static PyObject * iobase_unsupported(const char *message) { - PyErr_SetString(IO_STATE->unsupported_operation, message); + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); return NULL; } diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index fb89a17..747f623 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -45,7 +45,9 @@ PyDoc_STRVAR(textiobase_doc, static PyObject * _unsupported(const char *message) { - PyErr_SetString(IO_STATE->unsupported_operation, message); + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); return NULL; } @@ -852,7 +854,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) char *errors = NULL; char *newline = NULL; int line_buffering = 0, write_through = 0; - _PyIO_State *state = IO_STATE; + _PyIO_State *state = NULL; PyObject *res; int r; @@ -891,6 +893,9 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) if (encoding == NULL) { /* Try os.device_encoding(fileno) */ PyObject *fileno; + state = IO_STATE(); + if (state == NULL) + goto error; fileno = _PyObject_CallMethodId(buffer, &PyId_fileno, NULL); /* Ignore only AttributeError and UnsupportedOperation */ if (fileno == NULL) { |