summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2012-07-06 16:48:24 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2012-07-06 16:48:24 (GMT)
commitc2ec99269899f33d9c658b0291e46961f58cc410 (patch)
tree8895aeb396609b8cf93f8dae89c9dca98368944a
parent3b30b19e0a7b9adb37a590d257438544ff0b032c (diff)
downloadcpython-c2ec99269899f33d9c658b0291e46961f58cc410.zip
cpython-c2ec99269899f33d9c658b0291e46961f58cc410.tar.gz
cpython-c2ec99269899f33d9c658b0291e46961f58cc410.tar.bz2
Issue #15247: FileIO now raises an error when given a file descriptor pointing to a directory.
-rw-r--r--Lib/test/test_fileio.py8
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/_io/fileio.c17
3 files changed, 16 insertions, 12 deletions
diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py
index 4d13ce5..c6863d6 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 5b1b40c..c5e2e92 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 e23fc6e..a8567bf 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;