diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2013-12-21 15:51:54 +0100 |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2013-12-21 15:51:54 +0100 |
commit | 77d9aa6feaf1c7b49975b5d21e97d1b5e5d2146e (patch) | |
tree | 116d80437b4248e8f90c1e2cf717fbb6e5c01e13 /Modules | |
parent | de4652929a2b4d49cab4b20e4afb9bc6a479bfbd (diff) | |
download | cpython-77d9aa6feaf1c7b49975b5d21e97d1b5e5d2146e.tar.gz |
Issue #20037: Avoid crashes when doing text I/O late at interpreter shutdown.
Diffstat (limited to 'Modules')
-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 9866fbe82b..be0464c4fa 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 b90a658397..8927864e8c 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 a04b48dd3a..34c2bb97bd 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 0e1e709efd..cbb2daf5c2 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 1b7cb0ff70..e3729902d8 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 fb89a17927..747f62323c 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) { |