Issue #15247: FileIO now raises an error when given a file descriptor pointing to a directory.

This commit is contained in:
Antoine Pitrou 2012-07-06 18:48:24 +02:00
parent 3b30b19e0a
commit c2ec992698
3 changed files with 16 additions and 12 deletions

View File

@ -130,6 +130,14 @@ class AutoFileTests(unittest.TestCase):
else: else:
self.fail("Should have raised IOError") 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 #A set of functions testing that we get expected behaviour if someone has
#manually closed the internal file descriptor. First, a decorator: #manually closed the internal file descriptor. First, a decorator:
def ClosedFD(func): def ClosedFD(func):

View File

@ -84,6 +84,9 @@ Core and Builtins
Library 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 - Issue #14591: Fix bug in Random.jumpahead that could produce an invalid
Mersenne Twister state on 64-bit machines. Mersenne Twister state on 64-bit machines.

View File

@ -137,22 +137,15 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
directories, so we need a check. */ directories, so we need a check. */
static int static int
dircheck(fileio* self, const char *name) dircheck(fileio* self, PyObject *nameobj)
{ {
#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR) #if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
struct stat buf; struct stat buf;
if (self->fd < 0) if (self->fd < 0)
return 0; return 0;
if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) { if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
char *msg = strerror(EISDIR); errno = EISDIR;
PyObject *exc; PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
if (internal_close(self))
return -1;
exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
EISDIR, msg, name);
PyErr_SetObject(PyExc_IOError, exc);
Py_XDECREF(exc);
return -1; return -1;
} }
#endif #endif
@ -356,9 +349,9 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
PyErr_SetFromErrnoWithFilename(PyExc_IOError, name); PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
goto error; goto error;
} }
if(dircheck(self, name) < 0)
goto error;
} }
if (dircheck(self, nameobj) < 0)
goto error;
if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0) if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0)
goto error; goto error;