@@ -57,13 +57,15 @@ PyTypeObject PyFileIO_Type;
5757
5858#define PyFileIO_Check (op ) (PyObject_TypeCheck((op), &PyFileIO_Type))
5959
60-
6160int
6261_PyFileIO_closed (PyObject * self )
6362{
6463 return ((PyFileIOObject * )self )-> fd < 0 ;
6564}
6665
66+ static PyObject *
67+ portable_lseek (int fd , PyObject * posobj , int whence );
68+
6769/* Returns 0 on success, -1 with exception set on failure. */
6870static int
6971internal_close (PyFileIOObject * self )
@@ -156,7 +158,7 @@ check_fd(int fd)
156158{
157159#if defined(HAVE_FSTAT )
158160 struct stat buf ;
159- if (fstat (fd , & buf ) < 0 && errno == EBADF ) {
161+ if (! _PyVerify_fd ( fd ) || ( fstat (fd , & buf ) < 0 && errno == EBADF ) ) {
160162 PyObject * exc ;
161163 char * msg = strerror (EBADF );
162164 exc = PyObject_CallFunction (PyExc_OSError , "(is)" ,
@@ -176,7 +178,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
176178 PyFileIOObject * self = (PyFileIOObject * ) oself ;
177179 static char * kwlist [] = {"file" , "mode" , "closefd" , NULL };
178180 const char * name = NULL ;
179- PyObject * nameobj ;
181+ PyObject * nameobj , * stringobj = NULL ;
180182 char * mode = "r" ;
181183 char * s ;
182184#ifdef MS_WINDOWS
@@ -226,26 +228,27 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
226228 if (fd < 0 )
227229 {
228230 if (PyBytes_Check (nameobj ) || PyByteArray_Check (nameobj )) {
229- if (PyObject_AsCharBuffer (nameobj , & name , NULL ) < 0 )
231+ Py_ssize_t namelen ;
232+ if (PyObject_AsCharBuffer (nameobj , & name , & namelen ) < 0 )
230233 return -1 ;
231234 }
232235 else {
233- PyObject * s ;
234236 PyObject * u = PyUnicode_FromObject (nameobj );
235237
236238 if (u == NULL )
237239 return -1 ;
238240
239- s = PyUnicode_AsEncodedString (
241+ stringobj = PyUnicode_AsEncodedString (
240242 u , Py_FileSystemDefaultEncoding , NULL );
241243 Py_DECREF (u );
242- if (s == NULL )
244+ if (stringobj == NULL )
243245 return -1 ;
244- if (!PyBytes_Check (s )) {
246+ if (!PyBytes_Check (stringobj )) {
245247 PyErr_SetString (PyExc_TypeError ,
246248 "encoder failed to return bytes" );
249+ goto error ;
247250 }
248- name = PyBytes_AS_STRING (s );
251+ name = PyBytes_AS_STRING (stringobj );
249252 }
250253 }
251254
@@ -312,10 +315,10 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
312315#endif
313316
314317 if (fd >= 0 ) {
315- self -> fd = fd ;
316- self -> closefd = closefd ;
317318 if (check_fd (fd ))
318319 goto error ;
320+ self -> fd = fd ;
321+ self -> closefd = closefd ;
319322 }
320323 else {
321324 self -> closefd = 1 ;
@@ -350,12 +353,23 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
350353 if (PyObject_SetAttrString ((PyObject * )self , "name" , nameobj ) < 0 )
351354 goto error ;
352355
356+ if (append ) {
357+ /* For consistent behaviour, we explicitly seek to the
358+ end of file (otherwise, it might be done only on the
359+ first write()). */
360+ PyObject * pos = portable_lseek (self -> fd , NULL , 2 );
361+ if (pos == NULL )
362+ goto error ;
363+ Py_DECREF (pos );
364+ }
365+
353366 goto done ;
354367
355368 error :
356369 ret = -1 ;
357370
358371 done :
372+ Py_CLEAR (stringobj );
359373 return ret ;
360374}
361375
@@ -942,14 +956,14 @@ static PyGetSetDef fileio_getsetlist[] = {
942956
943957PyTypeObject PyFileIO_Type = {
944958 PyVarObject_HEAD_INIT (NULL , 0 )
945- "FileIO" ,
959+ "_io. FileIO" ,
946960 sizeof (PyFileIOObject ),
947961 0 ,
948962 (destructor )fileio_dealloc , /* tp_dealloc */
949963 0 , /* tp_print */
950964 0 , /* tp_getattr */
951965 0 , /* tp_setattr */
952- 0 , /* tp_compare */
966+ 0 , /* tp_reserved */
953967 (reprfunc )fileio_repr , /* tp_repr */
954968 0 , /* tp_as_number */
955969 0 , /* tp_as_sequence */
0 commit comments