blob: a02a9c1be33351512d7626130a8d196898619f17 [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
12#ifdef HAVE_FCNTL_H
Guido van Rossuma9e20242007-03-08 00:43:48 +000013#include <fcntl.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +000014#endif
Guido van Rossuma9e20242007-03-08 00:43:48 +000015#include <stddef.h> /* For offsetof */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000016#include "_iomodule.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +000017
18/*
19 * Known likely problems:
20 *
21 * - Files larger then 2**32-1
22 * - Files with unicode filenames
23 * - Passing numbers greater than 2**32-1 when an integer is expected
24 * - Making it work on Windows and other oddball platforms
25 *
26 * To Do:
27 *
28 * - autoconfify header file inclusion
Guido van Rossuma9e20242007-03-08 00:43:48 +000029 */
30
31#ifdef MS_WINDOWS
32/* can simulate truncate with Win32 API functions; see file_truncate */
Thomas Hellerfdeee3a2007-07-12 11:21:36 +000033#define HAVE_FTRUNCATE
Guido van Rossuma9e20242007-03-08 00:43:48 +000034#define WIN32_LEAN_AND_MEAN
35#include <windows.h>
36#endif
37
Christian Heimesa872de52008-12-05 08:26:55 +000038#if BUFSIZ < (8*1024)
39#define SMALLCHUNK (8*1024)
40#elif (BUFSIZ >= (2 << 25))
41#error "unreasonable BUFSIZ > 64MB defined"
42#else
43#define SMALLCHUNK BUFSIZ
44#endif
45
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030046/*[clinic input]
47module _io
48class _io.FileIO "fileio *" "&PyFileIO_Type"
49[clinic start generated code]*/
50/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/
51
52/*[python input]
53class io_ssize_t_converter(CConverter):
54 type = 'Py_ssize_t'
55 converter = '_PyIO_ConvertSsize_t'
56[python start generated code]*/
57/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/
58
Guido van Rossuma9e20242007-03-08 00:43:48 +000059typedef struct {
Antoine Pitrouae4b4722010-05-05 16:31:07 +000060 PyObject_HEAD
61 int fd;
Charles-François Natalidc3044c2012-01-09 22:40:02 +010062 unsigned int created : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000063 unsigned int readable : 1;
64 unsigned int writable : 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +020065 unsigned int appending : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000066 signed int seekable : 2; /* -1 means unknown */
67 unsigned int closefd : 1;
Antoine Pitrou796564c2013-07-30 19:59:21 +020068 char finalizing;
Antoine Pitroude687222014-06-29 20:07:28 -040069 unsigned int blksize;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000070 PyObject *weakreflist;
71 PyObject *dict;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000072} fileio;
Guido van Rossuma9e20242007-03-08 00:43:48 +000073
Collin Winteraf334382007-03-08 21:46:15 +000074PyTypeObject PyFileIO_Type;
75
Victor Stinnerd9d04192013-11-06 23:50:10 +010076_Py_IDENTIFIER(name);
77
Guido van Rossuma9e20242007-03-08 00:43:48 +000078#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
79
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000080int
81_PyFileIO_closed(PyObject *self)
82{
Antoine Pitrouae4b4722010-05-05 16:31:07 +000083 return ((fileio *)self)->fd < 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000084}
Antoine Pitrou08838b62009-01-21 00:55:13 +000085
Antoine Pitroue033e062010-10-29 10:38:18 +000086/* Because this can call arbitrary code, it shouldn't be called when
87 the refcount is 0 (that is, not directly from tp_dealloc unless
88 the refcount has been temporarily re-incremented). */
89static PyObject *
90fileio_dealloc_warn(fileio *self, PyObject *source)
91{
92 if (self->fd >= 0 && self->closefd) {
93 PyObject *exc, *val, *tb;
94 PyErr_Fetch(&exc, &val, &tb);
Victor Stinner914cde82016-03-19 01:03:51 +010095 if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) {
Antoine Pitroue033e062010-10-29 10:38:18 +000096 /* Spurious errors can appear at shutdown */
97 if (PyErr_ExceptionMatches(PyExc_Warning))
98 PyErr_WriteUnraisable((PyObject *) self);
99 }
100 PyErr_Restore(exc, val, tb);
101 }
102 Py_RETURN_NONE;
103}
104
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000105static PyObject *
106portable_lseek(int fd, PyObject *posobj, int whence);
107
Antoine Pitroua28fcfd2009-03-13 23:42:55 +0000108static PyObject *portable_lseek(int fd, PyObject *posobj, int whence);
109
Kristján Valur Jónsson19288c22008-12-18 17:15:54 +0000110/* Returns 0 on success, -1 with exception set on failure. */
Neal Norwitz88b44da2007-08-12 17:23:54 +0000111static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000112internal_close(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000113{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000114 int err = 0;
115 int save_errno = 0;
116 if (self->fd >= 0) {
117 int fd = self->fd;
118 self->fd = -1;
119 /* fd is accessible and someone else may have closed it */
120 if (_PyVerify_fd(fd)) {
121 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400122 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000123 err = close(fd);
124 if (err < 0)
125 save_errno = errno;
Steve Dower8fc89802015-04-12 00:26:27 -0400126 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000127 Py_END_ALLOW_THREADS
128 } else {
129 save_errno = errno;
130 err = -1;
131 }
132 }
133 if (err < 0) {
134 errno = save_errno;
135 PyErr_SetFromErrno(PyExc_IOError);
136 return -1;
137 }
138 return 0;
Neal Norwitz88b44da2007-08-12 17:23:54 +0000139}
140
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300141/*[clinic input]
142_io.FileIO.close
143
144Close the file.
145
146A closed file cannot be used for further I/O operations. close() may be
147called more than once without error.
148[clinic start generated code]*/
149
Neal Norwitz88b44da2007-08-12 17:23:54 +0000150static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300151_io_FileIO_close_impl(fileio *self)
152/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/
Neal Norwitz88b44da2007-08-12 17:23:54 +0000153{
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200154 PyObject *res;
155 PyObject *exc, *val, *tb;
156 int rc;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200157 _Py_IDENTIFIER(close);
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200158 res = _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type,
159 &PyId_close, "O", self);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000160 if (!self->closefd) {
161 self->fd = -1;
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200162 return res;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000163 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200164 if (res == NULL)
165 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou796564c2013-07-30 19:59:21 +0200166 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000167 PyObject *r = fileio_dealloc_warn(self, (PyObject *) self);
168 if (r)
169 Py_DECREF(r);
170 else
171 PyErr_Clear();
172 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200173 rc = internal_close(self);
174 if (res == NULL)
175 _PyErr_ChainExceptions(exc, val, tb);
176 if (rc < 0)
177 Py_CLEAR(res);
178 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000179}
180
181static PyObject *
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000182fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000183{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000184 fileio *self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000185
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000186 assert(type != NULL && type->tp_alloc != NULL);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000187
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000188 self = (fileio *) type->tp_alloc(type, 0);
189 if (self != NULL) {
190 self->fd = -1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100191 self->created = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000192 self->readable = 0;
193 self->writable = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200194 self->appending = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000195 self->seekable = -1;
Antoine Pitroude687222014-06-29 20:07:28 -0400196 self->blksize = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000197 self->closefd = 1;
198 self->weakreflist = NULL;
199 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000200
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000201 return (PyObject *) self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000202}
203
Victor Stinnerdaf45552013-08-28 00:53:59 +0200204#ifdef O_CLOEXEC
205extern int _Py_open_cloexec_works;
206#endif
Guido van Rossuma9e20242007-03-08 00:43:48 +0000207
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300208/*[clinic input]
209_io.FileIO.__init__
210 file as nameobj: object
211 mode: str = "r"
212 closefd: int(c_default="1") = True
213 opener: object = None
214
215Open a file.
216
217The mode can be 'r' (default), 'w', 'x' or 'a' for reading,
218writing, exclusive creation or appending. The file will be created if it
219doesn't exist when opened for writing or appending; it will be truncated
220when opened for writing. A FileExistsError will be raised if it already
221exists when opened for creating. Opening a file for creating implies
222writing so this mode behaves in a similar way to 'w'.Add a '+' to the mode
223to allow simultaneous reading and writing. A custom opener can be used by
224passing a callable as *opener*. The underlying file descriptor for the file
225object is then obtained by calling opener with (*name*, *flags*).
226*opener* must return an open file descriptor (passing os.open as *opener*
227results in functionality similar to passing None).
228[clinic start generated code]*/
229
Guido van Rossuma9e20242007-03-08 00:43:48 +0000230static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300231_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
232 int closefd, PyObject *opener)
233/*[clinic end generated code: output=23413f68e6484bbd input=193164e293d6c097]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000234{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000235 const char *name = NULL;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300236 PyObject *stringobj = NULL;
237 const char *s;
Thomas Helleraf2be262007-07-12 11:03:13 +0000238#ifdef MS_WINDOWS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000239 Py_UNICODE *widename = NULL;
Thomas Helleraf2be262007-07-12 11:03:13 +0000240#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000241 int ret = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200242 int rwa = 0, plus = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000243 int flags = 0;
244 int fd = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200245 int fd_is_own = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200246#ifdef O_CLOEXEC
247 int *atomic_flag_works = &_Py_open_cloexec_works;
248#elif !defined(MS_WINDOWS)
249 int *atomic_flag_works = NULL;
250#endif
Steve Dowerf2f373f2015-02-21 08:44:05 -0800251 struct _Py_stat_struct fdfstat;
Martin Panter0bb62b12015-12-06 03:15:05 +0000252 int fstat_result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000253 int async_err = 0;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000254
Christian Heimes82adeff2015-04-16 17:21:54 +0200255 assert(PyFileIO_Check(self));
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000256 if (self->fd >= 0) {
Hynek Schlawack2cc71562012-05-25 10:05:53 +0200257 if (self->closefd) {
258 /* Have to close the existing file first. */
259 if (internal_close(self) < 0)
260 return -1;
261 }
262 else
263 self->fd = -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000264 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000265
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000266 if (PyFloat_Check(nameobj)) {
267 PyErr_SetString(PyExc_TypeError,
268 "integer argument expected, got float");
269 return -1;
270 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000271
Serhiy Storchaka78980432013-01-15 01:12:17 +0200272 fd = _PyLong_AsInt(nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000273 if (fd < 0) {
274 if (!PyErr_Occurred()) {
275 PyErr_SetString(PyExc_ValueError,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +0300276 "negative file descriptor");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000277 return -1;
278 }
279 PyErr_Clear();
280 }
Guido van Rossumb0428152007-04-08 17:44:42 +0000281
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000282#ifdef MS_WINDOWS
Victor Stinnerfe9a8612011-09-29 23:19:04 +0200283 if (PyUnicode_Check(nameobj)) {
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300284 Py_ssize_t length;
285 widename = PyUnicode_AsUnicodeAndSize(nameobj, &length);
Victor Stinnerfe9a8612011-09-29 23:19:04 +0200286 if (widename == NULL)
287 return -1;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300288 if (wcslen(widename) != length) {
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +0300289 PyErr_SetString(PyExc_ValueError, "embedded null character");
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300290 return -1;
291 }
Victor Stinnerfe9a8612011-09-29 23:19:04 +0200292 } else
Guido van Rossuma9e20242007-03-08 00:43:48 +0000293#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000294 if (fd < 0)
295 {
Antoine Pitrou13348842012-01-29 18:36:34 +0100296 if (!PyUnicode_FSConverter(nameobj, &stringobj)) {
297 return -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000298 }
Antoine Pitrou13348842012-01-29 18:36:34 +0100299 name = PyBytes_AS_STRING(stringobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000300 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000301
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000302 s = mode;
303 while (*s) {
304 switch (*s++) {
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100305 case 'x':
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000306 if (rwa) {
307 bad_mode:
308 PyErr_SetString(PyExc_ValueError,
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100309 "Must have exactly one of create/read/write/append "
Georg Brandl28928ae2010-10-21 13:45:52 +0000310 "mode and at most one plus");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000311 goto error;
312 }
313 rwa = 1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100314 self->created = 1;
315 self->writable = 1;
316 flags |= O_EXCL | O_CREAT;
317 break;
318 case 'r':
319 if (rwa)
320 goto bad_mode;
321 rwa = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000322 self->readable = 1;
323 break;
324 case 'w':
325 if (rwa)
326 goto bad_mode;
327 rwa = 1;
328 self->writable = 1;
329 flags |= O_CREAT | O_TRUNC;
330 break;
331 case 'a':
332 if (rwa)
333 goto bad_mode;
334 rwa = 1;
335 self->writable = 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200336 self->appending = 1;
337 flags |= O_APPEND | O_CREAT;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000338 break;
339 case 'b':
340 break;
341 case '+':
342 if (plus)
343 goto bad_mode;
344 self->readable = self->writable = 1;
345 plus = 1;
346 break;
347 default:
348 PyErr_Format(PyExc_ValueError,
349 "invalid mode: %.200s", mode);
350 goto error;
351 }
352 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000353
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000354 if (!rwa)
355 goto bad_mode;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000356
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000357 if (self->readable && self->writable)
358 flags |= O_RDWR;
359 else if (self->readable)
360 flags |= O_RDONLY;
361 else
362 flags |= O_WRONLY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000363
364#ifdef O_BINARY
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000365 flags |= O_BINARY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000366#endif
367
Victor Stinnerdaf45552013-08-28 00:53:59 +0200368#ifdef MS_WINDOWS
369 flags |= O_NOINHERIT;
370#elif defined(O_CLOEXEC)
371 flags |= O_CLOEXEC;
372#endif
Walter Dörwald0e411482007-06-06 16:55:38 +0000373
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000374 if (fd >= 0) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000375 self->fd = fd;
376 self->closefd = closefd;
377 }
378 else {
379 self->closefd = 1;
380 if (!closefd) {
381 PyErr_SetString(PyExc_ValueError,
382 "Cannot use closefd=False with file name");
383 goto error;
384 }
Guido van Rossum2dced8b2007-10-30 17:27:30 +0000385
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000386 errno = 0;
Ross Lagerwall59142db2011-10-31 20:34:46 +0200387 if (opener == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000388 do {
389 Py_BEGIN_ALLOW_THREADS
Thomas Helleraf2be262007-07-12 11:03:13 +0000390#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000391 if (widename != NULL)
392 self->fd = _wopen(widename, flags, 0666);
393 else
Thomas Helleraf2be262007-07-12 11:03:13 +0000394#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000395 self->fd = open(name, flags, 0666);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000396 Py_END_ALLOW_THREADS
397 } while (self->fd < 0 && errno == EINTR &&
398 !(async_err = PyErr_CheckSignals()));
Victor Stinner9672da72015-03-04 18:40:10 +0100399
400 if (async_err)
401 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200402 }
403 else {
404 PyObject *fdobj;
405
406#ifndef MS_WINDOWS
407 /* the opener may clear the atomic flag */
408 atomic_flag_works = NULL;
409#endif
410
411 fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200412 if (fdobj == NULL)
413 goto error;
414 if (!PyLong_Check(fdobj)) {
415 Py_DECREF(fdobj);
416 PyErr_SetString(PyExc_TypeError,
417 "expected integer from opener");
418 goto error;
419 }
420
Serhiy Storchaka78980432013-01-15 01:12:17 +0200421 self->fd = _PyLong_AsInt(fdobj);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200422 Py_DECREF(fdobj);
423 if (self->fd == -1) {
424 goto error;
425 }
426 }
427
Hynek Schlawack7f59fd72012-06-22 09:32:22 +0200428 fd_is_own = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000429 if (self->fd < 0) {
Victor Stinner9672da72015-03-04 18:40:10 +0100430 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000431 goto error;
432 }
Victor Stinnerdaf45552013-08-28 00:53:59 +0200433
434#ifndef MS_WINDOWS
435 if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0)
436 goto error;
437#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000438 }
Antoine Pitroude687222014-06-29 20:07:28 -0400439
440 self->blksize = DEFAULT_BUFFER_SIZE;
Martin Panter0bb62b12015-12-06 03:15:05 +0000441 Py_BEGIN_ALLOW_THREADS
442 fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
443 Py_END_ALLOW_THREADS
444 if (fstat_result < 0) {
Martin Panter49d3db92015-12-06 11:12:15 +0000445 /* Tolerate fstat() errors other than EBADF. See Issue #25717, where
446 an anonymous file on a Virtual Box shared folder filesystem would
447 raise ENOENT. */
Martin Panter0bb62b12015-12-06 03:15:05 +0000448#ifdef MS_WINDOWS
449 if (GetLastError() == ERROR_INVALID_HANDLE) {
450 PyErr_SetFromWindowsErr(0);
451#else
452 if (errno == EBADF) {
453 PyErr_SetFromErrno(PyExc_OSError);
454#endif
455 goto error;
456 }
Antoine Pitroude687222014-06-29 20:07:28 -0400457 }
Martin Panter0bb62b12015-12-06 03:15:05 +0000458 else {
459#if defined(S_ISDIR) && defined(EISDIR)
460 /* On Unix, open will succeed for directories.
461 In Python, there should be no file objects referring to
462 directories, so we need a check. */
463 if (S_ISDIR(fdfstat.st_mode)) {
464 errno = EISDIR;
465 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
466 goto error;
467 }
Antoine Pitroude687222014-06-29 20:07:28 -0400468#endif /* defined(S_ISDIR) */
469#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin Panter0bb62b12015-12-06 03:15:05 +0000470 if (fdfstat.st_blksize > 1)
471 self->blksize = fdfstat.st_blksize;
Antoine Pitroude687222014-06-29 20:07:28 -0400472#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
Martin Panter0bb62b12015-12-06 03:15:05 +0000473 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000474
Victor Stinner89e34362011-01-07 18:47:22 +0000475#if defined(MS_WINDOWS) || defined(__CYGWIN__)
476 /* don't translate newlines (\r\n <=> \n) */
477 _setmode(self->fd, O_BINARY);
478#endif
479
Victor Stinnerd9d04192013-11-06 23:50:10 +0100480 if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000481 goto error;
Antoine Pitrou08838b62009-01-21 00:55:13 +0000482
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200483 if (self->appending) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000484 /* For consistent behaviour, we explicitly seek to the
485 end of file (otherwise, it might be done only on the
486 first write()). */
487 PyObject *pos = portable_lseek(self->fd, NULL, 2);
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200488 if (pos == NULL)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000489 goto error;
490 Py_DECREF(pos);
491 }
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000492
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000493 goto done;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000494
495 error:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000496 ret = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200497 if (!fd_is_own)
498 self->fd = -1;
Benjamin Petersonbbb04122010-10-30 23:16:28 +0000499 if (self->fd >= 0)
500 internal_close(self);
Guido van Rossum53807da2007-04-10 19:01:47 +0000501
Guido van Rossuma9e20242007-03-08 00:43:48 +0000502 done:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000503 Py_CLEAR(stringobj);
504 return ret;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000505}
506
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000507static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000508fileio_traverse(fileio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000509{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000510 Py_VISIT(self->dict);
511 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000512}
513
514static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000515fileio_clear(fileio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000516{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000517 Py_CLEAR(self->dict);
518 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000519}
520
Guido van Rossuma9e20242007-03-08 00:43:48 +0000521static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000522fileio_dealloc(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000523{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200524 self->finalizing = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000525 if (_PyIOBase_finalize((PyObject *) self) < 0)
526 return;
527 _PyObject_GC_UNTRACK(self);
528 if (self->weakreflist != NULL)
529 PyObject_ClearWeakRefs((PyObject *) self);
530 Py_CLEAR(self->dict);
531 Py_TYPE(self)->tp_free((PyObject *)self);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000532}
533
534static PyObject *
535err_closed(void)
536{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000537 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
538 return NULL;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000539}
540
541static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200542err_mode(const char *action)
Guido van Rossum53807da2007-04-10 19:01:47 +0000543{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100544 _PyIO_State *state = IO_STATE();
545 if (state != NULL)
546 PyErr_Format(state->unsupported_operation,
547 "File not open for %s", action);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000548 return NULL;
Guido van Rossum53807da2007-04-10 19:01:47 +0000549}
550
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300551/*[clinic input]
552_io.FileIO.fileno
553
554Return the underlying file descriptor (an integer).
555[clinic start generated code]*/
556
Guido van Rossum53807da2007-04-10 19:01:47 +0000557static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300558_io_FileIO_fileno_impl(fileio *self)
559/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000560{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000561 if (self->fd < 0)
562 return err_closed();
563 return PyLong_FromLong((long) self->fd);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000564}
565
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300566/*[clinic input]
567_io.FileIO.readable
568
569True if file was opened in a read mode.
570[clinic start generated code]*/
571
Guido van Rossuma9e20242007-03-08 00:43:48 +0000572static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300573_io_FileIO_readable_impl(fileio *self)
574/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000575{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000576 if (self->fd < 0)
577 return err_closed();
578 return PyBool_FromLong((long) self->readable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000579}
580
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300581/*[clinic input]
582_io.FileIO.writable
583
584True if file was opened in a write mode.
585[clinic start generated code]*/
586
Guido van Rossuma9e20242007-03-08 00:43:48 +0000587static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300588_io_FileIO_writable_impl(fileio *self)
589/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000590{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000591 if (self->fd < 0)
592 return err_closed();
593 return PyBool_FromLong((long) self->writable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000594}
595
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300596/*[clinic input]
597_io.FileIO.seekable
598
599True if file supports random-access.
600[clinic start generated code]*/
601
Guido van Rossuma9e20242007-03-08 00:43:48 +0000602static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300603_io_FileIO_seekable_impl(fileio *self)
604/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000605{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000606 if (self->fd < 0)
607 return err_closed();
608 if (self->seekable < 0) {
609 PyObject *pos = portable_lseek(self->fd, NULL, SEEK_CUR);
610 if (pos == NULL) {
611 PyErr_Clear();
612 self->seekable = 0;
613 } else {
614 Py_DECREF(pos);
615 self->seekable = 1;
616 }
617 }
618 return PyBool_FromLong((long) self->seekable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000619}
620
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300621/*[clinic input]
622_io.FileIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700623 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300624 /
625
626Same as RawIOBase.readinto().
627[clinic start generated code]*/
628
Guido van Rossuma9e20242007-03-08 00:43:48 +0000629static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300630_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700631/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000632{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100633 Py_ssize_t n;
634 int err;
Guido van Rossum53807da2007-04-10 19:01:47 +0000635
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000636 if (self->fd < 0)
637 return err_closed();
638 if (!self->readable)
639 return err_mode("reading");
Guido van Rossum53807da2007-04-10 19:01:47 +0000640
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300641 n = _Py_read(self->fd, buffer->buf, buffer->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100642 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100643 err = errno;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100644
645 if (n == -1) {
646 if (err == EAGAIN) {
647 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000648 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100649 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000650 return NULL;
651 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000652
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000653 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000654}
655
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656static size_t
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100657new_buffersize(fileio *self, size_t currentsize)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000658{
Antoine Pitroua3f44572012-04-17 13:50:58 +0200659 size_t addend;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100660
Nadeem Vawdad41a98b2011-10-13 13:34:16 +0200661 /* Expand the buffer by an amount proportional to the current size,
Antoine Pitroua3f44572012-04-17 13:50:58 +0200662 giving us amortized linear-time behavior. For bigger sizes, use a
663 less-than-double growth factor to avoid excessive allocation. */
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100664 assert(currentsize <= PY_SSIZE_T_MAX);
Antoine Pitroua3f44572012-04-17 13:50:58 +0200665 if (currentsize > 65536)
666 addend = currentsize >> 3;
667 else
668 addend = 256 + currentsize;
669 if (addend < SMALLCHUNK)
670 /* Avoid tiny read() calls. */
671 addend = SMALLCHUNK;
672 return addend + currentsize;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000673}
674
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300675/*[clinic input]
676_io.FileIO.readall
677
678Read all data from the file, returned as bytes.
679
680In non-blocking mode, returns as much as is immediately available,
681or None if no data is available. Return an empty bytes object at EOF.
682[clinic start generated code]*/
683
Guido van Rossum7165cb12007-07-10 06:54:34 +0000684static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300685_io_FileIO_readall_impl(fileio *self)
686/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/
Guido van Rossum7165cb12007-07-10 06:54:34 +0000687{
Victor Stinnere134a7f2015-03-30 10:09:31 +0200688 struct _Py_stat_struct status;
Victor Stinnera2a64772011-10-11 22:45:02 +0200689 Py_off_t pos, end;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000690 PyObject *result;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100691 Py_ssize_t bytes_read = 0;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100692 Py_ssize_t n;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100693 size_t bufsize;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000694
Victor Stinnerb79f28c2011-05-25 22:09:03 +0200695 if (self->fd < 0)
696 return err_closed();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000697 if (!_PyVerify_fd(self->fd))
698 return PyErr_SetFromErrno(PyExc_IOError);
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000699
Steve Dower8fc89802015-04-12 00:26:27 -0400700 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200701#ifdef MS_WINDOWS
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200702 pos = _lseeki64(self->fd, 0L, SEEK_CUR);
703#else
704 pos = lseek(self->fd, 0L, SEEK_CUR);
705#endif
Steve Dower8fc89802015-04-12 00:26:27 -0400706 _Py_END_SUPPRESS_IPH
707
Victor Stinnere134a7f2015-03-30 10:09:31 +0200708 if (_Py_fstat_noraise(self->fd, &status) == 0)
709 end = status.st_size;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200710 else
Victor Stinnera2a64772011-10-11 22:45:02 +0200711 end = (Py_off_t)-1;
Christian Heimesa872de52008-12-05 08:26:55 +0000712
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100713 if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) {
714 /* This is probably a real file, so we try to allocate a
715 buffer one byte larger than the rest of the file. If the
716 calculation is right then we should get EOF without having
717 to enlarge the buffer. */
718 bufsize = (size_t)(end - pos + 1);
719 } else {
720 bufsize = SMALLCHUNK;
721 }
722
723 result = PyBytes_FromStringAndSize(NULL, bufsize);
724 if (result == NULL)
725 return NULL;
726
727 while (1) {
728 if (bytes_read >= (Py_ssize_t)bufsize) {
729 bufsize = new_buffersize(self, bytes_read);
730 if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) {
731 PyErr_SetString(PyExc_OverflowError,
732 "unbounded read returned more bytes "
Serhiy Storchakab817b772015-04-10 02:18:44 +0300733 "than a Python bytes object can hold");
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100734 Py_DECREF(result);
735 return NULL;
736 }
737
738 if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) {
739 if (_PyBytes_Resize(&result, bufsize) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000740 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000741 }
742 }
Victor Stinner9672da72015-03-04 18:40:10 +0100743
Victor Stinner66aab0c2015-03-19 22:53:20 +0100744 n = _Py_read(self->fd,
745 PyBytes_AS_STRING(result) + bytes_read,
746 bufsize - bytes_read);
Victor Stinner9672da72015-03-04 18:40:10 +0100747
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000748 if (n == 0)
749 break;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100750 if (n == -1) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000751 if (errno == EAGAIN) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100752 PyErr_Clear();
Victor Stinnere10920f2014-07-02 22:59:31 +0200753 if (bytes_read > 0)
754 break;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000755 Py_DECREF(result);
756 Py_RETURN_NONE;
757 }
758 Py_DECREF(result);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000759 return NULL;
760 }
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100761 bytes_read += n;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200762 pos += n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000763 }
Guido van Rossum7165cb12007-07-10 06:54:34 +0000764
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100765 if (PyBytes_GET_SIZE(result) > bytes_read) {
766 if (_PyBytes_Resize(&result, bytes_read) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000767 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000768 }
769 return result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000770}
771
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300772/*[clinic input]
773_io.FileIO.read
774 size: io_ssize_t = -1
775 /
776
777Read at most size bytes, returned as bytes.
778
779Only makes one system call, so less data may be returned than requested.
780In non-blocking mode, returns None if no data is available.
781Return an empty bytes object at EOF.
782[clinic start generated code]*/
783
Guido van Rossuma9e20242007-03-08 00:43:48 +0000784static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300785_io_FileIO_read_impl(fileio *self, Py_ssize_t size)
786/*[clinic end generated code: output=42528d39dd0ca641 input=5c6caa5490c13a9b]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000787{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000788 char *ptr;
789 Py_ssize_t n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000790 PyObject *bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000791
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000792 if (self->fd < 0)
793 return err_closed();
794 if (!self->readable)
795 return err_mode("reading");
Guido van Rossuma9e20242007-03-08 00:43:48 +0000796
Victor Stinner66aab0c2015-03-19 22:53:20 +0100797 if (size < 0)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300798 return _io_FileIO_readall_impl(self);
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000799
Victor Stinner14b9b112013-06-25 00:37:25 +0200800#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +0100801 /* On Windows, the count parameter of read() is an int */
Victor Stinnerc655a722011-07-05 11:31:49 +0200802 if (size > INT_MAX)
803 size = INT_MAX;
804#endif
Victor Stinner66aab0c2015-03-19 22:53:20 +0100805
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000806 bytes = PyBytes_FromStringAndSize(NULL, size);
807 if (bytes == NULL)
808 return NULL;
809 ptr = PyBytes_AS_STRING(bytes);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000810
Victor Stinner66aab0c2015-03-19 22:53:20 +0100811 n = _Py_read(self->fd, ptr, size);
812 if (n == -1) {
813 /* copy errno because Py_DECREF() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100814 int err = errno;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000815 Py_DECREF(bytes);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100816 if (err == EAGAIN) {
817 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000818 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100819 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000820 return NULL;
821 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000822
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000823 if (n != size) {
824 if (_PyBytes_Resize(&bytes, n) < 0) {
Victor Stinner85c761d2013-07-16 21:36:02 +0200825 Py_CLEAR(bytes);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000826 return NULL;
827 }
828 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000829
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000830 return (PyObject *) bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000831}
832
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300833/*[clinic input]
834_io.FileIO.write
835 b: Py_buffer
836 /
837
838Write bytes b to file, return number written.
839
840Only makes one system call, so not all of the data may be written.
841The number of bytes actually written is returned. In non-blocking mode,
842returns None if the write would block.
843[clinic start generated code]*/
844
Guido van Rossuma9e20242007-03-08 00:43:48 +0000845static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300846_io_FileIO_write_impl(fileio *self, Py_buffer *b)
847/*[clinic end generated code: output=b4059db3d363a2f7 input=ffbd8834f447ac31]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000848{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100849 Py_ssize_t n;
850 int err;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000851
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000852 if (self->fd < 0)
853 return err_closed();
854 if (!self->writable)
855 return err_mode("writing");
Guido van Rossum53807da2007-04-10 19:01:47 +0000856
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300857 n = _Py_write(self->fd, b->buf, b->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100858 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100859 err = errno;
Martin v. Löwis423be952008-08-13 15:53:07 +0000860
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000861 if (n < 0) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100862 if (err == EAGAIN) {
863 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000864 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100865 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000866 return NULL;
867 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000868
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000869 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000870}
871
Guido van Rossum53807da2007-04-10 19:01:47 +0000872/* XXX Windows support below is likely incomplete */
873
Guido van Rossum53807da2007-04-10 19:01:47 +0000874/* Cribbed from posix_lseek() */
875static PyObject *
876portable_lseek(int fd, PyObject *posobj, int whence)
877{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000878 Py_off_t pos, res;
Guido van Rossum53807da2007-04-10 19:01:47 +0000879
880#ifdef SEEK_SET
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000881 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
882 switch (whence) {
Guido van Rossum53807da2007-04-10 19:01:47 +0000883#if SEEK_SET != 0
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000884 case 0: whence = SEEK_SET; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000885#endif
886#if SEEK_CUR != 1
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000887 case 1: whence = SEEK_CUR; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000888#endif
Antoine Pitrou4f7945f2009-01-20 11:42:11 +0000889#if SEEK_END != 2
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000890 case 2: whence = SEEK_END; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000891#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000892 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000893#endif /* SEEK_SET */
894
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000895 if (posobj == NULL)
896 pos = 0;
897 else {
898 if(PyFloat_Check(posobj)) {
899 PyErr_SetString(PyExc_TypeError, "an integer is required");
900 return NULL;
901 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000902#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000903 pos = PyLong_AsLongLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000904#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000905 pos = PyLong_AsLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000906#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000907 if (PyErr_Occurred())
908 return NULL;
909 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000910
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000911 if (_PyVerify_fd(fd)) {
912 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400913 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200914#ifdef MS_WINDOWS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000915 res = _lseeki64(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000916#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000917 res = lseek(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000918#endif
Steve Dower8fc89802015-04-12 00:26:27 -0400919 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000920 Py_END_ALLOW_THREADS
921 } else
922 res = -1;
923 if (res < 0)
924 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum53807da2007-04-10 19:01:47 +0000925
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000926#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000927 return PyLong_FromLongLong(res);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000928#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000929 return PyLong_FromLong(res);
Guido van Rossum53807da2007-04-10 19:01:47 +0000930#endif
931}
932
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300933/*[clinic input]
934_io.FileIO.seek
935 pos: object
936 whence: int = 0
937 /
Guido van Rossuma9e20242007-03-08 00:43:48 +0000938
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300939Move to new file position and return the file position.
940
941Argument offset is a byte count. Optional argument whence defaults to
942SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
943are SEEK_CUR or 1 (move relative to current position, positive or negative),
944and SEEK_END or 2 (move relative to end of file, usually negative, although
945many platforms allow seeking beyond the end of a file).
946
947Note that not all file objects are seekable.
948[clinic start generated code]*/
949
950static PyObject *
951_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
952/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/
953{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000954 if (self->fd < 0)
955 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000956
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300957 return portable_lseek(self->fd, pos, whence);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000958}
959
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300960/*[clinic input]
961_io.FileIO.tell
962
963Current file position.
964
965Can raise OSError for non seekable files.
966[clinic start generated code]*/
967
Guido van Rossuma9e20242007-03-08 00:43:48 +0000968static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300969_io_FileIO_tell_impl(fileio *self)
970/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000971{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000972 if (self->fd < 0)
973 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000974
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000975 return portable_lseek(self->fd, NULL, 1);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000976}
977
Thomas Hellerc6a55ee2007-07-11 12:45:46 +0000978#ifdef HAVE_FTRUNCATE
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300979/*[clinic input]
980_io.FileIO.truncate
981 size as posobj: object = NULL
982 /
983
984Truncate the file to at most size bytes and return the truncated size.
985
986Size defaults to the current file position, as returned by tell().
987The current file position is changed to the value of size.
988[clinic start generated code]*/
989
Guido van Rossuma9e20242007-03-08 00:43:48 +0000990static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300991_io_FileIO_truncate_impl(fileio *self, PyObject *posobj)
992/*[clinic end generated code: output=e49ca7a916c176fa input=9026af44686b7318]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000993{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000994 Py_off_t pos;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000995 int ret;
996 int fd;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000997
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000998 fd = self->fd;
999 if (fd < 0)
1000 return err_closed();
1001 if (!self->writable)
1002 return err_mode("writing");
Guido van Rossuma9e20242007-03-08 00:43:48 +00001003
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001004 if (posobj == Py_None || posobj == NULL) {
1005 /* Get the current position. */
1006 posobj = portable_lseek(fd, NULL, 1);
1007 if (posobj == NULL)
1008 return NULL;
1009 }
1010 else {
1011 Py_INCREF(posobj);
1012 }
Guido van Rossum53807da2007-04-10 19:01:47 +00001013
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001014#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001015 pos = PyLong_AsLongLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001016#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001017 pos = PyLong_AsLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001018#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001019 if (PyErr_Occurred()){
1020 Py_DECREF(posobj);
1021 return NULL;
1022 }
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001023
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001024 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04001025 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001026 errno = 0;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001027#ifdef MS_WINDOWS
1028 ret = _chsize_s(fd, pos);
1029#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001030 ret = ftruncate(fd, pos);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001031#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04001032 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001033 Py_END_ALLOW_THREADS
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001034
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001035 if (ret != 0) {
1036 Py_DECREF(posobj);
1037 PyErr_SetFromErrno(PyExc_IOError);
1038 return NULL;
1039 }
Guido van Rossuma9e20242007-03-08 00:43:48 +00001040
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001041 return posobj;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001042}
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001043#endif /* HAVE_FTRUNCATE */
Guido van Rossum53807da2007-04-10 19:01:47 +00001044
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001045static const char *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001046mode_string(fileio *self)
Guido van Rossum53807da2007-04-10 19:01:47 +00001047{
Charles-François Natalidc3044c2012-01-09 22:40:02 +01001048 if (self->created) {
1049 if (self->readable)
1050 return "xb+";
1051 else
1052 return "xb";
1053 }
Antoine Pitroue93b63b2013-09-04 20:46:33 +02001054 if (self->appending) {
1055 if (self->readable)
1056 return "ab+";
1057 else
1058 return "ab";
1059 }
1060 else if (self->readable) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001061 if (self->writable)
1062 return "rb+";
1063 else
1064 return "rb";
1065 }
1066 else
1067 return "wb";
Guido van Rossum53807da2007-04-10 19:01:47 +00001068}
Guido van Rossuma9e20242007-03-08 00:43:48 +00001069
1070static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001071fileio_repr(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +00001072{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001073 PyObject *nameobj, *res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001074
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001075 if (self->fd < 0)
1076 return PyUnicode_FromFormat("<_io.FileIO [closed]>");
Antoine Pitrou716c4442009-05-23 19:04:03 +00001077
Martin v. Löwis767046a2011-10-14 15:35:36 +02001078 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001079 if (nameobj == NULL) {
1080 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1081 PyErr_Clear();
1082 else
1083 return NULL;
Robert Collins933430a2014-10-18 13:32:43 +13001084 res = PyUnicode_FromFormat(
Serhiy Storchaka4954f9f2014-12-02 23:39:56 +02001085 "<_io.FileIO fd=%d mode='%s' closefd=%s>",
1086 self->fd, mode_string(self), self->closefd ? "True" : "False");
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001087 }
1088 else {
Robert Collins933430a2014-10-18 13:32:43 +13001089 res = PyUnicode_FromFormat(
Serhiy Storchaka4954f9f2014-12-02 23:39:56 +02001090 "<_io.FileIO name=%R mode='%s' closefd=%s>",
1091 nameobj, mode_string(self), self->closefd ? "True" : "False");
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001092 Py_DECREF(nameobj);
1093 }
1094 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001095}
1096
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001097/*[clinic input]
1098_io.FileIO.isatty
1099
1100True if the file is connected to a TTY device.
1101[clinic start generated code]*/
1102
Guido van Rossuma9e20242007-03-08 00:43:48 +00001103static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001104_io_FileIO_isatty_impl(fileio *self)
1105/*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +00001106{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001107 long res;
Guido van Rossum53807da2007-04-10 19:01:47 +00001108
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001109 if (self->fd < 0)
1110 return err_closed();
1111 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001112 _Py_BEGIN_SUPPRESS_IPH
1113 if (_PyVerify_fd(self->fd))
1114 res = isatty(self->fd);
1115 else
1116 res = 0;
1117 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001118 Py_END_ALLOW_THREADS
1119 return PyBool_FromLong(res);
Guido van Rossuma9e20242007-03-08 00:43:48 +00001120}
1121
Antoine Pitrou243757e2010-11-05 21:15:39 +00001122static PyObject *
1123fileio_getstate(fileio *self)
1124{
1125 PyErr_Format(PyExc_TypeError,
1126 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
1127 return NULL;
1128}
1129
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001130#include "clinic/fileio.c.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +00001131
1132static PyMethodDef fileio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001133 _IO_FILEIO_READ_METHODDEF
1134 _IO_FILEIO_READALL_METHODDEF
1135 _IO_FILEIO_READINTO_METHODDEF
1136 _IO_FILEIO_WRITE_METHODDEF
1137 _IO_FILEIO_SEEK_METHODDEF
1138 _IO_FILEIO_TELL_METHODDEF
1139 _IO_FILEIO_TRUNCATE_METHODDEF
1140 _IO_FILEIO_CLOSE_METHODDEF
1141 _IO_FILEIO_SEEKABLE_METHODDEF
1142 _IO_FILEIO_READABLE_METHODDEF
1143 _IO_FILEIO_WRITABLE_METHODDEF
1144 _IO_FILEIO_FILENO_METHODDEF
1145 _IO_FILEIO_ISATTY_METHODDEF
Antoine Pitroue033e062010-10-29 10:38:18 +00001146 {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001147 {"__getstate__", (PyCFunction)fileio_getstate, METH_NOARGS, NULL},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001148 {NULL, NULL} /* sentinel */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001149};
1150
Guido van Rossum53807da2007-04-10 19:01:47 +00001151/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */
1152
Guido van Rossumb0428152007-04-08 17:44:42 +00001153static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001154get_closed(fileio *self, void *closure)
Guido van Rossumb0428152007-04-08 17:44:42 +00001155{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001156 return PyBool_FromLong((long)(self->fd < 0));
Guido van Rossum53807da2007-04-10 19:01:47 +00001157}
1158
1159static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001160get_closefd(fileio *self, void *closure)
Christian Heimesecc42a22008-11-05 19:30:32 +00001161{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001162 return PyBool_FromLong((long)(self->closefd));
Christian Heimesecc42a22008-11-05 19:30:32 +00001163}
1164
1165static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001166get_mode(fileio *self, void *closure)
Guido van Rossum53807da2007-04-10 19:01:47 +00001167{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001168 return PyUnicode_FromString(mode_string(self));
Guido van Rossumb0428152007-04-08 17:44:42 +00001169}
1170
1171static PyGetSetDef fileio_getsetlist[] = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001172 {"closed", (getter)get_closed, NULL, "True if the file is closed"},
1173 {"closefd", (getter)get_closefd, NULL,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +03001174 "True if the file descriptor will be closed by close()."},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001175 {"mode", (getter)get_mode, NULL, "String giving the file mode"},
1176 {NULL},
Guido van Rossumb0428152007-04-08 17:44:42 +00001177};
1178
Antoine Pitrou796564c2013-07-30 19:59:21 +02001179static PyMemberDef fileio_members[] = {
Antoine Pitroude687222014-06-29 20:07:28 -04001180 {"_blksize", T_UINT, offsetof(fileio, blksize), 0},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001181 {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
1182 {NULL}
1183};
1184
Guido van Rossuma9e20242007-03-08 00:43:48 +00001185PyTypeObject PyFileIO_Type = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001186 PyVarObject_HEAD_INIT(NULL, 0)
1187 "_io.FileIO",
1188 sizeof(fileio),
1189 0,
1190 (destructor)fileio_dealloc, /* tp_dealloc */
1191 0, /* tp_print */
1192 0, /* tp_getattr */
1193 0, /* tp_setattr */
1194 0, /* tp_reserved */
1195 (reprfunc)fileio_repr, /* tp_repr */
1196 0, /* tp_as_number */
1197 0, /* tp_as_sequence */
1198 0, /* tp_as_mapping */
1199 0, /* tp_hash */
1200 0, /* tp_call */
1201 0, /* tp_str */
1202 PyObject_GenericGetAttr, /* tp_getattro */
1203 0, /* tp_setattro */
1204 0, /* tp_as_buffer */
1205 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001206 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001207 _io_FileIO___init____doc__, /* tp_doc */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001208 (traverseproc)fileio_traverse, /* tp_traverse */
1209 (inquiry)fileio_clear, /* tp_clear */
1210 0, /* tp_richcompare */
1211 offsetof(fileio, weakreflist), /* tp_weaklistoffset */
1212 0, /* tp_iter */
1213 0, /* tp_iternext */
1214 fileio_methods, /* tp_methods */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001215 fileio_members, /* tp_members */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001216 fileio_getsetlist, /* tp_getset */
1217 0, /* tp_base */
1218 0, /* tp_dict */
1219 0, /* tp_descr_get */
1220 0, /* tp_descr_set */
1221 offsetof(fileio, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001222 _io_FileIO___init__, /* tp_init */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001223 PyType_GenericAlloc, /* tp_alloc */
1224 fileio_new, /* tp_new */
1225 PyObject_GC_Del, /* tp_free */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001226 0, /* tp_is_gc */
1227 0, /* tp_bases */
1228 0, /* tp_mro */
1229 0, /* tp_cache */
1230 0, /* tp_subclasses */
1231 0, /* tp_weaklist */
1232 0, /* tp_del */
1233 0, /* tp_version_tag */
1234 0, /* tp_finalize */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001235};