Issue #15247: FileIO now raises an error when given a file descriptor pointing to...
authorAntoine Pitrou <solipsis@pitrou.net>
Fri, 6 Jul 2012 16:48:24 +0000 (18:48 +0200)
committerAntoine Pitrou <solipsis@pitrou.net>
Fri, 6 Jul 2012 16:48:24 +0000 (18:48 +0200)
Lib/test/test_fileio.py
Misc/NEWS
Modules/_io/fileio.c

index 4d13ce5bf2cda4fc97592a157c358b78fd601293..c6863d6e7c1e6e2753ce0f757f0843e0340d2c1f 100644 (file)
@@ -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):
index 5b1b40cb86f62b06cdf2263210fd99fad7d23772..c5e2e92737bbde2720f4b8ac78c1fa748bc8a5a6 100644 (file)
--- 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.
 
index e23fc6ed17d6021a86c0eb4de5011beb151ae5f5..a8567bf284ead0484d1317fa76efb3d592a8f033 100644 (file)
@@ -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;