blob: 3c0b7529323e4e2e3410dec3450427dd550daad0 [file] [log] [blame]
Guido van Rossuma9e20242007-03-08 00:43:48 +00001/* Author: Daniel Stutzbach */
2
3#define PY_SSIZE_T_CLEAN
4#include "Python.h"
Antoine Pitroue033e062010-10-29 10:38:18 +00005#include "structmember.h"
Benjamin Peterson2614cda2010-03-21 22:36:19 +00006#ifdef HAVE_SYS_TYPES_H
Guido van Rossuma9e20242007-03-08 00:43:48 +00007#include <sys/types.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +00008#endif
9#ifdef HAVE_SYS_STAT_H
Guido van Rossuma9e20242007-03-08 00:43:48 +000010#include <sys/stat.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +000011#endif
Steve Dowerbfce0f92016-12-28 15:41:09 -080012#ifdef HAVE_IO_H
13#include <io.h>
14#endif
Benjamin Peterson2614cda2010-03-21 22:36:19 +000015#ifdef HAVE_FCNTL_H
Guido van Rossuma9e20242007-03-08 00:43:48 +000016#include <fcntl.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +000017#endif
Guido van Rossuma9e20242007-03-08 00:43:48 +000018#include <stddef.h> /* For offsetof */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000019#include "_iomodule.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +000020
21/*
22 * Known likely problems:
23 *
24 * - Files larger then 2**32-1
25 * - Files with unicode filenames
26 * - Passing numbers greater than 2**32-1 when an integer is expected
27 * - Making it work on Windows and other oddball platforms
28 *
29 * To Do:
30 *
31 * - autoconfify header file inclusion
Guido van Rossuma9e20242007-03-08 00:43:48 +000032 */
33
34#ifdef MS_WINDOWS
35/* can simulate truncate with Win32 API functions; see file_truncate */
Thomas Hellerfdeee3a2007-07-12 11:21:36 +000036#define HAVE_FTRUNCATE
Guido van Rossuma9e20242007-03-08 00:43:48 +000037#define WIN32_LEAN_AND_MEAN
38#include <windows.h>
39#endif
40
Christian Heimesa872de52008-12-05 08:26:55 +000041#if BUFSIZ < (8*1024)
42#define SMALLCHUNK (8*1024)
43#elif (BUFSIZ >= (2 << 25))
44#error "unreasonable BUFSIZ > 64MB defined"
45#else
46#define SMALLCHUNK BUFSIZ
47#endif
48
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030049/*[clinic input]
50module _io
51class _io.FileIO "fileio *" "&PyFileIO_Type"
52[clinic start generated code]*/
53/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/
54
Guido van Rossuma9e20242007-03-08 00:43:48 +000055typedef struct {
Antoine Pitrouae4b4722010-05-05 16:31:07 +000056 PyObject_HEAD
57 int fd;
Charles-François Natalidc3044c2012-01-09 22:40:02 +010058 unsigned int created : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000059 unsigned int readable : 1;
60 unsigned int writable : 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +020061 unsigned int appending : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000062 signed int seekable : 2; /* -1 means unknown */
63 unsigned int closefd : 1;
Antoine Pitrou796564c2013-07-30 19:59:21 +020064 char finalizing;
Antoine Pitroude687222014-06-29 20:07:28 -040065 unsigned int blksize;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000066 PyObject *weakreflist;
67 PyObject *dict;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000068} fileio;
Guido van Rossuma9e20242007-03-08 00:43:48 +000069
Collin Winteraf334382007-03-08 21:46:15 +000070PyTypeObject PyFileIO_Type;
71
Victor Stinnerd9d04192013-11-06 23:50:10 +010072_Py_IDENTIFIER(name);
73
Guido van Rossuma9e20242007-03-08 00:43:48 +000074#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
75
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000076int
77_PyFileIO_closed(PyObject *self)
78{
Antoine Pitrouae4b4722010-05-05 16:31:07 +000079 return ((fileio *)self)->fd < 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000080}
Antoine Pitrou08838b62009-01-21 00:55:13 +000081
Antoine Pitroue033e062010-10-29 10:38:18 +000082/* Because this can call arbitrary code, it shouldn't be called when
83 the refcount is 0 (that is, not directly from tp_dealloc unless
84 the refcount has been temporarily re-incremented). */
85static PyObject *
86fileio_dealloc_warn(fileio *self, PyObject *source)
87{
88 if (self->fd >= 0 && self->closefd) {
89 PyObject *exc, *val, *tb;
90 PyErr_Fetch(&exc, &val, &tb);
Victor Stinner914cde82016-03-19 01:03:51 +010091 if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) {
Antoine Pitroue033e062010-10-29 10:38:18 +000092 /* Spurious errors can appear at shutdown */
93 if (PyErr_ExceptionMatches(PyExc_Warning))
94 PyErr_WriteUnraisable((PyObject *) self);
95 }
96 PyErr_Restore(exc, val, tb);
97 }
98 Py_RETURN_NONE;
99}
100
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000101static PyObject *
102portable_lseek(int fd, PyObject *posobj, int whence);
103
Antoine Pitroua28fcfd2009-03-13 23:42:55 +0000104static PyObject *portable_lseek(int fd, PyObject *posobj, int whence);
105
Kristján Valur Jónsson19288c22008-12-18 17:15:54 +0000106/* Returns 0 on success, -1 with exception set on failure. */
Neal Norwitz88b44da2007-08-12 17:23:54 +0000107static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000108internal_close(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000109{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000110 int err = 0;
111 int save_errno = 0;
112 if (self->fd >= 0) {
113 int fd = self->fd;
114 self->fd = -1;
115 /* fd is accessible and someone else may have closed it */
Steve Dower940f33a2016-09-08 11:21:54 -0700116 Py_BEGIN_ALLOW_THREADS
117 _Py_BEGIN_SUPPRESS_IPH
118 err = close(fd);
119 if (err < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000120 save_errno = errno;
Steve Dower940f33a2016-09-08 11:21:54 -0700121 _Py_END_SUPPRESS_IPH
122 Py_END_ALLOW_THREADS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000123 }
124 if (err < 0) {
125 errno = save_errno;
126 PyErr_SetFromErrno(PyExc_IOError);
127 return -1;
128 }
129 return 0;
Neal Norwitz88b44da2007-08-12 17:23:54 +0000130}
131
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300132/*[clinic input]
133_io.FileIO.close
134
135Close the file.
136
137A closed file cannot be used for further I/O operations. close() may be
138called more than once without error.
139[clinic start generated code]*/
140
Neal Norwitz88b44da2007-08-12 17:23:54 +0000141static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300142_io_FileIO_close_impl(fileio *self)
143/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/
Neal Norwitz88b44da2007-08-12 17:23:54 +0000144{
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200145 PyObject *res;
146 PyObject *exc, *val, *tb;
147 int rc;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200148 _Py_IDENTIFIER(close);
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100149 res = _PyObject_CallMethodIdObjArgs((PyObject*)&PyRawIOBase_Type,
150 &PyId_close, self, NULL);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000151 if (!self->closefd) {
152 self->fd = -1;
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200153 return res;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000154 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200155 if (res == NULL)
156 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou796564c2013-07-30 19:59:21 +0200157 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000158 PyObject *r = fileio_dealloc_warn(self, (PyObject *) self);
159 if (r)
160 Py_DECREF(r);
161 else
162 PyErr_Clear();
163 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200164 rc = internal_close(self);
165 if (res == NULL)
166 _PyErr_ChainExceptions(exc, val, tb);
167 if (rc < 0)
168 Py_CLEAR(res);
169 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000170}
171
172static PyObject *
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000173fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000174{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000175 fileio *self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000176
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000177 assert(type != NULL && type->tp_alloc != NULL);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000178
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000179 self = (fileio *) type->tp_alloc(type, 0);
180 if (self != NULL) {
181 self->fd = -1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100182 self->created = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000183 self->readable = 0;
184 self->writable = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200185 self->appending = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000186 self->seekable = -1;
Antoine Pitroude687222014-06-29 20:07:28 -0400187 self->blksize = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000188 self->closefd = 1;
189 self->weakreflist = NULL;
190 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000191
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000192 return (PyObject *) self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000193}
194
Victor Stinnerdaf45552013-08-28 00:53:59 +0200195#ifdef O_CLOEXEC
196extern int _Py_open_cloexec_works;
197#endif
Guido van Rossuma9e20242007-03-08 00:43:48 +0000198
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300199/*[clinic input]
200_io.FileIO.__init__
201 file as nameobj: object
202 mode: str = "r"
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200203 closefd: bool(accept={int}) = True
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300204 opener: object = None
205
206Open a file.
207
208The mode can be 'r' (default), 'w', 'x' or 'a' for reading,
209writing, exclusive creation or appending. The file will be created if it
210doesn't exist when opened for writing or appending; it will be truncated
211when opened for writing. A FileExistsError will be raised if it already
212exists when opened for creating. Opening a file for creating implies
213writing so this mode behaves in a similar way to 'w'.Add a '+' to the mode
214to allow simultaneous reading and writing. A custom opener can be used by
215passing a callable as *opener*. The underlying file descriptor for the file
216object is then obtained by calling opener with (*name*, *flags*).
217*opener* must return an open file descriptor (passing os.open as *opener*
218results in functionality similar to passing None).
219[clinic start generated code]*/
220
Guido van Rossuma9e20242007-03-08 00:43:48 +0000221static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300222_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
223 int closefd, PyObject *opener)
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200224/*[clinic end generated code: output=23413f68e6484bbd input=1596c9157a042a39]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000225{
Thomas Helleraf2be262007-07-12 11:03:13 +0000226#ifdef MS_WINDOWS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000227 Py_UNICODE *widename = NULL;
Steve Dowereacee982017-02-04 14:38:11 -0800228#else
229 const char *name = NULL;
Thomas Helleraf2be262007-07-12 11:03:13 +0000230#endif
Steve Dowereacee982017-02-04 14:38:11 -0800231 PyObject *stringobj = NULL;
232 const char *s;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000233 int ret = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200234 int rwa = 0, plus = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000235 int flags = 0;
236 int fd = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200237 int fd_is_own = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200238#ifdef O_CLOEXEC
239 int *atomic_flag_works = &_Py_open_cloexec_works;
240#elif !defined(MS_WINDOWS)
241 int *atomic_flag_works = NULL;
242#endif
Steve Dowerf2f373f2015-02-21 08:44:05 -0800243 struct _Py_stat_struct fdfstat;
Martin Panter0bb62b12015-12-06 03:15:05 +0000244 int fstat_result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000245 int async_err = 0;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000246
Christian Heimes82adeff2015-04-16 17:21:54 +0200247 assert(PyFileIO_Check(self));
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000248 if (self->fd >= 0) {
Hynek Schlawack2cc71562012-05-25 10:05:53 +0200249 if (self->closefd) {
250 /* Have to close the existing file first. */
251 if (internal_close(self) < 0)
252 return -1;
253 }
254 else
255 self->fd = -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000256 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000257
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000258 if (PyFloat_Check(nameobj)) {
259 PyErr_SetString(PyExc_TypeError,
260 "integer argument expected, got float");
261 return -1;
262 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000263
Serhiy Storchaka78980432013-01-15 01:12:17 +0200264 fd = _PyLong_AsInt(nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000265 if (fd < 0) {
266 if (!PyErr_Occurred()) {
267 PyErr_SetString(PyExc_ValueError,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +0300268 "negative file descriptor");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000269 return -1;
270 }
271 PyErr_Clear();
272 }
Guido van Rossumb0428152007-04-08 17:44:42 +0000273
Steve Dowereacee982017-02-04 14:38:11 -0800274 if (fd < 0) {
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000275#ifdef MS_WINDOWS
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300276 Py_ssize_t length;
Steve Dowereacee982017-02-04 14:38:11 -0800277 if (!PyUnicode_FSDecoder(nameobj, &stringobj)) {
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300278 return -1;
279 }
Steve Dowereacee982017-02-04 14:38:11 -0800280 widename = PyUnicode_AsUnicodeAndSize(stringobj, &length);
281 if (widename == NULL)
282 return -1;
283#else
Antoine Pitrou13348842012-01-29 18:36:34 +0100284 if (!PyUnicode_FSConverter(nameobj, &stringobj)) {
285 return -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000286 }
Antoine Pitrou13348842012-01-29 18:36:34 +0100287 name = PyBytes_AS_STRING(stringobj);
Steve Dowereacee982017-02-04 14:38:11 -0800288#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000289 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000290
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000291 s = mode;
292 while (*s) {
293 switch (*s++) {
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100294 case 'x':
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000295 if (rwa) {
296 bad_mode:
297 PyErr_SetString(PyExc_ValueError,
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100298 "Must have exactly one of create/read/write/append "
Georg Brandl28928ae2010-10-21 13:45:52 +0000299 "mode and at most one plus");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000300 goto error;
301 }
302 rwa = 1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100303 self->created = 1;
304 self->writable = 1;
305 flags |= O_EXCL | O_CREAT;
306 break;
307 case 'r':
308 if (rwa)
309 goto bad_mode;
310 rwa = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000311 self->readable = 1;
312 break;
313 case 'w':
314 if (rwa)
315 goto bad_mode;
316 rwa = 1;
317 self->writable = 1;
318 flags |= O_CREAT | O_TRUNC;
319 break;
320 case 'a':
321 if (rwa)
322 goto bad_mode;
323 rwa = 1;
324 self->writable = 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200325 self->appending = 1;
326 flags |= O_APPEND | O_CREAT;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000327 break;
328 case 'b':
329 break;
330 case '+':
331 if (plus)
332 goto bad_mode;
333 self->readable = self->writable = 1;
334 plus = 1;
335 break;
336 default:
337 PyErr_Format(PyExc_ValueError,
338 "invalid mode: %.200s", mode);
339 goto error;
340 }
341 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000342
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000343 if (!rwa)
344 goto bad_mode;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000345
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000346 if (self->readable && self->writable)
347 flags |= O_RDWR;
348 else if (self->readable)
349 flags |= O_RDONLY;
350 else
351 flags |= O_WRONLY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000352
353#ifdef O_BINARY
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000354 flags |= O_BINARY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000355#endif
356
Victor Stinnerdaf45552013-08-28 00:53:59 +0200357#ifdef MS_WINDOWS
358 flags |= O_NOINHERIT;
359#elif defined(O_CLOEXEC)
360 flags |= O_CLOEXEC;
361#endif
Walter Dörwald0e411482007-06-06 16:55:38 +0000362
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000363 if (fd >= 0) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000364 self->fd = fd;
365 self->closefd = closefd;
366 }
367 else {
368 self->closefd = 1;
369 if (!closefd) {
370 PyErr_SetString(PyExc_ValueError,
371 "Cannot use closefd=False with file name");
372 goto error;
373 }
Guido van Rossum2dced8b2007-10-30 17:27:30 +0000374
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000375 errno = 0;
Ross Lagerwall59142db2011-10-31 20:34:46 +0200376 if (opener == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000377 do {
378 Py_BEGIN_ALLOW_THREADS
Thomas Helleraf2be262007-07-12 11:03:13 +0000379#ifdef MS_WINDOWS
Steve Dowereacee982017-02-04 14:38:11 -0800380 self->fd = _wopen(widename, flags, 0666);
381#else
382 self->fd = open(name, flags, 0666);
Thomas Helleraf2be262007-07-12 11:03:13 +0000383#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000384 Py_END_ALLOW_THREADS
385 } while (self->fd < 0 && errno == EINTR &&
386 !(async_err = PyErr_CheckSignals()));
Victor Stinner9672da72015-03-04 18:40:10 +0100387
388 if (async_err)
389 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200390 }
391 else {
392 PyObject *fdobj;
393
394#ifndef MS_WINDOWS
395 /* the opener may clear the atomic flag */
396 atomic_flag_works = NULL;
397#endif
398
399 fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200400 if (fdobj == NULL)
401 goto error;
402 if (!PyLong_Check(fdobj)) {
403 Py_DECREF(fdobj);
404 PyErr_SetString(PyExc_TypeError,
405 "expected integer from opener");
406 goto error;
407 }
408
Serhiy Storchaka78980432013-01-15 01:12:17 +0200409 self->fd = _PyLong_AsInt(fdobj);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200410 Py_DECREF(fdobj);
Barry Warsaw480e2852016-06-08 17:47:26 -0400411 if (self->fd < 0) {
412 if (!PyErr_Occurred()) {
Barry Warsaw118598a2016-06-08 17:54:43 -0400413 /* The opener returned a negative but didn't set an
414 exception. See issue #27066 */
Barry Warsaw480e2852016-06-08 17:47:26 -0400415 PyErr_Format(PyExc_ValueError,
416 "opener returned %d", self->fd);
417 }
Ross Lagerwall59142db2011-10-31 20:34:46 +0200418 goto error;
419 }
420 }
421
Hynek Schlawack7f59fd72012-06-22 09:32:22 +0200422 fd_is_own = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000423 if (self->fd < 0) {
Victor Stinner9672da72015-03-04 18:40:10 +0100424 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000425 goto error;
426 }
Victor Stinnerdaf45552013-08-28 00:53:59 +0200427
428#ifndef MS_WINDOWS
429 if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0)
430 goto error;
431#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000432 }
Antoine Pitroude687222014-06-29 20:07:28 -0400433
434 self->blksize = DEFAULT_BUFFER_SIZE;
Martin Panter0bb62b12015-12-06 03:15:05 +0000435 Py_BEGIN_ALLOW_THREADS
436 fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
437 Py_END_ALLOW_THREADS
438 if (fstat_result < 0) {
Martin Panter49d3db92015-12-06 11:12:15 +0000439 /* Tolerate fstat() errors other than EBADF. See Issue #25717, where
440 an anonymous file on a Virtual Box shared folder filesystem would
441 raise ENOENT. */
Martin Panter0bb62b12015-12-06 03:15:05 +0000442#ifdef MS_WINDOWS
443 if (GetLastError() == ERROR_INVALID_HANDLE) {
444 PyErr_SetFromWindowsErr(0);
445#else
446 if (errno == EBADF) {
447 PyErr_SetFromErrno(PyExc_OSError);
448#endif
449 goto error;
450 }
Antoine Pitroude687222014-06-29 20:07:28 -0400451 }
Martin Panter0bb62b12015-12-06 03:15:05 +0000452 else {
453#if defined(S_ISDIR) && defined(EISDIR)
454 /* On Unix, open will succeed for directories.
455 In Python, there should be no file objects referring to
456 directories, so we need a check. */
457 if (S_ISDIR(fdfstat.st_mode)) {
458 errno = EISDIR;
459 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
460 goto error;
461 }
Antoine Pitroude687222014-06-29 20:07:28 -0400462#endif /* defined(S_ISDIR) */
463#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin Panter0bb62b12015-12-06 03:15:05 +0000464 if (fdfstat.st_blksize > 1)
465 self->blksize = fdfstat.st_blksize;
Antoine Pitroude687222014-06-29 20:07:28 -0400466#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
Martin Panter0bb62b12015-12-06 03:15:05 +0000467 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000468
Victor Stinner89e34362011-01-07 18:47:22 +0000469#if defined(MS_WINDOWS) || defined(__CYGWIN__)
470 /* don't translate newlines (\r\n <=> \n) */
471 _setmode(self->fd, O_BINARY);
472#endif
473
Victor Stinnerd9d04192013-11-06 23:50:10 +0100474 if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000475 goto error;
Antoine Pitrou08838b62009-01-21 00:55:13 +0000476
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200477 if (self->appending) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000478 /* For consistent behaviour, we explicitly seek to the
479 end of file (otherwise, it might be done only on the
480 first write()). */
481 PyObject *pos = portable_lseek(self->fd, NULL, 2);
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200482 if (pos == NULL)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000483 goto error;
484 Py_DECREF(pos);
485 }
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000486
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000487 goto done;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000488
489 error:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000490 ret = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200491 if (!fd_is_own)
492 self->fd = -1;
Benjamin Petersonbbb04122010-10-30 23:16:28 +0000493 if (self->fd >= 0)
494 internal_close(self);
Guido van Rossum53807da2007-04-10 19:01:47 +0000495
Guido van Rossuma9e20242007-03-08 00:43:48 +0000496 done:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000497 Py_CLEAR(stringobj);
498 return ret;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000499}
500
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000501static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000502fileio_traverse(fileio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000503{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000504 Py_VISIT(self->dict);
505 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000506}
507
508static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000509fileio_clear(fileio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000510{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000511 Py_CLEAR(self->dict);
512 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000513}
514
Guido van Rossuma9e20242007-03-08 00:43:48 +0000515static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000516fileio_dealloc(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000517{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200518 self->finalizing = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000519 if (_PyIOBase_finalize((PyObject *) self) < 0)
520 return;
521 _PyObject_GC_UNTRACK(self);
522 if (self->weakreflist != NULL)
523 PyObject_ClearWeakRefs((PyObject *) self);
524 Py_CLEAR(self->dict);
525 Py_TYPE(self)->tp_free((PyObject *)self);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000526}
527
528static PyObject *
529err_closed(void)
530{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000531 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
532 return NULL;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000533}
534
535static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200536err_mode(const char *action)
Guido van Rossum53807da2007-04-10 19:01:47 +0000537{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100538 _PyIO_State *state = IO_STATE();
539 if (state != NULL)
540 PyErr_Format(state->unsupported_operation,
541 "File not open for %s", action);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000542 return NULL;
Guido van Rossum53807da2007-04-10 19:01:47 +0000543}
544
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300545/*[clinic input]
546_io.FileIO.fileno
547
548Return the underlying file descriptor (an integer).
549[clinic start generated code]*/
550
Guido van Rossum53807da2007-04-10 19:01:47 +0000551static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300552_io_FileIO_fileno_impl(fileio *self)
553/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000554{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000555 if (self->fd < 0)
556 return err_closed();
557 return PyLong_FromLong((long) self->fd);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000558}
559
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300560/*[clinic input]
561_io.FileIO.readable
562
563True if file was opened in a read mode.
564[clinic start generated code]*/
565
Guido van Rossuma9e20242007-03-08 00:43:48 +0000566static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300567_io_FileIO_readable_impl(fileio *self)
568/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000569{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000570 if (self->fd < 0)
571 return err_closed();
572 return PyBool_FromLong((long) self->readable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000573}
574
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300575/*[clinic input]
576_io.FileIO.writable
577
578True if file was opened in a write mode.
579[clinic start generated code]*/
580
Guido van Rossuma9e20242007-03-08 00:43:48 +0000581static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300582_io_FileIO_writable_impl(fileio *self)
583/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000584{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000585 if (self->fd < 0)
586 return err_closed();
587 return PyBool_FromLong((long) self->writable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000588}
589
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300590/*[clinic input]
591_io.FileIO.seekable
592
593True if file supports random-access.
594[clinic start generated code]*/
595
Guido van Rossuma9e20242007-03-08 00:43:48 +0000596static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300597_io_FileIO_seekable_impl(fileio *self)
598/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000599{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000600 if (self->fd < 0)
601 return err_closed();
602 if (self->seekable < 0) {
603 PyObject *pos = portable_lseek(self->fd, NULL, SEEK_CUR);
604 if (pos == NULL) {
605 PyErr_Clear();
606 self->seekable = 0;
607 } else {
608 Py_DECREF(pos);
609 self->seekable = 1;
610 }
611 }
612 return PyBool_FromLong((long) self->seekable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000613}
614
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300615/*[clinic input]
616_io.FileIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700617 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300618 /
619
620Same as RawIOBase.readinto().
621[clinic start generated code]*/
622
Guido van Rossuma9e20242007-03-08 00:43:48 +0000623static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300624_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700625/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000626{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100627 Py_ssize_t n;
628 int err;
Guido van Rossum53807da2007-04-10 19:01:47 +0000629
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000630 if (self->fd < 0)
631 return err_closed();
632 if (!self->readable)
633 return err_mode("reading");
Guido van Rossum53807da2007-04-10 19:01:47 +0000634
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300635 n = _Py_read(self->fd, buffer->buf, buffer->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100636 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100637 err = errno;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100638
639 if (n == -1) {
640 if (err == EAGAIN) {
641 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000642 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100643 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000644 return NULL;
645 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000646
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000647 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000648}
649
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000650static size_t
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100651new_buffersize(fileio *self, size_t currentsize)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000652{
Antoine Pitroua3f44572012-04-17 13:50:58 +0200653 size_t addend;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100654
Nadeem Vawdad41a98b2011-10-13 13:34:16 +0200655 /* Expand the buffer by an amount proportional to the current size,
Antoine Pitroua3f44572012-04-17 13:50:58 +0200656 giving us amortized linear-time behavior. For bigger sizes, use a
657 less-than-double growth factor to avoid excessive allocation. */
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100658 assert(currentsize <= PY_SSIZE_T_MAX);
Antoine Pitroua3f44572012-04-17 13:50:58 +0200659 if (currentsize > 65536)
660 addend = currentsize >> 3;
661 else
662 addend = 256 + currentsize;
663 if (addend < SMALLCHUNK)
664 /* Avoid tiny read() calls. */
665 addend = SMALLCHUNK;
666 return addend + currentsize;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000667}
668
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300669/*[clinic input]
670_io.FileIO.readall
671
672Read all data from the file, returned as bytes.
673
674In non-blocking mode, returns as much as is immediately available,
675or None if no data is available. Return an empty bytes object at EOF.
676[clinic start generated code]*/
677
Guido van Rossum7165cb12007-07-10 06:54:34 +0000678static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300679_io_FileIO_readall_impl(fileio *self)
680/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/
Guido van Rossum7165cb12007-07-10 06:54:34 +0000681{
Victor Stinnere134a7f2015-03-30 10:09:31 +0200682 struct _Py_stat_struct status;
Victor Stinnera2a64772011-10-11 22:45:02 +0200683 Py_off_t pos, end;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000684 PyObject *result;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100685 Py_ssize_t bytes_read = 0;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100686 Py_ssize_t n;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100687 size_t bufsize;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000688
Victor Stinnerb79f28c2011-05-25 22:09:03 +0200689 if (self->fd < 0)
690 return err_closed();
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000691
Steve Dower8fc89802015-04-12 00:26:27 -0400692 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200693#ifdef MS_WINDOWS
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200694 pos = _lseeki64(self->fd, 0L, SEEK_CUR);
695#else
696 pos = lseek(self->fd, 0L, SEEK_CUR);
697#endif
Steve Dower8fc89802015-04-12 00:26:27 -0400698 _Py_END_SUPPRESS_IPH
699
Victor Stinnere134a7f2015-03-30 10:09:31 +0200700 if (_Py_fstat_noraise(self->fd, &status) == 0)
701 end = status.st_size;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200702 else
Victor Stinnera2a64772011-10-11 22:45:02 +0200703 end = (Py_off_t)-1;
Christian Heimesa872de52008-12-05 08:26:55 +0000704
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100705 if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) {
706 /* This is probably a real file, so we try to allocate a
707 buffer one byte larger than the rest of the file. If the
708 calculation is right then we should get EOF without having
709 to enlarge the buffer. */
710 bufsize = (size_t)(end - pos + 1);
711 } else {
712 bufsize = SMALLCHUNK;
713 }
714
715 result = PyBytes_FromStringAndSize(NULL, bufsize);
716 if (result == NULL)
717 return NULL;
718
719 while (1) {
720 if (bytes_read >= (Py_ssize_t)bufsize) {
721 bufsize = new_buffersize(self, bytes_read);
722 if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) {
723 PyErr_SetString(PyExc_OverflowError,
724 "unbounded read returned more bytes "
Serhiy Storchakab817b772015-04-10 02:18:44 +0300725 "than a Python bytes object can hold");
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100726 Py_DECREF(result);
727 return NULL;
728 }
729
730 if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) {
731 if (_PyBytes_Resize(&result, bufsize) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000732 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000733 }
734 }
Victor Stinner9672da72015-03-04 18:40:10 +0100735
Victor Stinner66aab0c2015-03-19 22:53:20 +0100736 n = _Py_read(self->fd,
737 PyBytes_AS_STRING(result) + bytes_read,
738 bufsize - bytes_read);
Victor Stinner9672da72015-03-04 18:40:10 +0100739
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000740 if (n == 0)
741 break;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100742 if (n == -1) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000743 if (errno == EAGAIN) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100744 PyErr_Clear();
Victor Stinnere10920f2014-07-02 22:59:31 +0200745 if (bytes_read > 0)
746 break;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000747 Py_DECREF(result);
748 Py_RETURN_NONE;
749 }
750 Py_DECREF(result);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000751 return NULL;
752 }
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100753 bytes_read += n;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200754 pos += n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000755 }
Guido van Rossum7165cb12007-07-10 06:54:34 +0000756
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100757 if (PyBytes_GET_SIZE(result) > bytes_read) {
758 if (_PyBytes_Resize(&result, bytes_read) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000759 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000760 }
761 return result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000762}
763
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300764/*[clinic input]
765_io.FileIO.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300766 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300767 /
768
769Read at most size bytes, returned as bytes.
770
771Only makes one system call, so less data may be returned than requested.
772In non-blocking mode, returns None if no data is available.
773Return an empty bytes object at EOF.
774[clinic start generated code]*/
775
Guido van Rossuma9e20242007-03-08 00:43:48 +0000776static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300777_io_FileIO_read_impl(fileio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300778/*[clinic end generated code: output=42528d39dd0ca641 input=bec9a2c704ddcbc9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000779{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000780 char *ptr;
781 Py_ssize_t n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000782 PyObject *bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000783
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000784 if (self->fd < 0)
785 return err_closed();
786 if (!self->readable)
787 return err_mode("reading");
Guido van Rossuma9e20242007-03-08 00:43:48 +0000788
Victor Stinner66aab0c2015-03-19 22:53:20 +0100789 if (size < 0)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300790 return _io_FileIO_readall_impl(self);
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000791
Victor Stinner14b9b112013-06-25 00:37:25 +0200792#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +0100793 /* On Windows, the count parameter of read() is an int */
Victor Stinnerc655a722011-07-05 11:31:49 +0200794 if (size > INT_MAX)
795 size = INT_MAX;
796#endif
Victor Stinner66aab0c2015-03-19 22:53:20 +0100797
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000798 bytes = PyBytes_FromStringAndSize(NULL, size);
799 if (bytes == NULL)
800 return NULL;
801 ptr = PyBytes_AS_STRING(bytes);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000802
Victor Stinner66aab0c2015-03-19 22:53:20 +0100803 n = _Py_read(self->fd, ptr, size);
804 if (n == -1) {
805 /* copy errno because Py_DECREF() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100806 int err = errno;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000807 Py_DECREF(bytes);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100808 if (err == EAGAIN) {
809 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000810 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100811 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000812 return NULL;
813 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000814
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000815 if (n != size) {
816 if (_PyBytes_Resize(&bytes, n) < 0) {
Victor Stinner85c761d2013-07-16 21:36:02 +0200817 Py_CLEAR(bytes);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000818 return NULL;
819 }
820 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000821
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000822 return (PyObject *) bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000823}
824
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300825/*[clinic input]
826_io.FileIO.write
827 b: Py_buffer
828 /
829
Martin Panter6bb91f32016-05-28 00:41:57 +0000830Write buffer b to file, return number of bytes written.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300831
832Only makes one system call, so not all of the data may be written.
833The number of bytes actually written is returned. In non-blocking mode,
834returns None if the write would block.
835[clinic start generated code]*/
836
Guido van Rossuma9e20242007-03-08 00:43:48 +0000837static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300838_io_FileIO_write_impl(fileio *self, Py_buffer *b)
Martin Panter6bb91f32016-05-28 00:41:57 +0000839/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000840{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100841 Py_ssize_t n;
842 int err;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000843
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000844 if (self->fd < 0)
845 return err_closed();
846 if (!self->writable)
847 return err_mode("writing");
Guido van Rossum53807da2007-04-10 19:01:47 +0000848
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300849 n = _Py_write(self->fd, b->buf, b->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100850 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100851 err = errno;
Martin v. Löwis423be952008-08-13 15:53:07 +0000852
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000853 if (n < 0) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100854 if (err == EAGAIN) {
855 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000856 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100857 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000858 return NULL;
859 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000860
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000861 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000862}
863
Guido van Rossum53807da2007-04-10 19:01:47 +0000864/* XXX Windows support below is likely incomplete */
865
Guido van Rossum53807da2007-04-10 19:01:47 +0000866/* Cribbed from posix_lseek() */
867static PyObject *
868portable_lseek(int fd, PyObject *posobj, int whence)
869{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000870 Py_off_t pos, res;
Guido van Rossum53807da2007-04-10 19:01:47 +0000871
872#ifdef SEEK_SET
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000873 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
874 switch (whence) {
Guido van Rossum53807da2007-04-10 19:01:47 +0000875#if SEEK_SET != 0
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000876 case 0: whence = SEEK_SET; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000877#endif
878#if SEEK_CUR != 1
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000879 case 1: whence = SEEK_CUR; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000880#endif
Antoine Pitrou4f7945f2009-01-20 11:42:11 +0000881#if SEEK_END != 2
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000882 case 2: whence = SEEK_END; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000883#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000884 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000885#endif /* SEEK_SET */
886
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000887 if (posobj == NULL)
888 pos = 0;
889 else {
890 if(PyFloat_Check(posobj)) {
891 PyErr_SetString(PyExc_TypeError, "an integer is required");
892 return NULL;
893 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000894#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000895 pos = PyLong_AsLongLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000896#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000897 pos = PyLong_AsLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000898#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000899 if (PyErr_Occurred())
900 return NULL;
901 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000902
Steve Dower940f33a2016-09-08 11:21:54 -0700903 Py_BEGIN_ALLOW_THREADS
904 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200905#ifdef MS_WINDOWS
Steve Dower940f33a2016-09-08 11:21:54 -0700906 res = _lseeki64(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000907#else
Steve Dower940f33a2016-09-08 11:21:54 -0700908 res = lseek(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000909#endif
Steve Dower940f33a2016-09-08 11:21:54 -0700910 _Py_END_SUPPRESS_IPH
911 Py_END_ALLOW_THREADS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000912 if (res < 0)
913 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum53807da2007-04-10 19:01:47 +0000914
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000915#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000916 return PyLong_FromLongLong(res);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000917#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000918 return PyLong_FromLong(res);
Guido van Rossum53807da2007-04-10 19:01:47 +0000919#endif
920}
921
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300922/*[clinic input]
923_io.FileIO.seek
924 pos: object
925 whence: int = 0
926 /
Guido van Rossuma9e20242007-03-08 00:43:48 +0000927
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300928Move to new file position and return the file position.
929
930Argument offset is a byte count. Optional argument whence defaults to
931SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
932are SEEK_CUR or 1 (move relative to current position, positive or negative),
933and SEEK_END or 2 (move relative to end of file, usually negative, although
934many platforms allow seeking beyond the end of a file).
935
936Note that not all file objects are seekable.
937[clinic start generated code]*/
938
939static PyObject *
940_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
941/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/
942{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000943 if (self->fd < 0)
944 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000945
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300946 return portable_lseek(self->fd, pos, whence);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000947}
948
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300949/*[clinic input]
950_io.FileIO.tell
951
952Current file position.
953
954Can raise OSError for non seekable files.
955[clinic start generated code]*/
956
Guido van Rossuma9e20242007-03-08 00:43:48 +0000957static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300958_io_FileIO_tell_impl(fileio *self)
959/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000960{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000961 if (self->fd < 0)
962 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000963
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000964 return portable_lseek(self->fd, NULL, 1);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000965}
966
Thomas Hellerc6a55ee2007-07-11 12:45:46 +0000967#ifdef HAVE_FTRUNCATE
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300968/*[clinic input]
969_io.FileIO.truncate
970 size as posobj: object = NULL
971 /
972
973Truncate the file to at most size bytes and return the truncated size.
974
975Size defaults to the current file position, as returned by tell().
976The current file position is changed to the value of size.
977[clinic start generated code]*/
978
Guido van Rossuma9e20242007-03-08 00:43:48 +0000979static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300980_io_FileIO_truncate_impl(fileio *self, PyObject *posobj)
981/*[clinic end generated code: output=e49ca7a916c176fa input=9026af44686b7318]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000982{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000983 Py_off_t pos;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000984 int ret;
985 int fd;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000986
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000987 fd = self->fd;
988 if (fd < 0)
989 return err_closed();
990 if (!self->writable)
991 return err_mode("writing");
Guido van Rossuma9e20242007-03-08 00:43:48 +0000992
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000993 if (posobj == Py_None || posobj == NULL) {
994 /* Get the current position. */
995 posobj = portable_lseek(fd, NULL, 1);
996 if (posobj == NULL)
997 return NULL;
998 }
999 else {
1000 Py_INCREF(posobj);
1001 }
Guido van Rossum53807da2007-04-10 19:01:47 +00001002
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001003#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001004 pos = PyLong_AsLongLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001005#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001006 pos = PyLong_AsLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001007#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001008 if (PyErr_Occurred()){
1009 Py_DECREF(posobj);
1010 return NULL;
1011 }
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001012
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001013 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04001014 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001015 errno = 0;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001016#ifdef MS_WINDOWS
1017 ret = _chsize_s(fd, pos);
1018#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001019 ret = ftruncate(fd, pos);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001020#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04001021 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001022 Py_END_ALLOW_THREADS
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001023
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001024 if (ret != 0) {
1025 Py_DECREF(posobj);
1026 PyErr_SetFromErrno(PyExc_IOError);
1027 return NULL;
1028 }
Guido van Rossuma9e20242007-03-08 00:43:48 +00001029
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001030 return posobj;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001031}
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001032#endif /* HAVE_FTRUNCATE */
Guido van Rossum53807da2007-04-10 19:01:47 +00001033
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001034static const char *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001035mode_string(fileio *self)
Guido van Rossum53807da2007-04-10 19:01:47 +00001036{
Charles-François Natalidc3044c2012-01-09 22:40:02 +01001037 if (self->created) {
1038 if (self->readable)
1039 return "xb+";
1040 else
1041 return "xb";
1042 }
Antoine Pitroue93b63b2013-09-04 20:46:33 +02001043 if (self->appending) {
1044 if (self->readable)
1045 return "ab+";
1046 else
1047 return "ab";
1048 }
1049 else if (self->readable) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001050 if (self->writable)
1051 return "rb+";
1052 else
1053 return "rb";
1054 }
1055 else
1056 return "wb";
Guido van Rossum53807da2007-04-10 19:01:47 +00001057}
Guido van Rossuma9e20242007-03-08 00:43:48 +00001058
1059static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001060fileio_repr(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +00001061{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001062 PyObject *nameobj, *res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001063
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001064 if (self->fd < 0)
1065 return PyUnicode_FromFormat("<_io.FileIO [closed]>");
Antoine Pitrou716c4442009-05-23 19:04:03 +00001066
Martin v. Löwis767046a2011-10-14 15:35:36 +02001067 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001068 if (nameobj == NULL) {
1069 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1070 PyErr_Clear();
1071 else
1072 return NULL;
Robert Collins933430a2014-10-18 13:32:43 +13001073 res = PyUnicode_FromFormat(
Serhiy Storchaka4954f9f2014-12-02 23:39:56 +02001074 "<_io.FileIO fd=%d mode='%s' closefd=%s>",
1075 self->fd, mode_string(self), self->closefd ? "True" : "False");
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001076 }
1077 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001078 int status = Py_ReprEnter((PyObject *)self);
1079 res = NULL;
1080 if (status == 0) {
1081 res = PyUnicode_FromFormat(
1082 "<_io.FileIO name=%R mode='%s' closefd=%s>",
1083 nameobj, mode_string(self), self->closefd ? "True" : "False");
1084 Py_ReprLeave((PyObject *)self);
1085 }
1086 else if (status > 0) {
1087 PyErr_Format(PyExc_RuntimeError,
1088 "reentrant call inside %s.__repr__",
1089 Py_TYPE(self)->tp_name);
1090 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001091 Py_DECREF(nameobj);
1092 }
1093 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001094}
1095
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001096/*[clinic input]
1097_io.FileIO.isatty
1098
1099True if the file is connected to a TTY device.
1100[clinic start generated code]*/
1101
Guido van Rossuma9e20242007-03-08 00:43:48 +00001102static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001103_io_FileIO_isatty_impl(fileio *self)
1104/*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +00001105{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001106 long res;
Guido van Rossum53807da2007-04-10 19:01:47 +00001107
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001108 if (self->fd < 0)
1109 return err_closed();
1110 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001111 _Py_BEGIN_SUPPRESS_IPH
Steve Dower940f33a2016-09-08 11:21:54 -07001112 res = isatty(self->fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001113 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001114 Py_END_ALLOW_THREADS
1115 return PyBool_FromLong(res);
Guido van Rossuma9e20242007-03-08 00:43:48 +00001116}
1117
Antoine Pitrou243757e2010-11-05 21:15:39 +00001118static PyObject *
1119fileio_getstate(fileio *self)
1120{
1121 PyErr_Format(PyExc_TypeError,
1122 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
1123 return NULL;
1124}
1125
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001126#include "clinic/fileio.c.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +00001127
1128static PyMethodDef fileio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001129 _IO_FILEIO_READ_METHODDEF
1130 _IO_FILEIO_READALL_METHODDEF
1131 _IO_FILEIO_READINTO_METHODDEF
1132 _IO_FILEIO_WRITE_METHODDEF
1133 _IO_FILEIO_SEEK_METHODDEF
1134 _IO_FILEIO_TELL_METHODDEF
1135 _IO_FILEIO_TRUNCATE_METHODDEF
1136 _IO_FILEIO_CLOSE_METHODDEF
1137 _IO_FILEIO_SEEKABLE_METHODDEF
1138 _IO_FILEIO_READABLE_METHODDEF
1139 _IO_FILEIO_WRITABLE_METHODDEF
1140 _IO_FILEIO_FILENO_METHODDEF
1141 _IO_FILEIO_ISATTY_METHODDEF
Antoine Pitroue033e062010-10-29 10:38:18 +00001142 {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001143 {"__getstate__", (PyCFunction)fileio_getstate, METH_NOARGS, NULL},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001144 {NULL, NULL} /* sentinel */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001145};
1146
Guido van Rossum53807da2007-04-10 19:01:47 +00001147/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */
1148
Guido van Rossumb0428152007-04-08 17:44:42 +00001149static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001150get_closed(fileio *self, void *closure)
Guido van Rossumb0428152007-04-08 17:44:42 +00001151{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001152 return PyBool_FromLong((long)(self->fd < 0));
Guido van Rossum53807da2007-04-10 19:01:47 +00001153}
1154
1155static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001156get_closefd(fileio *self, void *closure)
Christian Heimesecc42a22008-11-05 19:30:32 +00001157{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001158 return PyBool_FromLong((long)(self->closefd));
Christian Heimesecc42a22008-11-05 19:30:32 +00001159}
1160
1161static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001162get_mode(fileio *self, void *closure)
Guido van Rossum53807da2007-04-10 19:01:47 +00001163{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001164 return PyUnicode_FromString(mode_string(self));
Guido van Rossumb0428152007-04-08 17:44:42 +00001165}
1166
1167static PyGetSetDef fileio_getsetlist[] = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001168 {"closed", (getter)get_closed, NULL, "True if the file is closed"},
1169 {"closefd", (getter)get_closefd, NULL,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +03001170 "True if the file descriptor will be closed by close()."},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001171 {"mode", (getter)get_mode, NULL, "String giving the file mode"},
1172 {NULL},
Guido van Rossumb0428152007-04-08 17:44:42 +00001173};
1174
Antoine Pitrou796564c2013-07-30 19:59:21 +02001175static PyMemberDef fileio_members[] = {
Antoine Pitroude687222014-06-29 20:07:28 -04001176 {"_blksize", T_UINT, offsetof(fileio, blksize), 0},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001177 {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
1178 {NULL}
1179};
1180
Guido van Rossuma9e20242007-03-08 00:43:48 +00001181PyTypeObject PyFileIO_Type = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001182 PyVarObject_HEAD_INIT(NULL, 0)
1183 "_io.FileIO",
1184 sizeof(fileio),
1185 0,
1186 (destructor)fileio_dealloc, /* tp_dealloc */
1187 0, /* tp_print */
1188 0, /* tp_getattr */
1189 0, /* tp_setattr */
1190 0, /* tp_reserved */
1191 (reprfunc)fileio_repr, /* tp_repr */
1192 0, /* tp_as_number */
1193 0, /* tp_as_sequence */
1194 0, /* tp_as_mapping */
1195 0, /* tp_hash */
1196 0, /* tp_call */
1197 0, /* tp_str */
1198 PyObject_GenericGetAttr, /* tp_getattro */
1199 0, /* tp_setattro */
1200 0, /* tp_as_buffer */
1201 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001202 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001203 _io_FileIO___init____doc__, /* tp_doc */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001204 (traverseproc)fileio_traverse, /* tp_traverse */
1205 (inquiry)fileio_clear, /* tp_clear */
1206 0, /* tp_richcompare */
1207 offsetof(fileio, weakreflist), /* tp_weaklistoffset */
1208 0, /* tp_iter */
1209 0, /* tp_iternext */
1210 fileio_methods, /* tp_methods */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001211 fileio_members, /* tp_members */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001212 fileio_getsetlist, /* tp_getset */
1213 0, /* tp_base */
1214 0, /* tp_dict */
1215 0, /* tp_descr_get */
1216 0, /* tp_descr_set */
1217 offsetof(fileio, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001218 _io_FileIO___init__, /* tp_init */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001219 PyType_GenericAlloc, /* tp_alloc */
1220 fileio_new, /* tp_new */
1221 PyObject_GC_Del, /* tp_free */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001222 0, /* tp_is_gc */
1223 0, /* tp_bases */
1224 0, /* tp_mro */
1225 0, /* tp_cache */
1226 0, /* tp_subclasses */
1227 0, /* tp_weaklist */
1228 0, /* tp_del */
1229 0, /* tp_version_tag */
1230 0, /* tp_finalize */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001231};