From 7fb111bb9e53324a622c0cf87fdbaeda288b947a Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 4 Mar 2009 11:14:01 +0000 Subject: [PATCH] Fix failures introduced by buggy merge (1) --- Lib/test/test_fileio.py | 4 ++-- Modules/_fileio.c | 40 +++++++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py index 615361eeea7..498d3fc5a52 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -193,8 +193,8 @@ class OtherFileTests(unittest.TestCase): os.unlink(TESTFN) def testInvalidFd(self): - self.assertRaises(ValueError, _fileio._FileIO, -10) - self.assertRaises(OSError, _fileio._FileIO, make_bad_fd()) + self.assertRaises(ValueError, _FileIO, -10) + self.assertRaises(OSError, _FileIO, make_bad_fd()) def testBadModeArgument(self): # verify that we get a sensible error message for bad mode argument diff --git a/Modules/_fileio.c b/Modules/_fileio.c index d6c14c6ffe3..4b382fb7298 100644 --- a/Modules/_fileio.c +++ b/Modules/_fileio.c @@ -57,13 +57,15 @@ PyTypeObject PyFileIO_Type; #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) - int _PyFileIO_closed(PyObject *self) { return ((PyFileIOObject *)self)->fd < 0; } +static PyObject * +portable_lseek(int fd, PyObject *posobj, int whence); + /* Returns 0 on success, -1 with exception set on failure. */ static int internal_close(PyFileIOObject *self) @@ -156,7 +158,7 @@ check_fd(int fd) { #if defined(HAVE_FSTAT) struct stat buf; - if (fstat(fd, &buf) < 0 && errno == EBADF) { + if (!_PyVerify_fd(fd) || (fstat(fd, &buf) < 0 && errno == EBADF)) { PyObject *exc; char *msg = strerror(EBADF); exc = PyObject_CallFunction(PyExc_OSError, "(is)", @@ -176,7 +178,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) PyFileIOObject *self = (PyFileIOObject *) oself; static char *kwlist[] = {"file", "mode", "closefd", NULL}; const char *name = NULL; - PyObject *nameobj; + PyObject *nameobj, *stringobj = NULL; char *mode = "r"; char *s; #ifdef MS_WINDOWS @@ -226,26 +228,27 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) if (fd < 0) { if (PyBytes_Check(nameobj) || PyByteArray_Check(nameobj)) { - if (PyObject_AsCharBuffer(nameobj, &name, NULL) < 0) + Py_ssize_t namelen; + if (PyObject_AsCharBuffer(nameobj, &name, &namelen) < 0) return -1; } else { - PyObject *s; PyObject *u = PyUnicode_FromObject(nameobj); if (u == NULL) return -1; - s = PyUnicode_AsEncodedString( + stringobj = PyUnicode_AsEncodedString( u, Py_FileSystemDefaultEncoding, NULL); Py_DECREF(u); - if (s == NULL) + if (stringobj == NULL) return -1; - if (!PyBytes_Check(s)) { + if (!PyBytes_Check(stringobj)) { PyErr_SetString(PyExc_TypeError, "encoder failed to return bytes"); + goto error; } - name = PyBytes_AS_STRING(s); + name = PyBytes_AS_STRING(stringobj); } } @@ -312,10 +315,10 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) #endif if (fd >= 0) { - self->fd = fd; - self->closefd = closefd; if (check_fd(fd)) goto error; + self->fd = fd; + self->closefd = closefd; } else { self->closefd = 1; @@ -350,12 +353,23 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0) goto error; + if (append) { + /* For consistent behaviour, we explicitly seek to the + end of file (otherwise, it might be done only on the + first write()). */ + PyObject *pos = portable_lseek(self->fd, NULL, 2); + if (pos == NULL) + goto error; + Py_DECREF(pos); + } + goto done; error: ret = -1; done: + Py_CLEAR(stringobj); return ret; } @@ -942,14 +956,14 @@ static PyGetSetDef fileio_getsetlist[] = { PyTypeObject PyFileIO_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "FileIO", + "_io.FileIO", sizeof(PyFileIOObject), 0, (destructor)fileio_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_reserved */ (reprfunc)fileio_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */