diff options
-rw-r--r-- | Lib/test/test_fileio.py | 8 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | 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 99f2069..906952c 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -128,6 +128,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): @@ -23,6 +23,9 @@ Core and Builtins Library ------- +- Issue #15247: FileIO now raises an error when given a file descriptor + pointing to a directory. + - Issue #15261: Stop os.stat(fd) crashing on Windows when fd not open. - Issue #15166: Implement imp.get_tag() using sys.implementation.cache_tag. diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 198392f..6e0bbee 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -169,22 +169,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 @@ -406,9 +399,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 defined(MS_WINDOWS) || defined(__CYGWIN__) /* don't translate newlines (\r\n <=> \n) */ |