blob: 7f3bcab9625ef51a4703d7fdea68ce9c69c19ec8 [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
55/*[python input]
56class io_ssize_t_converter(CConverter):
57 type = 'Py_ssize_t'
58 converter = '_PyIO_ConvertSsize_t'
59[python start generated code]*/
60/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/
61
Guido van Rossuma9e20242007-03-08 00:43:48 +000062typedef struct {
Antoine Pitrouae4b4722010-05-05 16:31:07 +000063 PyObject_HEAD
64 int fd;
Charles-François Natalidc3044c2012-01-09 22:40:02 +010065 unsigned int created : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000066 unsigned int readable : 1;
67 unsigned int writable : 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +020068 unsigned int appending : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000069 signed int seekable : 2; /* -1 means unknown */
70 unsigned int closefd : 1;
Antoine Pitrou796564c2013-07-30 19:59:21 +020071 char finalizing;
Antoine Pitroude687222014-06-29 20:07:28 -040072 unsigned int blksize;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000073 PyObject *weakreflist;
74 PyObject *dict;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000075} fileio;
Guido van Rossuma9e20242007-03-08 00:43:48 +000076
Collin Winteraf334382007-03-08 21:46:15 +000077PyTypeObject PyFileIO_Type;
78
Victor Stinnerd9d04192013-11-06 23:50:10 +010079_Py_IDENTIFIER(name);
80
Guido van Rossuma9e20242007-03-08 00:43:48 +000081#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
82
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000083int
84_PyFileIO_closed(PyObject *self)
85{
Antoine Pitrouae4b4722010-05-05 16:31:07 +000086 return ((fileio *)self)->fd < 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000087}
Antoine Pitrou08838b62009-01-21 00:55:13 +000088
Antoine Pitroue033e062010-10-29 10:38:18 +000089/* Because this can call arbitrary code, it shouldn't be called when
90 the refcount is 0 (that is, not directly from tp_dealloc unless
91 the refcount has been temporarily re-incremented). */
92static PyObject *
93fileio_dealloc_warn(fileio *self, PyObject *source)
94{
95 if (self->fd >= 0 && self->closefd) {
96 PyObject *exc, *val, *tb;
97 PyErr_Fetch(&exc, &val, &tb);
Victor Stinner914cde82016-03-19 01:03:51 +010098 if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) {
Antoine Pitroue033e062010-10-29 10:38:18 +000099 /* Spurious errors can appear at shutdown */
100 if (PyErr_ExceptionMatches(PyExc_Warning))
101 PyErr_WriteUnraisable((PyObject *) self);
102 }
103 PyErr_Restore(exc, val, tb);
104 }
105 Py_RETURN_NONE;
106}
107
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000108static PyObject *
109portable_lseek(int fd, PyObject *posobj, int whence);
110
Antoine Pitroua28fcfd2009-03-13 23:42:55 +0000111static PyObject *portable_lseek(int fd, PyObject *posobj, int whence);
112
Kristján Valur Jónsson19288c22008-12-18 17:15:54 +0000113/* Returns 0 on success, -1 with exception set on failure. */
Neal Norwitz88b44da2007-08-12 17:23:54 +0000114static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000115internal_close(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000116{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000117 int err = 0;
118 int save_errno = 0;
119 if (self->fd >= 0) {
120 int fd = self->fd;
121 self->fd = -1;
122 /* fd is accessible and someone else may have closed it */
Steve Dower940f33a2016-09-08 11:21:54 -0700123 Py_BEGIN_ALLOW_THREADS
124 _Py_BEGIN_SUPPRESS_IPH
125 err = close(fd);
126 if (err < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000127 save_errno = errno;
Steve Dower940f33a2016-09-08 11:21:54 -0700128 _Py_END_SUPPRESS_IPH
129 Py_END_ALLOW_THREADS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000130 }
131 if (err < 0) {
132 errno = save_errno;
133 PyErr_SetFromErrno(PyExc_IOError);
134 return -1;
135 }
136 return 0;
Neal Norwitz88b44da2007-08-12 17:23:54 +0000137}
138
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300139/*[clinic input]
140_io.FileIO.close
141
142Close the file.
143
144A closed file cannot be used for further I/O operations. close() may be
145called more than once without error.
146[clinic start generated code]*/
147
Neal Norwitz88b44da2007-08-12 17:23:54 +0000148static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300149_io_FileIO_close_impl(fileio *self)
150/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/
Neal Norwitz88b44da2007-08-12 17:23:54 +0000151{
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200152 PyObject *res;
153 PyObject *exc, *val, *tb;
154 int rc;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200155 _Py_IDENTIFIER(close);
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200156 res = _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type,
157 &PyId_close, "O", self);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000158 if (!self->closefd) {
159 self->fd = -1;
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200160 return res;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000161 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200162 if (res == NULL)
163 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou796564c2013-07-30 19:59:21 +0200164 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000165 PyObject *r = fileio_dealloc_warn(self, (PyObject *) self);
166 if (r)
167 Py_DECREF(r);
168 else
169 PyErr_Clear();
170 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200171 rc = internal_close(self);
172 if (res == NULL)
173 _PyErr_ChainExceptions(exc, val, tb);
174 if (rc < 0)
175 Py_CLEAR(res);
176 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000177}
178
179static PyObject *
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000180fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000181{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000182 fileio *self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000183
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000184 assert(type != NULL && type->tp_alloc != NULL);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000185
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000186 self = (fileio *) type->tp_alloc(type, 0);
187 if (self != NULL) {
188 self->fd = -1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100189 self->created = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000190 self->readable = 0;
191 self->writable = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200192 self->appending = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000193 self->seekable = -1;
Antoine Pitroude687222014-06-29 20:07:28 -0400194 self->blksize = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000195 self->closefd = 1;
196 self->weakreflist = NULL;
197 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000198
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000199 return (PyObject *) self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000200}
201
Victor Stinnerdaf45552013-08-28 00:53:59 +0200202#ifdef O_CLOEXEC
203extern int _Py_open_cloexec_works;
204#endif
Guido van Rossuma9e20242007-03-08 00:43:48 +0000205
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300206/*[clinic input]
207_io.FileIO.__init__
208 file as nameobj: object
209 mode: str = "r"
210 closefd: int(c_default="1") = True
211 opener: object = None
212
213Open a file.
214
215The mode can be 'r' (default), 'w', 'x' or 'a' for reading,
216writing, exclusive creation or appending. The file will be created if it
217doesn't exist when opened for writing or appending; it will be truncated
218when opened for writing. A FileExistsError will be raised if it already
219exists when opened for creating. Opening a file for creating implies
220writing so this mode behaves in a similar way to 'w'.Add a '+' to the mode
221to allow simultaneous reading and writing. A custom opener can be used by
222passing a callable as *opener*. The underlying file descriptor for the file
223object is then obtained by calling opener with (*name*, *flags*).
224*opener* must return an open file descriptor (passing os.open as *opener*
225results in functionality similar to passing None).
226[clinic start generated code]*/
227
Guido van Rossuma9e20242007-03-08 00:43:48 +0000228static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300229_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
230 int closefd, PyObject *opener)
231/*[clinic end generated code: output=23413f68e6484bbd input=193164e293d6c097]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000232{
Thomas Helleraf2be262007-07-12 11:03:13 +0000233#ifdef MS_WINDOWS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000234 Py_UNICODE *widename = NULL;
Steve Dowereacee982017-02-04 14:38:11 -0800235#else
236 const char *name = NULL;
Thomas Helleraf2be262007-07-12 11:03:13 +0000237#endif
Steve Dowereacee982017-02-04 14:38:11 -0800238 PyObject *stringobj = NULL;
239 const char *s;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000240 int ret = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200241 int rwa = 0, plus = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000242 int flags = 0;
243 int fd = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200244 int fd_is_own = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200245#ifdef O_CLOEXEC
246 int *atomic_flag_works = &_Py_open_cloexec_works;
247#elif !defined(MS_WINDOWS)
248 int *atomic_flag_works = NULL;
249#endif
Steve Dowerf2f373f2015-02-21 08:44:05 -0800250 struct _Py_stat_struct fdfstat;
Martin Panter0bb62b12015-12-06 03:15:05 +0000251 int fstat_result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000252 int async_err = 0;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000253
Christian Heimes82adeff2015-04-16 17:21:54 +0200254 assert(PyFileIO_Check(self));
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000255 if (self->fd >= 0) {
Hynek Schlawack2cc71562012-05-25 10:05:53 +0200256 if (self->closefd) {
257 /* Have to close the existing file first. */
258 if (internal_close(self) < 0)
259 return -1;
260 }
261 else
262 self->fd = -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000263 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000264
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000265 if (PyFloat_Check(nameobj)) {
266 PyErr_SetString(PyExc_TypeError,
267 "integer argument expected, got float");
268 return -1;
269 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000270
Serhiy Storchaka78980432013-01-15 01:12:17 +0200271 fd = _PyLong_AsInt(nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000272 if (fd < 0) {
273 if (!PyErr_Occurred()) {
274 PyErr_SetString(PyExc_ValueError,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +0300275 "negative file descriptor");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000276 return -1;
277 }
278 PyErr_Clear();
279 }
Guido van Rossumb0428152007-04-08 17:44:42 +0000280
Steve Dowereacee982017-02-04 14:38:11 -0800281 if (fd < 0) {
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000282#ifdef MS_WINDOWS
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300283 Py_ssize_t length;
Steve Dowereacee982017-02-04 14:38:11 -0800284 if (!PyUnicode_FSDecoder(nameobj, &stringobj)) {
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300285 return -1;
286 }
Steve Dowereacee982017-02-04 14:38:11 -0800287 widename = PyUnicode_AsUnicodeAndSize(stringobj, &length);
288 if (widename == NULL)
289 return -1;
290#else
Antoine Pitrou13348842012-01-29 18:36:34 +0100291 if (!PyUnicode_FSConverter(nameobj, &stringobj)) {
292 return -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000293 }
Antoine Pitrou13348842012-01-29 18:36:34 +0100294 name = PyBytes_AS_STRING(stringobj);
Steve Dowereacee982017-02-04 14:38:11 -0800295#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000296 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000297
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000298 s = mode;
299 while (*s) {
300 switch (*s++) {
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100301 case 'x':
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000302 if (rwa) {
303 bad_mode:
304 PyErr_SetString(PyExc_ValueError,
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100305 "Must have exactly one of create/read/write/append "
Georg Brandl28928ae2010-10-21 13:45:52 +0000306 "mode and at most one plus");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000307 goto error;
308 }
309 rwa = 1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100310 self->created = 1;
311 self->writable = 1;
312 flags |= O_EXCL | O_CREAT;
313 break;
314 case 'r':
315 if (rwa)
316 goto bad_mode;
317 rwa = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000318 self->readable = 1;
319 break;
320 case 'w':
321 if (rwa)
322 goto bad_mode;
323 rwa = 1;
324 self->writable = 1;
325 flags |= O_CREAT | O_TRUNC;
326 break;
327 case 'a':
328 if (rwa)
329 goto bad_mode;
330 rwa = 1;
331 self->writable = 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200332 self->appending = 1;
333 flags |= O_APPEND | O_CREAT;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000334 break;
335 case 'b':
336 break;
337 case '+':
338 if (plus)
339 goto bad_mode;
340 self->readable = self->writable = 1;
341 plus = 1;
342 break;
343 default:
344 PyErr_Format(PyExc_ValueError,
345 "invalid mode: %.200s", mode);
346 goto error;
347 }
348 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000349
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000350 if (!rwa)
351 goto bad_mode;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000352
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000353 if (self->readable && self->writable)
354 flags |= O_RDWR;
355 else if (self->readable)
356 flags |= O_RDONLY;
357 else
358 flags |= O_WRONLY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000359
360#ifdef O_BINARY
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000361 flags |= O_BINARY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000362#endif
363
Victor Stinnerdaf45552013-08-28 00:53:59 +0200364#ifdef MS_WINDOWS
365 flags |= O_NOINHERIT;
366#elif defined(O_CLOEXEC)
367 flags |= O_CLOEXEC;
368#endif
Walter Dörwald0e411482007-06-06 16:55:38 +0000369
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000370 if (fd >= 0) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000371 self->fd = fd;
372 self->closefd = closefd;
373 }
374 else {
375 self->closefd = 1;
376 if (!closefd) {
377 PyErr_SetString(PyExc_ValueError,
378 "Cannot use closefd=False with file name");
379 goto error;
380 }
Guido van Rossum2dced8b2007-10-30 17:27:30 +0000381
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000382 errno = 0;
Ross Lagerwall59142db2011-10-31 20:34:46 +0200383 if (opener == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000384 do {
385 Py_BEGIN_ALLOW_THREADS
Thomas Helleraf2be262007-07-12 11:03:13 +0000386#ifdef MS_WINDOWS
Steve Dowereacee982017-02-04 14:38:11 -0800387 self->fd = _wopen(widename, flags, 0666);
388#else
389 self->fd = open(name, flags, 0666);
Thomas Helleraf2be262007-07-12 11:03:13 +0000390#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000391 Py_END_ALLOW_THREADS
392 } while (self->fd < 0 && errno == EINTR &&
393 !(async_err = PyErr_CheckSignals()));
Victor Stinner9672da72015-03-04 18:40:10 +0100394
395 if (async_err)
396 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200397 }
398 else {
399 PyObject *fdobj;
400
401#ifndef MS_WINDOWS
402 /* the opener may clear the atomic flag */
403 atomic_flag_works = NULL;
404#endif
405
406 fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200407 if (fdobj == NULL)
408 goto error;
409 if (!PyLong_Check(fdobj)) {
410 Py_DECREF(fdobj);
411 PyErr_SetString(PyExc_TypeError,
412 "expected integer from opener");
413 goto error;
414 }
415
Serhiy Storchaka78980432013-01-15 01:12:17 +0200416 self->fd = _PyLong_AsInt(fdobj);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200417 Py_DECREF(fdobj);
Barry Warsaw480e2852016-06-08 17:47:26 -0400418 if (self->fd < 0) {
419 if (!PyErr_Occurred()) {
Barry Warsaw118598a2016-06-08 17:54:43 -0400420 /* The opener returned a negative but didn't set an
421 exception. See issue #27066 */
Barry Warsaw480e2852016-06-08 17:47:26 -0400422 PyErr_Format(PyExc_ValueError,
423 "opener returned %d", self->fd);
424 }
Ross Lagerwall59142db2011-10-31 20:34:46 +0200425 goto error;
426 }
427 }
428
Hynek Schlawack7f59fd72012-06-22 09:32:22 +0200429 fd_is_own = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000430 if (self->fd < 0) {
Victor Stinner9672da72015-03-04 18:40:10 +0100431 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000432 goto error;
433 }
Victor Stinnerdaf45552013-08-28 00:53:59 +0200434
435#ifndef MS_WINDOWS
436 if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0)
437 goto error;
438#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000439 }
Antoine Pitroude687222014-06-29 20:07:28 -0400440
441 self->blksize = DEFAULT_BUFFER_SIZE;
Martin Panter0bb62b12015-12-06 03:15:05 +0000442 Py_BEGIN_ALLOW_THREADS
443 fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
444 Py_END_ALLOW_THREADS
445 if (fstat_result < 0) {
Martin Panter49d3db92015-12-06 11:12:15 +0000446 /* Tolerate fstat() errors other than EBADF. See Issue #25717, where
447 an anonymous file on a Virtual Box shared folder filesystem would
448 raise ENOENT. */
Martin Panter0bb62b12015-12-06 03:15:05 +0000449#ifdef MS_WINDOWS
450 if (GetLastError() == ERROR_INVALID_HANDLE) {
451 PyErr_SetFromWindowsErr(0);
452#else
453 if (errno == EBADF) {
454 PyErr_SetFromErrno(PyExc_OSError);
455#endif
456 goto error;
457 }
Antoine Pitroude687222014-06-29 20:07:28 -0400458 }
Martin Panter0bb62b12015-12-06 03:15:05 +0000459 else {
460#if defined(S_ISDIR) && defined(EISDIR)
461 /* On Unix, open will succeed for directories.
462 In Python, there should be no file objects referring to
463 directories, so we need a check. */
464 if (S_ISDIR(fdfstat.st_mode)) {
465 errno = EISDIR;
466 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
467 goto error;
468 }
Antoine Pitroude687222014-06-29 20:07:28 -0400469#endif /* defined(S_ISDIR) */
470#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin Panter0bb62b12015-12-06 03:15:05 +0000471 if (fdfstat.st_blksize > 1)
472 self->blksize = fdfstat.st_blksize;
Antoine Pitroude687222014-06-29 20:07:28 -0400473#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
Martin Panter0bb62b12015-12-06 03:15:05 +0000474 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000475
Victor Stinner89e34362011-01-07 18:47:22 +0000476#if defined(MS_WINDOWS) || defined(__CYGWIN__)
477 /* don't translate newlines (\r\n <=> \n) */
478 _setmode(self->fd, O_BINARY);
479#endif
480
Victor Stinnerd9d04192013-11-06 23:50:10 +0100481 if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000482 goto error;
Antoine Pitrou08838b62009-01-21 00:55:13 +0000483
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200484 if (self->appending) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000485 /* For consistent behaviour, we explicitly seek to the
486 end of file (otherwise, it might be done only on the
487 first write()). */
488 PyObject *pos = portable_lseek(self->fd, NULL, 2);
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200489 if (pos == NULL)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000490 goto error;
491 Py_DECREF(pos);
492 }
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000493
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000494 goto done;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000495
496 error:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000497 ret = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200498 if (!fd_is_own)
499 self->fd = -1;
Benjamin Petersonbbb04122010-10-30 23:16:28 +0000500 if (self->fd >= 0)
501 internal_close(self);
Guido van Rossum53807da2007-04-10 19:01:47 +0000502
Guido van Rossuma9e20242007-03-08 00:43:48 +0000503 done:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000504 Py_CLEAR(stringobj);
505 return ret;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000506}
507
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000508static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000509fileio_traverse(fileio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000510{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000511 Py_VISIT(self->dict);
512 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000513}
514
515static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000516fileio_clear(fileio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000517{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000518 Py_CLEAR(self->dict);
519 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000520}
521
Guido van Rossuma9e20242007-03-08 00:43:48 +0000522static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000523fileio_dealloc(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000524{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200525 self->finalizing = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000526 if (_PyIOBase_finalize((PyObject *) self) < 0)
527 return;
528 _PyObject_GC_UNTRACK(self);
529 if (self->weakreflist != NULL)
530 PyObject_ClearWeakRefs((PyObject *) self);
531 Py_CLEAR(self->dict);
532 Py_TYPE(self)->tp_free((PyObject *)self);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000533}
534
535static PyObject *
536err_closed(void)
537{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000538 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
539 return NULL;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000540}
541
542static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200543err_mode(const char *action)
Guido van Rossum53807da2007-04-10 19:01:47 +0000544{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100545 _PyIO_State *state = IO_STATE();
546 if (state != NULL)
547 PyErr_Format(state->unsupported_operation,
548 "File not open for %s", action);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000549 return NULL;
Guido van Rossum53807da2007-04-10 19:01:47 +0000550}
551
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300552/*[clinic input]
553_io.FileIO.fileno
554
555Return the underlying file descriptor (an integer).
556[clinic start generated code]*/
557
Guido van Rossum53807da2007-04-10 19:01:47 +0000558static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300559_io_FileIO_fileno_impl(fileio *self)
560/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000561{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000562 if (self->fd < 0)
563 return err_closed();
564 return PyLong_FromLong((long) self->fd);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000565}
566
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300567/*[clinic input]
568_io.FileIO.readable
569
570True if file was opened in a read mode.
571[clinic start generated code]*/
572
Guido van Rossuma9e20242007-03-08 00:43:48 +0000573static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300574_io_FileIO_readable_impl(fileio *self)
575/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000576{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000577 if (self->fd < 0)
578 return err_closed();
579 return PyBool_FromLong((long) self->readable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000580}
581
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300582/*[clinic input]
583_io.FileIO.writable
584
585True if file was opened in a write mode.
586[clinic start generated code]*/
587
Guido van Rossuma9e20242007-03-08 00:43:48 +0000588static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300589_io_FileIO_writable_impl(fileio *self)
590/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000591{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000592 if (self->fd < 0)
593 return err_closed();
594 return PyBool_FromLong((long) self->writable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000595}
596
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300597/*[clinic input]
598_io.FileIO.seekable
599
600True if file supports random-access.
601[clinic start generated code]*/
602
Guido van Rossuma9e20242007-03-08 00:43:48 +0000603static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300604_io_FileIO_seekable_impl(fileio *self)
605/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000606{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000607 if (self->fd < 0)
608 return err_closed();
609 if (self->seekable < 0) {
610 PyObject *pos = portable_lseek(self->fd, NULL, SEEK_CUR);
611 if (pos == NULL) {
612 PyErr_Clear();
613 self->seekable = 0;
614 } else {
615 Py_DECREF(pos);
616 self->seekable = 1;
617 }
618 }
619 return PyBool_FromLong((long) self->seekable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000620}
621
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300622/*[clinic input]
623_io.FileIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700624 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300625 /
626
627Same as RawIOBase.readinto().
628[clinic start generated code]*/
629
Guido van Rossuma9e20242007-03-08 00:43:48 +0000630static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300631_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700632/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000633{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100634 Py_ssize_t n;
635 int err;
Guido van Rossum53807da2007-04-10 19:01:47 +0000636
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000637 if (self->fd < 0)
638 return err_closed();
639 if (!self->readable)
640 return err_mode("reading");
Guido van Rossum53807da2007-04-10 19:01:47 +0000641
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300642 n = _Py_read(self->fd, buffer->buf, buffer->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100643 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100644 err = errno;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100645
646 if (n == -1) {
647 if (err == EAGAIN) {
648 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000649 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100650 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000651 return NULL;
652 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000653
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000654 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000655}
656
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000657static size_t
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100658new_buffersize(fileio *self, size_t currentsize)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000659{
Antoine Pitroua3f44572012-04-17 13:50:58 +0200660 size_t addend;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100661
Nadeem Vawdad41a98b2011-10-13 13:34:16 +0200662 /* Expand the buffer by an amount proportional to the current size,
Antoine Pitroua3f44572012-04-17 13:50:58 +0200663 giving us amortized linear-time behavior. For bigger sizes, use a
664 less-than-double growth factor to avoid excessive allocation. */
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100665 assert(currentsize <= PY_SSIZE_T_MAX);
Antoine Pitroua3f44572012-04-17 13:50:58 +0200666 if (currentsize > 65536)
667 addend = currentsize >> 3;
668 else
669 addend = 256 + currentsize;
670 if (addend < SMALLCHUNK)
671 /* Avoid tiny read() calls. */
672 addend = SMALLCHUNK;
673 return addend + currentsize;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000674}
675
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300676/*[clinic input]
677_io.FileIO.readall
678
679Read all data from the file, returned as bytes.
680
681In non-blocking mode, returns as much as is immediately available,
682or None if no data is available. Return an empty bytes object at EOF.
683[clinic start generated code]*/
684
Guido van Rossum7165cb12007-07-10 06:54:34 +0000685static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300686_io_FileIO_readall_impl(fileio *self)
687/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/
Guido van Rossum7165cb12007-07-10 06:54:34 +0000688{
Victor Stinnere134a7f2015-03-30 10:09:31 +0200689 struct _Py_stat_struct status;
Victor Stinnera2a64772011-10-11 22:45:02 +0200690 Py_off_t pos, end;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000691 PyObject *result;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100692 Py_ssize_t bytes_read = 0;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100693 Py_ssize_t n;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100694 size_t bufsize;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000695
Victor Stinnerb79f28c2011-05-25 22:09:03 +0200696 if (self->fd < 0)
697 return err_closed();
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000698
Steve Dower8fc89802015-04-12 00:26:27 -0400699 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200700#ifdef MS_WINDOWS
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200701 pos = _lseeki64(self->fd, 0L, SEEK_CUR);
702#else
703 pos = lseek(self->fd, 0L, SEEK_CUR);
704#endif
Steve Dower8fc89802015-04-12 00:26:27 -0400705 _Py_END_SUPPRESS_IPH
706
Victor Stinnere134a7f2015-03-30 10:09:31 +0200707 if (_Py_fstat_noraise(self->fd, &status) == 0)
708 end = status.st_size;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200709 else
Victor Stinnera2a64772011-10-11 22:45:02 +0200710 end = (Py_off_t)-1;
Christian Heimesa872de52008-12-05 08:26:55 +0000711
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100712 if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) {
713 /* This is probably a real file, so we try to allocate a
714 buffer one byte larger than the rest of the file. If the
715 calculation is right then we should get EOF without having
716 to enlarge the buffer. */
717 bufsize = (size_t)(end - pos + 1);
718 } else {
719 bufsize = SMALLCHUNK;
720 }
721
722 result = PyBytes_FromStringAndSize(NULL, bufsize);
723 if (result == NULL)
724 return NULL;
725
726 while (1) {
727 if (bytes_read >= (Py_ssize_t)bufsize) {
728 bufsize = new_buffersize(self, bytes_read);
729 if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) {
730 PyErr_SetString(PyExc_OverflowError,
731 "unbounded read returned more bytes "
Serhiy Storchakab817b772015-04-10 02:18:44 +0300732 "than a Python bytes object can hold");
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100733 Py_DECREF(result);
734 return NULL;
735 }
736
737 if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) {
738 if (_PyBytes_Resize(&result, bufsize) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000739 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000740 }
741 }
Victor Stinner9672da72015-03-04 18:40:10 +0100742
Victor Stinner66aab0c2015-03-19 22:53:20 +0100743 n = _Py_read(self->fd,
744 PyBytes_AS_STRING(result) + bytes_read,
745 bufsize - bytes_read);
Victor Stinner9672da72015-03-04 18:40:10 +0100746
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000747 if (n == 0)
748 break;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100749 if (n == -1) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000750 if (errno == EAGAIN) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100751 PyErr_Clear();
Victor Stinnere10920f2014-07-02 22:59:31 +0200752 if (bytes_read > 0)
753 break;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000754 Py_DECREF(result);
755 Py_RETURN_NONE;
756 }
757 Py_DECREF(result);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000758 return NULL;
759 }
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100760 bytes_read += n;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200761 pos += n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000762 }
Guido van Rossum7165cb12007-07-10 06:54:34 +0000763
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100764 if (PyBytes_GET_SIZE(result) > bytes_read) {
765 if (_PyBytes_Resize(&result, bytes_read) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000766 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000767 }
768 return result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000769}
770
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300771/*[clinic input]
772_io.FileIO.read
773 size: io_ssize_t = -1
774 /
775
776Read at most size bytes, returned as bytes.
777
778Only makes one system call, so less data may be returned than requested.
779In non-blocking mode, returns None if no data is available.
780Return an empty bytes object at EOF.
781[clinic start generated code]*/
782
Guido van Rossuma9e20242007-03-08 00:43:48 +0000783static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300784_io_FileIO_read_impl(fileio *self, Py_ssize_t size)
785/*[clinic end generated code: output=42528d39dd0ca641 input=5c6caa5490c13a9b]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000786{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000787 char *ptr;
788 Py_ssize_t n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000789 PyObject *bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000790
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000791 if (self->fd < 0)
792 return err_closed();
793 if (!self->readable)
794 return err_mode("reading");
Guido van Rossuma9e20242007-03-08 00:43:48 +0000795
Victor Stinner66aab0c2015-03-19 22:53:20 +0100796 if (size < 0)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300797 return _io_FileIO_readall_impl(self);
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000798
Victor Stinner14b9b112013-06-25 00:37:25 +0200799#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +0100800 /* On Windows, the count parameter of read() is an int */
Victor Stinnerc655a722011-07-05 11:31:49 +0200801 if (size > INT_MAX)
802 size = INT_MAX;
803#endif
Victor Stinner66aab0c2015-03-19 22:53:20 +0100804
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000805 bytes = PyBytes_FromStringAndSize(NULL, size);
806 if (bytes == NULL)
807 return NULL;
808 ptr = PyBytes_AS_STRING(bytes);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000809
Victor Stinner66aab0c2015-03-19 22:53:20 +0100810 n = _Py_read(self->fd, ptr, size);
811 if (n == -1) {
812 /* copy errno because Py_DECREF() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100813 int err = errno;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000814 Py_DECREF(bytes);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100815 if (err == EAGAIN) {
816 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000817 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100818 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000819 return NULL;
820 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000821
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000822 if (n != size) {
823 if (_PyBytes_Resize(&bytes, n) < 0) {
Victor Stinner85c761d2013-07-16 21:36:02 +0200824 Py_CLEAR(bytes);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000825 return NULL;
826 }
827 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000828
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000829 return (PyObject *) bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000830}
831
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300832/*[clinic input]
833_io.FileIO.write
834 b: Py_buffer
835 /
836
Martin Panter6bb91f32016-05-28 00:41:57 +0000837Write buffer b to file, return number of bytes written.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300838
839Only makes one system call, so not all of the data may be written.
840The number of bytes actually written is returned. In non-blocking mode,
841returns None if the write would block.
842[clinic start generated code]*/
843
Guido van Rossuma9e20242007-03-08 00:43:48 +0000844static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300845_io_FileIO_write_impl(fileio *self, Py_buffer *b)
Martin Panter6bb91f32016-05-28 00:41:57 +0000846/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000847{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100848 Py_ssize_t n;
849 int err;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000850
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000851 if (self->fd < 0)
852 return err_closed();
853 if (!self->writable)
854 return err_mode("writing");
Guido van Rossum53807da2007-04-10 19:01:47 +0000855
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300856 n = _Py_write(self->fd, b->buf, b->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100857 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100858 err = errno;
Martin v. Löwis423be952008-08-13 15:53:07 +0000859
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000860 if (n < 0) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100861 if (err == EAGAIN) {
862 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000863 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100864 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000865 return NULL;
866 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000867
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000868 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000869}
870
Guido van Rossum53807da2007-04-10 19:01:47 +0000871/* XXX Windows support below is likely incomplete */
872
Guido van Rossum53807da2007-04-10 19:01:47 +0000873/* Cribbed from posix_lseek() */
874static PyObject *
875portable_lseek(int fd, PyObject *posobj, int whence)
876{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000877 Py_off_t pos, res;
Guido van Rossum53807da2007-04-10 19:01:47 +0000878
879#ifdef SEEK_SET
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000880 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
881 switch (whence) {
Guido van Rossum53807da2007-04-10 19:01:47 +0000882#if SEEK_SET != 0
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000883 case 0: whence = SEEK_SET; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000884#endif
885#if SEEK_CUR != 1
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000886 case 1: whence = SEEK_CUR; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000887#endif
Antoine Pitrou4f7945f2009-01-20 11:42:11 +0000888#if SEEK_END != 2
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000889 case 2: whence = SEEK_END; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000890#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000891 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000892#endif /* SEEK_SET */
893
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000894 if (posobj == NULL)
895 pos = 0;
896 else {
897 if(PyFloat_Check(posobj)) {
898 PyErr_SetString(PyExc_TypeError, "an integer is required");
899 return NULL;
900 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000901#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000902 pos = PyLong_AsLongLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000903#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000904 pos = PyLong_AsLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000905#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000906 if (PyErr_Occurred())
907 return NULL;
908 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000909
Steve Dower940f33a2016-09-08 11:21:54 -0700910 Py_BEGIN_ALLOW_THREADS
911 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200912#ifdef MS_WINDOWS
Steve Dower940f33a2016-09-08 11:21:54 -0700913 res = _lseeki64(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000914#else
Steve Dower940f33a2016-09-08 11:21:54 -0700915 res = lseek(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000916#endif
Steve Dower940f33a2016-09-08 11:21:54 -0700917 _Py_END_SUPPRESS_IPH
918 Py_END_ALLOW_THREADS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000919 if (res < 0)
920 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum53807da2007-04-10 19:01:47 +0000921
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000922#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000923 return PyLong_FromLongLong(res);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000924#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000925 return PyLong_FromLong(res);
Guido van Rossum53807da2007-04-10 19:01:47 +0000926#endif
927}
928
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300929/*[clinic input]
930_io.FileIO.seek
931 pos: object
932 whence: int = 0
933 /
Guido van Rossuma9e20242007-03-08 00:43:48 +0000934
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300935Move to new file position and return the file position.
936
937Argument offset is a byte count. Optional argument whence defaults to
938SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
939are SEEK_CUR or 1 (move relative to current position, positive or negative),
940and SEEK_END or 2 (move relative to end of file, usually negative, although
941many platforms allow seeking beyond the end of a file).
942
943Note that not all file objects are seekable.
944[clinic start generated code]*/
945
946static PyObject *
947_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
948/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/
949{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000950 if (self->fd < 0)
951 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000952
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300953 return portable_lseek(self->fd, pos, whence);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000954}
955
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300956/*[clinic input]
957_io.FileIO.tell
958
959Current file position.
960
961Can raise OSError for non seekable files.
962[clinic start generated code]*/
963
Guido van Rossuma9e20242007-03-08 00:43:48 +0000964static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300965_io_FileIO_tell_impl(fileio *self)
966/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000967{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000968 if (self->fd < 0)
969 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000970
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000971 return portable_lseek(self->fd, NULL, 1);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000972}
973
Thomas Hellerc6a55ee2007-07-11 12:45:46 +0000974#ifdef HAVE_FTRUNCATE
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300975/*[clinic input]
976_io.FileIO.truncate
977 size as posobj: object = NULL
978 /
979
980Truncate the file to at most size bytes and return the truncated size.
981
982Size defaults to the current file position, as returned by tell().
983The current file position is changed to the value of size.
984[clinic start generated code]*/
985
Guido van Rossuma9e20242007-03-08 00:43:48 +0000986static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300987_io_FileIO_truncate_impl(fileio *self, PyObject *posobj)
988/*[clinic end generated code: output=e49ca7a916c176fa input=9026af44686b7318]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000989{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000990 Py_off_t pos;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000991 int ret;
992 int fd;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000993
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000994 fd = self->fd;
995 if (fd < 0)
996 return err_closed();
997 if (!self->writable)
998 return err_mode("writing");
Guido van Rossuma9e20242007-03-08 00:43:48 +0000999
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001000 if (posobj == Py_None || posobj == NULL) {
1001 /* Get the current position. */
1002 posobj = portable_lseek(fd, NULL, 1);
1003 if (posobj == NULL)
1004 return NULL;
1005 }
1006 else {
1007 Py_INCREF(posobj);
1008 }
Guido van Rossum53807da2007-04-10 19:01:47 +00001009
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001010#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001011 pos = PyLong_AsLongLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001012#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001013 pos = PyLong_AsLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001014#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001015 if (PyErr_Occurred()){
1016 Py_DECREF(posobj);
1017 return NULL;
1018 }
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001019
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001020 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04001021 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001022 errno = 0;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001023#ifdef MS_WINDOWS
1024 ret = _chsize_s(fd, pos);
1025#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001026 ret = ftruncate(fd, pos);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001027#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04001028 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001029 Py_END_ALLOW_THREADS
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001030
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001031 if (ret != 0) {
1032 Py_DECREF(posobj);
1033 PyErr_SetFromErrno(PyExc_IOError);
1034 return NULL;
1035 }
Guido van Rossuma9e20242007-03-08 00:43:48 +00001036
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001037 return posobj;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001038}
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001039#endif /* HAVE_FTRUNCATE */
Guido van Rossum53807da2007-04-10 19:01:47 +00001040
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001041static const char *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001042mode_string(fileio *self)
Guido van Rossum53807da2007-04-10 19:01:47 +00001043{
Charles-François Natalidc3044c2012-01-09 22:40:02 +01001044 if (self->created) {
1045 if (self->readable)
1046 return "xb+";
1047 else
1048 return "xb";
1049 }
Antoine Pitroue93b63b2013-09-04 20:46:33 +02001050 if (self->appending) {
1051 if (self->readable)
1052 return "ab+";
1053 else
1054 return "ab";
1055 }
1056 else if (self->readable) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001057 if (self->writable)
1058 return "rb+";
1059 else
1060 return "rb";
1061 }
1062 else
1063 return "wb";
Guido van Rossum53807da2007-04-10 19:01:47 +00001064}
Guido van Rossuma9e20242007-03-08 00:43:48 +00001065
1066static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001067fileio_repr(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +00001068{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001069 PyObject *nameobj, *res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001070
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001071 if (self->fd < 0)
1072 return PyUnicode_FromFormat("<_io.FileIO [closed]>");
Antoine Pitrou716c4442009-05-23 19:04:03 +00001073
Martin v. Löwis767046a2011-10-14 15:35:36 +02001074 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001075 if (nameobj == NULL) {
1076 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1077 PyErr_Clear();
1078 else
1079 return NULL;
Robert Collins933430a2014-10-18 13:32:43 +13001080 res = PyUnicode_FromFormat(
Serhiy Storchaka4954f9f2014-12-02 23:39:56 +02001081 "<_io.FileIO fd=%d mode='%s' closefd=%s>",
1082 self->fd, mode_string(self), self->closefd ? "True" : "False");
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001083 }
1084 else {
Robert Collins933430a2014-10-18 13:32:43 +13001085 res = PyUnicode_FromFormat(
Serhiy Storchaka4954f9f2014-12-02 23:39:56 +02001086 "<_io.FileIO name=%R mode='%s' closefd=%s>",
1087 nameobj, mode_string(self), self->closefd ? "True" : "False");
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001088 Py_DECREF(nameobj);
1089 }
1090 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001091}
1092
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001093/*[clinic input]
1094_io.FileIO.isatty
1095
1096True if the file is connected to a TTY device.
1097[clinic start generated code]*/
1098
Guido van Rossuma9e20242007-03-08 00:43:48 +00001099static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001100_io_FileIO_isatty_impl(fileio *self)
1101/*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +00001102{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001103 long res;
Guido van Rossum53807da2007-04-10 19:01:47 +00001104
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001105 if (self->fd < 0)
1106 return err_closed();
1107 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001108 _Py_BEGIN_SUPPRESS_IPH
Steve Dower940f33a2016-09-08 11:21:54 -07001109 res = isatty(self->fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001110 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001111 Py_END_ALLOW_THREADS
1112 return PyBool_FromLong(res);
Guido van Rossuma9e20242007-03-08 00:43:48 +00001113}
1114
Antoine Pitrou243757e2010-11-05 21:15:39 +00001115static PyObject *
1116fileio_getstate(fileio *self)
1117{
1118 PyErr_Format(PyExc_TypeError,
1119 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
1120 return NULL;
1121}
1122
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001123#include "clinic/fileio.c.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +00001124
1125static PyMethodDef fileio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001126 _IO_FILEIO_READ_METHODDEF
1127 _IO_FILEIO_READALL_METHODDEF
1128 _IO_FILEIO_READINTO_METHODDEF
1129 _IO_FILEIO_WRITE_METHODDEF
1130 _IO_FILEIO_SEEK_METHODDEF
1131 _IO_FILEIO_TELL_METHODDEF
1132 _IO_FILEIO_TRUNCATE_METHODDEF
1133 _IO_FILEIO_CLOSE_METHODDEF
1134 _IO_FILEIO_SEEKABLE_METHODDEF
1135 _IO_FILEIO_READABLE_METHODDEF
1136 _IO_FILEIO_WRITABLE_METHODDEF
1137 _IO_FILEIO_FILENO_METHODDEF
1138 _IO_FILEIO_ISATTY_METHODDEF
Antoine Pitroue033e062010-10-29 10:38:18 +00001139 {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001140 {"__getstate__", (PyCFunction)fileio_getstate, METH_NOARGS, NULL},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001141 {NULL, NULL} /* sentinel */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001142};
1143
Guido van Rossum53807da2007-04-10 19:01:47 +00001144/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */
1145
Guido van Rossumb0428152007-04-08 17:44:42 +00001146static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001147get_closed(fileio *self, void *closure)
Guido van Rossumb0428152007-04-08 17:44:42 +00001148{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001149 return PyBool_FromLong((long)(self->fd < 0));
Guido van Rossum53807da2007-04-10 19:01:47 +00001150}
1151
1152static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001153get_closefd(fileio *self, void *closure)
Christian Heimesecc42a22008-11-05 19:30:32 +00001154{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001155 return PyBool_FromLong((long)(self->closefd));
Christian Heimesecc42a22008-11-05 19:30:32 +00001156}
1157
1158static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001159get_mode(fileio *self, void *closure)
Guido van Rossum53807da2007-04-10 19:01:47 +00001160{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001161 return PyUnicode_FromString(mode_string(self));
Guido van Rossumb0428152007-04-08 17:44:42 +00001162}
1163
1164static PyGetSetDef fileio_getsetlist[] = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001165 {"closed", (getter)get_closed, NULL, "True if the file is closed"},
1166 {"closefd", (getter)get_closefd, NULL,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +03001167 "True if the file descriptor will be closed by close()."},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001168 {"mode", (getter)get_mode, NULL, "String giving the file mode"},
1169 {NULL},
Guido van Rossumb0428152007-04-08 17:44:42 +00001170};
1171
Antoine Pitrou796564c2013-07-30 19:59:21 +02001172static PyMemberDef fileio_members[] = {
Antoine Pitroude687222014-06-29 20:07:28 -04001173 {"_blksize", T_UINT, offsetof(fileio, blksize), 0},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001174 {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
1175 {NULL}
1176};
1177
Guido van Rossuma9e20242007-03-08 00:43:48 +00001178PyTypeObject PyFileIO_Type = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001179 PyVarObject_HEAD_INIT(NULL, 0)
1180 "_io.FileIO",
1181 sizeof(fileio),
1182 0,
1183 (destructor)fileio_dealloc, /* tp_dealloc */
1184 0, /* tp_print */
1185 0, /* tp_getattr */
1186 0, /* tp_setattr */
1187 0, /* tp_reserved */
1188 (reprfunc)fileio_repr, /* tp_repr */
1189 0, /* tp_as_number */
1190 0, /* tp_as_sequence */
1191 0, /* tp_as_mapping */
1192 0, /* tp_hash */
1193 0, /* tp_call */
1194 0, /* tp_str */
1195 PyObject_GenericGetAttr, /* tp_getattro */
1196 0, /* tp_setattro */
1197 0, /* tp_as_buffer */
1198 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001199 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001200 _io_FileIO___init____doc__, /* tp_doc */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001201 (traverseproc)fileio_traverse, /* tp_traverse */
1202 (inquiry)fileio_clear, /* tp_clear */
1203 0, /* tp_richcompare */
1204 offsetof(fileio, weakreflist), /* tp_weaklistoffset */
1205 0, /* tp_iter */
1206 0, /* tp_iternext */
1207 fileio_methods, /* tp_methods */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001208 fileio_members, /* tp_members */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001209 fileio_getsetlist, /* tp_getset */
1210 0, /* tp_base */
1211 0, /* tp_dict */
1212 0, /* tp_descr_get */
1213 0, /* tp_descr_set */
1214 offsetof(fileio, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001215 _io_FileIO___init__, /* tp_init */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001216 PyType_GenericAlloc, /* tp_alloc */
1217 fileio_new, /* tp_new */
1218 PyObject_GC_Del, /* tp_free */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001219 0, /* tp_is_gc */
1220 0, /* tp_bases */
1221 0, /* tp_mro */
1222 0, /* tp_cache */
1223 0, /* tp_subclasses */
1224 0, /* tp_weaklist */
1225 0, /* tp_del */
1226 0, /* tp_version_tag */
1227 0, /* tp_finalize */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001228};