From c2ec99269899f33d9c658b0291e46961f58cc410 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 6 Jul 2012 18:48:24 +0200 Subject: [PATCH] Issue #15247: FileIO now raises an error when given a file descriptor pointing to a directory. --- Lib/test/test_fileio.py | 8 ++++++++ Misc/NEWS | 3 +++ Modules/_io/fileio.c | 17 +++++------------ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py index 4d13ce5bf2c..c6863d6e7c1 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -130,6 +130,14 @@ class AutoFileTests(unittest.TestCase): else: self.fail("Should have raised IOError") + @unittest.skipIf(os.name == 'nt', "test only works on a POSIX-like system") + def testOpenDirFD(self): + fd = os.open('.', os.O_RDONLY) + with self.assertRaises(IOError) as cm: + _FileIO(fd, 'r') + os.close(fd) + self.assertEqual(cm.exception.errno, errno.EISDIR) + #A set of functions testing that we get expected behaviour if someone has #manually closed the internal file descriptor. First, a decorator: def ClosedFD(func): diff --git a/Misc/NEWS b/Misc/NEWS index 5b1b40cb86f..c5e2e92737b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -84,6 +84,9 @@ Core and Builtins Library ------- +- Issue #15247: FileIO now raises an error when given a file descriptor + pointing to a directory. + - Issue #14591: Fix bug in Random.jumpahead that could produce an invalid Mersenne Twister state on 64-bit machines. diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index e23fc6ed17d..a8567bf284e 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -137,22 +137,15 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) directories, so we need a check. */ static int -dircheck(fileio* self, const char *name) +dircheck(fileio* self, PyObject *nameobj) { #if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR) struct stat buf; if (self->fd < 0) return 0; if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) { - char *msg = strerror(EISDIR); - PyObject *exc; - if (internal_close(self)) - return -1; - - exc = PyObject_CallFunction(PyExc_IOError, "(iss)", - EISDIR, msg, name); - PyErr_SetObject(PyExc_IOError, exc); - Py_XDECREF(exc); + errno = EISDIR; + PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj); return -1; } #endif @@ -356,9 +349,9 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) PyErr_SetFromErrnoWithFilename(PyExc_IOError, name); goto error; } - if(dircheck(self, name) < 0) - goto error; } + if (dircheck(self, nameobj) < 0) + goto error; if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0) goto error;