diff options
author | Benjamin Peterson <benjamin@python.org> | 2014-04-14 23:45:46 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2014-04-14 23:45:46 (GMT) |
commit | 5c863bf93809cefeb4469512eadac291b7046051 (patch) | |
tree | 7558bb2d632c47f29cc245e599718f3fad49b231 /Modules | |
parent | f609a3dc1830bab171742cffa95dac289b48d9c2 (diff) | |
download | cpython-5c863bf93809cefeb4469512eadac291b7046051.zip cpython-5c863bf93809cefeb4469512eadac291b7046051.tar.gz cpython-5c863bf93809cefeb4469512eadac291b7046051.tar.bz2 |
when an exception is raised in fdopen, never close the fd (changing on my mind on #21191)
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/posixmodule.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 168f7f4..7a5ef1c 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6841,19 +6841,37 @@ posix_fdopen(PyObject *self, PyObject *args) /* Sanitize mode. See fileobject.c */ mode = PyMem_MALLOC(strlen(orgmode)+3); if (!mode) { - close(fd); PyErr_NoMemory(); return NULL; } strcpy(mode, orgmode); if (_PyFile_SanitizeMode(mode)) { - close(fd); PyMem_FREE(mode); return NULL; } if (!_PyVerify_fd(fd)) { - posix_error(); - close(fd); + PyMem_FREE(mode); + return posix_error(); + } +#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR) + { + struct stat buf; + if (fstat(fd, &buf) == 0 && S_ISDIR(buf.st_mode)) { + PyMem_FREE(mode); + char *msg = strerror(EISDIR); + PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(isO)", + EISDIR, msg, "<fdopen>"); + PyErr_SetObject(PyExc_IOError, exc); + Py_XDECREF(exc); + return NULL; + } + } +#endif + /* The dummy filename used here must be kept in sync with the value + tested against in gzip.GzipFile.__init__() - see issue #13781. */ + f = PyFile_FromFile(NULL, "<fdopen>", orgmode, fclose); + if (f == NULL) { + PyMem_FREE(mode); return NULL; } Py_BEGIN_ALLOW_THREADS @@ -6876,16 +6894,11 @@ posix_fdopen(PyObject *self, PyObject *args) #endif Py_END_ALLOW_THREADS PyMem_FREE(mode); - if (fp == NULL) { - posix_error(); - close(fd); - return NULL; - } - /* The dummy filename used here must be kept in sync with the value - tested against in gzip.GzipFile.__init__() - see issue #13781. */ - f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose); - if (f != NULL) - PyFile_SetBufSize(f, bufsize); + if (fp == NULL) + return posix_error(); + /* We now know we will succeed, so initialize the file object. */ + ((PyFileObject *)f)->f_fp = fp; + PyFile_SetBufSize(f, bufsize); return f; } |