blob: c502c430134ef6ccbd2aae9b4247ca4dca469448 [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"
Victor Stinnerbcda8f12018-11-21 22:27:47 +01005#include "pycore_object.h"
Antoine Pitroue033e062010-10-29 10:38:18 +00006#include "structmember.h"
Benjamin Peterson2614cda2010-03-21 22:36:19 +00007#ifdef HAVE_SYS_TYPES_H
Guido van Rossuma9e20242007-03-08 00:43:48 +00008#include <sys/types.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +00009#endif
10#ifdef HAVE_SYS_STAT_H
Guido van Rossuma9e20242007-03-08 00:43:48 +000011#include <sys/stat.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +000012#endif
Steve Dowerbfce0f92016-12-28 15:41:09 -080013#ifdef HAVE_IO_H
14#include <io.h>
15#endif
Benjamin Peterson2614cda2010-03-21 22:36:19 +000016#ifdef HAVE_FCNTL_H
Guido van Rossuma9e20242007-03-08 00:43:48 +000017#include <fcntl.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +000018#endif
Guido van Rossuma9e20242007-03-08 00:43:48 +000019#include <stddef.h> /* For offsetof */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000020#include "_iomodule.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +000021
22/*
23 * Known likely problems:
24 *
25 * - Files larger then 2**32-1
26 * - Files with unicode filenames
27 * - Passing numbers greater than 2**32-1 when an integer is expected
28 * - Making it work on Windows and other oddball platforms
29 *
30 * To Do:
31 *
32 * - autoconfify header file inclusion
Guido van Rossuma9e20242007-03-08 00:43:48 +000033 */
34
35#ifdef MS_WINDOWS
36/* can simulate truncate with Win32 API functions; see file_truncate */
Thomas Hellerfdeee3a2007-07-12 11:21:36 +000037#define HAVE_FTRUNCATE
Guido van Rossuma9e20242007-03-08 00:43:48 +000038#define WIN32_LEAN_AND_MEAN
39#include <windows.h>
40#endif
41
Christian Heimesa872de52008-12-05 08:26:55 +000042#if BUFSIZ < (8*1024)
43#define SMALLCHUNK (8*1024)
44#elif (BUFSIZ >= (2 << 25))
Victor Stinner8c663fd2017-11-08 14:44:44 -080045#error "unreasonable BUFSIZ > 64 MiB defined"
Christian Heimesa872de52008-12-05 08:26:55 +000046#else
47#define SMALLCHUNK BUFSIZ
48#endif
49
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030050/*[clinic input]
51module _io
52class _io.FileIO "fileio *" "&PyFileIO_Type"
53[clinic start generated code]*/
54/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/
55
Guido van Rossuma9e20242007-03-08 00:43:48 +000056typedef struct {
Antoine Pitrouae4b4722010-05-05 16:31:07 +000057 PyObject_HEAD
58 int fd;
Charles-François Natalidc3044c2012-01-09 22:40:02 +010059 unsigned int created : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000060 unsigned int readable : 1;
61 unsigned int writable : 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +020062 unsigned int appending : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000063 signed int seekable : 2; /* -1 means unknown */
64 unsigned int closefd : 1;
Antoine Pitrou796564c2013-07-30 19:59:21 +020065 char finalizing;
Antoine Pitroude687222014-06-29 20:07:28 -040066 unsigned int blksize;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000067 PyObject *weakreflist;
68 PyObject *dict;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000069} fileio;
Guido van Rossuma9e20242007-03-08 00:43:48 +000070
Collin Winteraf334382007-03-08 21:46:15 +000071PyTypeObject PyFileIO_Type;
72
Victor Stinnerd9d04192013-11-06 23:50:10 +010073_Py_IDENTIFIER(name);
74
Guido van Rossuma9e20242007-03-08 00:43:48 +000075#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
76
Victor Stinner99970732017-05-02 15:10:39 +020077/* Forward declarations */
78static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence);
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
Kristján Valur Jónsson19288c22008-12-18 17:15:54 +0000105/* Returns 0 on success, -1 with exception set on failure. */
Neal Norwitz88b44da2007-08-12 17:23:54 +0000106static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000107internal_close(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000108{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000109 int err = 0;
110 int save_errno = 0;
111 if (self->fd >= 0) {
112 int fd = self->fd;
113 self->fd = -1;
114 /* fd is accessible and someone else may have closed it */
Steve Dower940f33a2016-09-08 11:21:54 -0700115 Py_BEGIN_ALLOW_THREADS
116 _Py_BEGIN_SUPPRESS_IPH
117 err = close(fd);
118 if (err < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000119 save_errno = errno;
Steve Dower940f33a2016-09-08 11:21:54 -0700120 _Py_END_SUPPRESS_IPH
121 Py_END_ALLOW_THREADS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000122 }
123 if (err < 0) {
124 errno = save_errno;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300125 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000126 return -1;
127 }
128 return 0;
Neal Norwitz88b44da2007-08-12 17:23:54 +0000129}
130
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300131/*[clinic input]
132_io.FileIO.close
133
134Close the file.
135
136A closed file cannot be used for further I/O operations. close() may be
137called more than once without error.
138[clinic start generated code]*/
139
Neal Norwitz88b44da2007-08-12 17:23:54 +0000140static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300141_io_FileIO_close_impl(fileio *self)
142/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/
Neal Norwitz88b44da2007-08-12 17:23:54 +0000143{
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200144 PyObject *res;
145 PyObject *exc, *val, *tb;
146 int rc;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200147 _Py_IDENTIFIER(close);
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100148 res = _PyObject_CallMethodIdObjArgs((PyObject*)&PyRawIOBase_Type,
149 &PyId_close, self, NULL);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000150 if (!self->closefd) {
151 self->fd = -1;
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200152 return res;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000153 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200154 if (res == NULL)
155 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou796564c2013-07-30 19:59:21 +0200156 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000157 PyObject *r = fileio_dealloc_warn(self, (PyObject *) self);
158 if (r)
159 Py_DECREF(r);
160 else
161 PyErr_Clear();
162 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200163 rc = internal_close(self);
164 if (res == NULL)
165 _PyErr_ChainExceptions(exc, val, tb);
166 if (rc < 0)
167 Py_CLEAR(res);
168 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000169}
170
171static PyObject *
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000172fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000173{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000174 fileio *self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000175
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000176 assert(type != NULL && type->tp_alloc != NULL);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000177
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000178 self = (fileio *) type->tp_alloc(type, 0);
179 if (self != NULL) {
180 self->fd = -1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100181 self->created = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000182 self->readable = 0;
183 self->writable = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200184 self->appending = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000185 self->seekable = -1;
Antoine Pitroude687222014-06-29 20:07:28 -0400186 self->blksize = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000187 self->closefd = 1;
188 self->weakreflist = NULL;
189 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000190
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000191 return (PyObject *) self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000192}
193
Victor Stinnerdaf45552013-08-28 00:53:59 +0200194#ifdef O_CLOEXEC
195extern int _Py_open_cloexec_works;
196#endif
Guido van Rossuma9e20242007-03-08 00:43:48 +0000197
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300198/*[clinic input]
199_io.FileIO.__init__
200 file as nameobj: object
201 mode: str = "r"
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200202 closefd: bool(accept={int}) = True
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300203 opener: object = None
204
205Open a file.
206
207The mode can be 'r' (default), 'w', 'x' or 'a' for reading,
208writing, exclusive creation or appending. The file will be created if it
209doesn't exist when opened for writing or appending; it will be truncated
210when opened for writing. A FileExistsError will be raised if it already
211exists when opened for creating. Opening a file for creating implies
212writing so this mode behaves in a similar way to 'w'.Add a '+' to the mode
213to allow simultaneous reading and writing. A custom opener can be used by
214passing a callable as *opener*. The underlying file descriptor for the file
215object is then obtained by calling opener with (*name*, *flags*).
216*opener* must return an open file descriptor (passing os.open as *opener*
217results in functionality similar to passing None).
218[clinic start generated code]*/
219
Guido van Rossuma9e20242007-03-08 00:43:48 +0000220static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300221_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
222 int closefd, PyObject *opener)
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200223/*[clinic end generated code: output=23413f68e6484bbd input=1596c9157a042a39]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000224{
Thomas Helleraf2be262007-07-12 11:03:13 +0000225#ifdef MS_WINDOWS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000226 Py_UNICODE *widename = NULL;
Steve Dowereacee982017-02-04 14:38:11 -0800227#else
228 const char *name = NULL;
Thomas Helleraf2be262007-07-12 11:03:13 +0000229#endif
Steve Dowereacee982017-02-04 14:38:11 -0800230 PyObject *stringobj = NULL;
231 const char *s;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000232 int ret = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200233 int rwa = 0, plus = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000234 int flags = 0;
235 int fd = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200236 int fd_is_own = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200237#ifdef O_CLOEXEC
238 int *atomic_flag_works = &_Py_open_cloexec_works;
239#elif !defined(MS_WINDOWS)
240 int *atomic_flag_works = NULL;
241#endif
Steve Dowerf2f373f2015-02-21 08:44:05 -0800242 struct _Py_stat_struct fdfstat;
Martin Panter0bb62b12015-12-06 03:15:05 +0000243 int fstat_result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000244 int async_err = 0;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000245
Christian Heimes82adeff2015-04-16 17:21:54 +0200246 assert(PyFileIO_Check(self));
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000247 if (self->fd >= 0) {
Hynek Schlawack2cc71562012-05-25 10:05:53 +0200248 if (self->closefd) {
249 /* Have to close the existing file first. */
250 if (internal_close(self) < 0)
251 return -1;
252 }
253 else
254 self->fd = -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000255 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000256
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000257 if (PyFloat_Check(nameobj)) {
258 PyErr_SetString(PyExc_TypeError,
259 "integer argument expected, got float");
260 return -1;
261 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000262
Serhiy Storchaka78980432013-01-15 01:12:17 +0200263 fd = _PyLong_AsInt(nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000264 if (fd < 0) {
265 if (!PyErr_Occurred()) {
266 PyErr_SetString(PyExc_ValueError,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +0300267 "negative file descriptor");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000268 return -1;
269 }
270 PyErr_Clear();
271 }
Guido van Rossumb0428152007-04-08 17:44:42 +0000272
Steve Dowereacee982017-02-04 14:38:11 -0800273 if (fd < 0) {
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000274#ifdef MS_WINDOWS
Steve Dowereacee982017-02-04 14:38:11 -0800275 if (!PyUnicode_FSDecoder(nameobj, &stringobj)) {
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300276 return -1;
277 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300278 widename = PyUnicode_AsUnicode(stringobj);
Steve Dowereacee982017-02-04 14:38:11 -0800279 if (widename == NULL)
280 return -1;
281#else
Antoine Pitrou13348842012-01-29 18:36:34 +0100282 if (!PyUnicode_FSConverter(nameobj, &stringobj)) {
283 return -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000284 }
Antoine Pitrou13348842012-01-29 18:36:34 +0100285 name = PyBytes_AS_STRING(stringobj);
Steve Dowereacee982017-02-04 14:38:11 -0800286#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000287 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000288
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000289 s = mode;
290 while (*s) {
291 switch (*s++) {
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100292 case 'x':
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000293 if (rwa) {
294 bad_mode:
295 PyErr_SetString(PyExc_ValueError,
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100296 "Must have exactly one of create/read/write/append "
Georg Brandl28928ae2010-10-21 13:45:52 +0000297 "mode and at most one plus");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000298 goto error;
299 }
300 rwa = 1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100301 self->created = 1;
302 self->writable = 1;
303 flags |= O_EXCL | O_CREAT;
304 break;
305 case 'r':
306 if (rwa)
307 goto bad_mode;
308 rwa = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000309 self->readable = 1;
310 break;
311 case 'w':
312 if (rwa)
313 goto bad_mode;
314 rwa = 1;
315 self->writable = 1;
316 flags |= O_CREAT | O_TRUNC;
317 break;
318 case 'a':
319 if (rwa)
320 goto bad_mode;
321 rwa = 1;
322 self->writable = 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200323 self->appending = 1;
324 flags |= O_APPEND | O_CREAT;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000325 break;
326 case 'b':
327 break;
328 case '+':
329 if (plus)
330 goto bad_mode;
331 self->readable = self->writable = 1;
332 plus = 1;
333 break;
334 default:
335 PyErr_Format(PyExc_ValueError,
336 "invalid mode: %.200s", mode);
337 goto error;
338 }
339 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000340
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000341 if (!rwa)
342 goto bad_mode;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000343
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000344 if (self->readable && self->writable)
345 flags |= O_RDWR;
346 else if (self->readable)
347 flags |= O_RDONLY;
348 else
349 flags |= O_WRONLY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000350
351#ifdef O_BINARY
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000352 flags |= O_BINARY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000353#endif
354
Victor Stinnerdaf45552013-08-28 00:53:59 +0200355#ifdef MS_WINDOWS
356 flags |= O_NOINHERIT;
357#elif defined(O_CLOEXEC)
358 flags |= O_CLOEXEC;
359#endif
Walter Dörwald0e411482007-06-06 16:55:38 +0000360
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000361 if (fd >= 0) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000362 self->fd = fd;
363 self->closefd = closefd;
364 }
365 else {
366 self->closefd = 1;
367 if (!closefd) {
368 PyErr_SetString(PyExc_ValueError,
369 "Cannot use closefd=False with file name");
370 goto error;
371 }
Guido van Rossum2dced8b2007-10-30 17:27:30 +0000372
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000373 errno = 0;
Ross Lagerwall59142db2011-10-31 20:34:46 +0200374 if (opener == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000375 do {
376 Py_BEGIN_ALLOW_THREADS
Thomas Helleraf2be262007-07-12 11:03:13 +0000377#ifdef MS_WINDOWS
Steve Dowereacee982017-02-04 14:38:11 -0800378 self->fd = _wopen(widename, flags, 0666);
379#else
380 self->fd = open(name, flags, 0666);
Thomas Helleraf2be262007-07-12 11:03:13 +0000381#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000382 Py_END_ALLOW_THREADS
383 } while (self->fd < 0 && errno == EINTR &&
384 !(async_err = PyErr_CheckSignals()));
Victor Stinner9672da72015-03-04 18:40:10 +0100385
386 if (async_err)
387 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200388 }
389 else {
390 PyObject *fdobj;
391
392#ifndef MS_WINDOWS
393 /* the opener may clear the atomic flag */
394 atomic_flag_works = NULL;
395#endif
396
397 fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200398 if (fdobj == NULL)
399 goto error;
400 if (!PyLong_Check(fdobj)) {
401 Py_DECREF(fdobj);
402 PyErr_SetString(PyExc_TypeError,
403 "expected integer from opener");
404 goto error;
405 }
406
Serhiy Storchaka78980432013-01-15 01:12:17 +0200407 self->fd = _PyLong_AsInt(fdobj);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200408 Py_DECREF(fdobj);
Barry Warsaw480e2852016-06-08 17:47:26 -0400409 if (self->fd < 0) {
410 if (!PyErr_Occurred()) {
Barry Warsaw118598a2016-06-08 17:54:43 -0400411 /* The opener returned a negative but didn't set an
412 exception. See issue #27066 */
Barry Warsaw480e2852016-06-08 17:47:26 -0400413 PyErr_Format(PyExc_ValueError,
414 "opener returned %d", self->fd);
415 }
Ross Lagerwall59142db2011-10-31 20:34:46 +0200416 goto error;
417 }
418 }
419
Hynek Schlawack7f59fd72012-06-22 09:32:22 +0200420 fd_is_own = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000421 if (self->fd < 0) {
Victor Stinner9672da72015-03-04 18:40:10 +0100422 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000423 goto error;
424 }
Victor Stinnerdaf45552013-08-28 00:53:59 +0200425
426#ifndef MS_WINDOWS
427 if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0)
428 goto error;
429#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000430 }
Antoine Pitroude687222014-06-29 20:07:28 -0400431
432 self->blksize = DEFAULT_BUFFER_SIZE;
Martin Panter0bb62b12015-12-06 03:15:05 +0000433 Py_BEGIN_ALLOW_THREADS
434 fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
435 Py_END_ALLOW_THREADS
436 if (fstat_result < 0) {
Martin Panter49d3db92015-12-06 11:12:15 +0000437 /* Tolerate fstat() errors other than EBADF. See Issue #25717, where
438 an anonymous file on a Virtual Box shared folder filesystem would
439 raise ENOENT. */
Martin Panter0bb62b12015-12-06 03:15:05 +0000440#ifdef MS_WINDOWS
441 if (GetLastError() == ERROR_INVALID_HANDLE) {
442 PyErr_SetFromWindowsErr(0);
443#else
444 if (errno == EBADF) {
445 PyErr_SetFromErrno(PyExc_OSError);
446#endif
447 goto error;
448 }
Antoine Pitroude687222014-06-29 20:07:28 -0400449 }
Martin Panter0bb62b12015-12-06 03:15:05 +0000450 else {
451#if defined(S_ISDIR) && defined(EISDIR)
452 /* On Unix, open will succeed for directories.
453 In Python, there should be no file objects referring to
454 directories, so we need a check. */
455 if (S_ISDIR(fdfstat.st_mode)) {
456 errno = EISDIR;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300457 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Martin Panter0bb62b12015-12-06 03:15:05 +0000458 goto error;
459 }
Antoine Pitroude687222014-06-29 20:07:28 -0400460#endif /* defined(S_ISDIR) */
461#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin Panter0bb62b12015-12-06 03:15:05 +0000462 if (fdfstat.st_blksize > 1)
463 self->blksize = fdfstat.st_blksize;
Antoine Pitroude687222014-06-29 20:07:28 -0400464#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
Martin Panter0bb62b12015-12-06 03:15:05 +0000465 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000466
Victor Stinner89e34362011-01-07 18:47:22 +0000467#if defined(MS_WINDOWS) || defined(__CYGWIN__)
468 /* don't translate newlines (\r\n <=> \n) */
469 _setmode(self->fd, O_BINARY);
470#endif
471
Victor Stinnerd9d04192013-11-06 23:50:10 +0100472 if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000473 goto error;
Antoine Pitrou08838b62009-01-21 00:55:13 +0000474
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200475 if (self->appending) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000476 /* For consistent behaviour, we explicitly seek to the
477 end of file (otherwise, it might be done only on the
478 first write()). */
Victor Stinner99970732017-05-02 15:10:39 +0200479 PyObject *pos = portable_lseek(self, NULL, 2);
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200480 if (pos == NULL)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000481 goto error;
482 Py_DECREF(pos);
483 }
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000484
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000485 goto done;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000486
487 error:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000488 ret = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200489 if (!fd_is_own)
490 self->fd = -1;
Benjamin Petersonbbb04122010-10-30 23:16:28 +0000491 if (self->fd >= 0)
492 internal_close(self);
Guido van Rossum53807da2007-04-10 19:01:47 +0000493
Guido van Rossuma9e20242007-03-08 00:43:48 +0000494 done:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000495 Py_CLEAR(stringobj);
496 return ret;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000497}
498
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000499static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000500fileio_traverse(fileio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000501{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000502 Py_VISIT(self->dict);
503 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000504}
505
506static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000507fileio_clear(fileio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000508{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000509 Py_CLEAR(self->dict);
510 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000511}
512
Guido van Rossuma9e20242007-03-08 00:43:48 +0000513static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000514fileio_dealloc(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000515{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200516 self->finalizing = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000517 if (_PyIOBase_finalize((PyObject *) self) < 0)
518 return;
519 _PyObject_GC_UNTRACK(self);
520 if (self->weakreflist != NULL)
521 PyObject_ClearWeakRefs((PyObject *) self);
522 Py_CLEAR(self->dict);
523 Py_TYPE(self)->tp_free((PyObject *)self);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000524}
525
526static PyObject *
527err_closed(void)
528{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000529 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
530 return NULL;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000531}
532
533static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200534err_mode(const char *action)
Guido van Rossum53807da2007-04-10 19:01:47 +0000535{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100536 _PyIO_State *state = IO_STATE();
537 if (state != NULL)
538 PyErr_Format(state->unsupported_operation,
539 "File not open for %s", action);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000540 return NULL;
Guido van Rossum53807da2007-04-10 19:01:47 +0000541}
542
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300543/*[clinic input]
544_io.FileIO.fileno
545
546Return the underlying file descriptor (an integer).
547[clinic start generated code]*/
548
Guido van Rossum53807da2007-04-10 19:01:47 +0000549static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300550_io_FileIO_fileno_impl(fileio *self)
551/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000552{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000553 if (self->fd < 0)
554 return err_closed();
555 return PyLong_FromLong((long) self->fd);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000556}
557
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300558/*[clinic input]
559_io.FileIO.readable
560
561True if file was opened in a read mode.
562[clinic start generated code]*/
563
Guido van Rossuma9e20242007-03-08 00:43:48 +0000564static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300565_io_FileIO_readable_impl(fileio *self)
566/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000567{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000568 if (self->fd < 0)
569 return err_closed();
570 return PyBool_FromLong((long) self->readable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000571}
572
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300573/*[clinic input]
574_io.FileIO.writable
575
576True if file was opened in a write mode.
577[clinic start generated code]*/
578
Guido van Rossuma9e20242007-03-08 00:43:48 +0000579static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300580_io_FileIO_writable_impl(fileio *self)
581/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000582{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000583 if (self->fd < 0)
584 return err_closed();
585 return PyBool_FromLong((long) self->writable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000586}
587
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300588/*[clinic input]
589_io.FileIO.seekable
590
591True if file supports random-access.
592[clinic start generated code]*/
593
Guido van Rossuma9e20242007-03-08 00:43:48 +0000594static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300595_io_FileIO_seekable_impl(fileio *self)
596/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000597{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000598 if (self->fd < 0)
599 return err_closed();
600 if (self->seekable < 0) {
Victor Stinner99970732017-05-02 15:10:39 +0200601 /* portable_lseek() sets the seekable attribute */
602 PyObject *pos = portable_lseek(self, NULL, SEEK_CUR);
603 assert(self->seekable >= 0);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000604 if (pos == NULL) {
605 PyErr_Clear();
Victor Stinner99970732017-05-02 15:10:39 +0200606 }
607 else {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000608 Py_DECREF(pos);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000609 }
610 }
611 return PyBool_FromLong((long) self->seekable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000612}
613
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300614/*[clinic input]
615_io.FileIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700616 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300617 /
618
619Same as RawIOBase.readinto().
620[clinic start generated code]*/
621
Guido van Rossuma9e20242007-03-08 00:43:48 +0000622static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300623_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700624/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000625{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100626 Py_ssize_t n;
627 int err;
Guido van Rossum53807da2007-04-10 19:01:47 +0000628
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000629 if (self->fd < 0)
630 return err_closed();
631 if (!self->readable)
632 return err_mode("reading");
Guido van Rossum53807da2007-04-10 19:01:47 +0000633
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300634 n = _Py_read(self->fd, buffer->buf, buffer->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100635 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100636 err = errno;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100637
638 if (n == -1) {
639 if (err == EAGAIN) {
640 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000641 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100642 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000643 return NULL;
644 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000645
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000646 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000647}
648
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000649static size_t
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100650new_buffersize(fileio *self, size_t currentsize)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651{
Antoine Pitroua3f44572012-04-17 13:50:58 +0200652 size_t addend;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100653
Nadeem Vawdad41a98b2011-10-13 13:34:16 +0200654 /* Expand the buffer by an amount proportional to the current size,
Antoine Pitroua3f44572012-04-17 13:50:58 +0200655 giving us amortized linear-time behavior. For bigger sizes, use a
656 less-than-double growth factor to avoid excessive allocation. */
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100657 assert(currentsize <= PY_SSIZE_T_MAX);
Antoine Pitroua3f44572012-04-17 13:50:58 +0200658 if (currentsize > 65536)
659 addend = currentsize >> 3;
660 else
661 addend = 256 + currentsize;
662 if (addend < SMALLCHUNK)
663 /* Avoid tiny read() calls. */
664 addend = SMALLCHUNK;
665 return addend + currentsize;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000666}
667
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300668/*[clinic input]
669_io.FileIO.readall
670
671Read all data from the file, returned as bytes.
672
673In non-blocking mode, returns as much as is immediately available,
674or None if no data is available. Return an empty bytes object at EOF.
675[clinic start generated code]*/
676
Guido van Rossum7165cb12007-07-10 06:54:34 +0000677static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300678_io_FileIO_readall_impl(fileio *self)
679/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/
Guido van Rossum7165cb12007-07-10 06:54:34 +0000680{
Victor Stinnere134a7f2015-03-30 10:09:31 +0200681 struct _Py_stat_struct status;
Victor Stinnera2a64772011-10-11 22:45:02 +0200682 Py_off_t pos, end;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000683 PyObject *result;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100684 Py_ssize_t bytes_read = 0;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100685 Py_ssize_t n;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100686 size_t bufsize;
Nir Soffer6a894812017-12-01 03:18:58 +0200687 int fstat_result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000688
Victor Stinnerb79f28c2011-05-25 22:09:03 +0200689 if (self->fd < 0)
690 return err_closed();
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000691
Nir Soffer6a894812017-12-01 03:18:58 +0200692 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400693 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200694#ifdef MS_WINDOWS
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200695 pos = _lseeki64(self->fd, 0L, SEEK_CUR);
696#else
697 pos = lseek(self->fd, 0L, SEEK_CUR);
698#endif
Steve Dower8fc89802015-04-12 00:26:27 -0400699 _Py_END_SUPPRESS_IPH
Nir Soffer6a894812017-12-01 03:18:58 +0200700 fstat_result = _Py_fstat_noraise(self->fd, &status);
701 Py_END_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400702
Nir Soffer6a894812017-12-01 03:18:58 +0200703 if (fstat_result == 0)
Victor Stinnere134a7f2015-03-30 10:09:31 +0200704 end = status.st_size;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200705 else
Victor Stinnera2a64772011-10-11 22:45:02 +0200706 end = (Py_off_t)-1;
Christian Heimesa872de52008-12-05 08:26:55 +0000707
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100708 if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) {
709 /* This is probably a real file, so we try to allocate a
710 buffer one byte larger than the rest of the file. If the
711 calculation is right then we should get EOF without having
712 to enlarge the buffer. */
713 bufsize = (size_t)(end - pos + 1);
714 } else {
715 bufsize = SMALLCHUNK;
716 }
717
718 result = PyBytes_FromStringAndSize(NULL, bufsize);
719 if (result == NULL)
720 return NULL;
721
722 while (1) {
723 if (bytes_read >= (Py_ssize_t)bufsize) {
724 bufsize = new_buffersize(self, bytes_read);
725 if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) {
726 PyErr_SetString(PyExc_OverflowError,
727 "unbounded read returned more bytes "
Serhiy Storchakab817b772015-04-10 02:18:44 +0300728 "than a Python bytes object can hold");
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100729 Py_DECREF(result);
730 return NULL;
731 }
732
733 if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) {
734 if (_PyBytes_Resize(&result, bufsize) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000735 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000736 }
737 }
Victor Stinner9672da72015-03-04 18:40:10 +0100738
Victor Stinner66aab0c2015-03-19 22:53:20 +0100739 n = _Py_read(self->fd,
740 PyBytes_AS_STRING(result) + bytes_read,
741 bufsize - bytes_read);
Victor Stinner9672da72015-03-04 18:40:10 +0100742
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000743 if (n == 0)
744 break;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100745 if (n == -1) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000746 if (errno == EAGAIN) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100747 PyErr_Clear();
Victor Stinnere10920f2014-07-02 22:59:31 +0200748 if (bytes_read > 0)
749 break;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000750 Py_DECREF(result);
751 Py_RETURN_NONE;
752 }
753 Py_DECREF(result);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000754 return NULL;
755 }
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100756 bytes_read += n;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200757 pos += n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000758 }
Guido van Rossum7165cb12007-07-10 06:54:34 +0000759
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100760 if (PyBytes_GET_SIZE(result) > bytes_read) {
761 if (_PyBytes_Resize(&result, bytes_read) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000762 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000763 }
764 return result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000765}
766
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300767/*[clinic input]
768_io.FileIO.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300769 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300770 /
771
772Read at most size bytes, returned as bytes.
773
774Only makes one system call, so less data may be returned than requested.
775In non-blocking mode, returns None if no data is available.
776Return an empty bytes object at EOF.
777[clinic start generated code]*/
778
Guido van Rossuma9e20242007-03-08 00:43:48 +0000779static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300780_io_FileIO_read_impl(fileio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300781/*[clinic end generated code: output=42528d39dd0ca641 input=bec9a2c704ddcbc9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000782{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000783 char *ptr;
784 Py_ssize_t n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000785 PyObject *bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000786
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000787 if (self->fd < 0)
788 return err_closed();
789 if (!self->readable)
790 return err_mode("reading");
Guido van Rossuma9e20242007-03-08 00:43:48 +0000791
Victor Stinner66aab0c2015-03-19 22:53:20 +0100792 if (size < 0)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300793 return _io_FileIO_readall_impl(self);
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000794
Stéphane Wirtel74a8b6e2018-10-18 01:05:04 +0200795 if (size > _PY_READ_MAX) {
796 size = _PY_READ_MAX;
797 }
Victor Stinner66aab0c2015-03-19 22:53:20 +0100798
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000799 bytes = PyBytes_FromStringAndSize(NULL, size);
800 if (bytes == NULL)
801 return NULL;
802 ptr = PyBytes_AS_STRING(bytes);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000803
Victor Stinner66aab0c2015-03-19 22:53:20 +0100804 n = _Py_read(self->fd, ptr, size);
805 if (n == -1) {
806 /* copy errno because Py_DECREF() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100807 int err = errno;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000808 Py_DECREF(bytes);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100809 if (err == EAGAIN) {
810 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000811 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100812 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000813 return NULL;
814 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000815
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000816 if (n != size) {
817 if (_PyBytes_Resize(&bytes, n) < 0) {
Victor Stinner85c761d2013-07-16 21:36:02 +0200818 Py_CLEAR(bytes);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000819 return NULL;
820 }
821 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000822
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000823 return (PyObject *) bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000824}
825
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300826/*[clinic input]
827_io.FileIO.write
828 b: Py_buffer
829 /
830
Martin Panter6bb91f32016-05-28 00:41:57 +0000831Write buffer b to file, return number of bytes written.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300832
833Only makes one system call, so not all of the data may be written.
834The number of bytes actually written is returned. In non-blocking mode,
835returns None if the write would block.
836[clinic start generated code]*/
837
Guido van Rossuma9e20242007-03-08 00:43:48 +0000838static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300839_io_FileIO_write_impl(fileio *self, Py_buffer *b)
Martin Panter6bb91f32016-05-28 00:41:57 +0000840/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000841{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100842 Py_ssize_t n;
843 int err;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000844
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000845 if (self->fd < 0)
846 return err_closed();
847 if (!self->writable)
848 return err_mode("writing");
Guido van Rossum53807da2007-04-10 19:01:47 +0000849
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300850 n = _Py_write(self->fd, b->buf, b->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100851 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100852 err = errno;
Martin v. Löwis423be952008-08-13 15:53:07 +0000853
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000854 if (n < 0) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100855 if (err == EAGAIN) {
856 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000857 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100858 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000859 return NULL;
860 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000861
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000862 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000863}
864
Guido van Rossum53807da2007-04-10 19:01:47 +0000865/* XXX Windows support below is likely incomplete */
866
Guido van Rossum53807da2007-04-10 19:01:47 +0000867/* Cribbed from posix_lseek() */
868static PyObject *
Victor Stinner99970732017-05-02 15:10:39 +0200869portable_lseek(fileio *self, PyObject *posobj, int whence)
Guido van Rossum53807da2007-04-10 19:01:47 +0000870{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000871 Py_off_t pos, res;
Victor Stinner99970732017-05-02 15:10:39 +0200872 int fd = self->fd;
Guido van Rossum53807da2007-04-10 19:01:47 +0000873
874#ifdef SEEK_SET
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000875 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
876 switch (whence) {
Guido van Rossum53807da2007-04-10 19:01:47 +0000877#if SEEK_SET != 0
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000878 case 0: whence = SEEK_SET; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000879#endif
880#if SEEK_CUR != 1
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000881 case 1: whence = SEEK_CUR; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000882#endif
Antoine Pitrou4f7945f2009-01-20 11:42:11 +0000883#if SEEK_END != 2
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000884 case 2: whence = SEEK_END; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000885#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000886 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000887#endif /* SEEK_SET */
888
Victor Stinner99970732017-05-02 15:10:39 +0200889 if (posobj == NULL) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000890 pos = 0;
Victor Stinner99970732017-05-02 15:10:39 +0200891 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000892 else {
893 if(PyFloat_Check(posobj)) {
894 PyErr_SetString(PyExc_TypeError, "an integer is required");
895 return NULL;
896 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000897#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000898 pos = PyLong_AsLongLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000899#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000900 pos = PyLong_AsLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000901#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000902 if (PyErr_Occurred())
903 return NULL;
904 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000905
Steve Dower940f33a2016-09-08 11:21:54 -0700906 Py_BEGIN_ALLOW_THREADS
907 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200908#ifdef MS_WINDOWS
Steve Dower940f33a2016-09-08 11:21:54 -0700909 res = _lseeki64(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000910#else
Steve Dower940f33a2016-09-08 11:21:54 -0700911 res = lseek(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000912#endif
Steve Dower940f33a2016-09-08 11:21:54 -0700913 _Py_END_SUPPRESS_IPH
914 Py_END_ALLOW_THREADS
Victor Stinner99970732017-05-02 15:10:39 +0200915
916 if (self->seekable < 0) {
917 self->seekable = (res >= 0);
918 }
919
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000920 if (res < 0)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300921 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum53807da2007-04-10 19:01:47 +0000922
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000923#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000924 return PyLong_FromLongLong(res);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000925#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000926 return PyLong_FromLong(res);
Guido van Rossum53807da2007-04-10 19:01:47 +0000927#endif
928}
929
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300930/*[clinic input]
931_io.FileIO.seek
932 pos: object
933 whence: int = 0
934 /
Guido van Rossuma9e20242007-03-08 00:43:48 +0000935
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300936Move to new file position and return the file position.
937
938Argument offset is a byte count. Optional argument whence defaults to
939SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
940are SEEK_CUR or 1 (move relative to current position, positive or negative),
941and SEEK_END or 2 (move relative to end of file, usually negative, although
942many platforms allow seeking beyond the end of a file).
943
944Note that not all file objects are seekable.
945[clinic start generated code]*/
946
947static PyObject *
948_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
949/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/
950{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000951 if (self->fd < 0)
952 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000953
Victor Stinner99970732017-05-02 15:10:39 +0200954 return portable_lseek(self, pos, whence);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000955}
956
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300957/*[clinic input]
958_io.FileIO.tell
959
960Current file position.
961
962Can raise OSError for non seekable files.
963[clinic start generated code]*/
964
Guido van Rossuma9e20242007-03-08 00:43:48 +0000965static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300966_io_FileIO_tell_impl(fileio *self)
967/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000968{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000969 if (self->fd < 0)
970 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000971
Victor Stinner99970732017-05-02 15:10:39 +0200972 return portable_lseek(self, NULL, 1);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000973}
974
Thomas Hellerc6a55ee2007-07-11 12:45:46 +0000975#ifdef HAVE_FTRUNCATE
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300976/*[clinic input]
977_io.FileIO.truncate
978 size as posobj: object = NULL
979 /
980
981Truncate the file to at most size bytes and return the truncated size.
982
983Size defaults to the current file position, as returned by tell().
984The current file position is changed to the value of size.
985[clinic start generated code]*/
986
Guido van Rossuma9e20242007-03-08 00:43:48 +0000987static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300988_io_FileIO_truncate_impl(fileio *self, PyObject *posobj)
989/*[clinic end generated code: output=e49ca7a916c176fa input=9026af44686b7318]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000990{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000991 Py_off_t pos;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000992 int ret;
993 int fd;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000994
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000995 fd = self->fd;
996 if (fd < 0)
997 return err_closed();
998 if (!self->writable)
999 return err_mode("writing");
Guido van Rossuma9e20242007-03-08 00:43:48 +00001000
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001001 if (posobj == Py_None || posobj == NULL) {
1002 /* Get the current position. */
Victor Stinner99970732017-05-02 15:10:39 +02001003 posobj = portable_lseek(self, NULL, 1);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001004 if (posobj == NULL)
1005 return NULL;
1006 }
1007 else {
1008 Py_INCREF(posobj);
1009 }
Guido van Rossum53807da2007-04-10 19:01:47 +00001010
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001011#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001012 pos = PyLong_AsLongLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001013#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001014 pos = PyLong_AsLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001015#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001016 if (PyErr_Occurred()){
1017 Py_DECREF(posobj);
1018 return NULL;
1019 }
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001020
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001021 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04001022 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001023 errno = 0;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001024#ifdef MS_WINDOWS
1025 ret = _chsize_s(fd, pos);
1026#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001027 ret = ftruncate(fd, pos);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001028#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04001029 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001030 Py_END_ALLOW_THREADS
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001031
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001032 if (ret != 0) {
1033 Py_DECREF(posobj);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001034 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001035 return NULL;
1036 }
Guido van Rossuma9e20242007-03-08 00:43:48 +00001037
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001038 return posobj;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001039}
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001040#endif /* HAVE_FTRUNCATE */
Guido van Rossum53807da2007-04-10 19:01:47 +00001041
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001042static const char *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001043mode_string(fileio *self)
Guido van Rossum53807da2007-04-10 19:01:47 +00001044{
Charles-François Natalidc3044c2012-01-09 22:40:02 +01001045 if (self->created) {
1046 if (self->readable)
1047 return "xb+";
1048 else
1049 return "xb";
1050 }
Antoine Pitroue93b63b2013-09-04 20:46:33 +02001051 if (self->appending) {
1052 if (self->readable)
1053 return "ab+";
1054 else
1055 return "ab";
1056 }
1057 else if (self->readable) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001058 if (self->writable)
1059 return "rb+";
1060 else
1061 return "rb";
1062 }
1063 else
1064 return "wb";
Guido van Rossum53807da2007-04-10 19:01:47 +00001065}
Guido van Rossuma9e20242007-03-08 00:43:48 +00001066
1067static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001068fileio_repr(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +00001069{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001070 PyObject *nameobj, *res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001071
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001072 if (self->fd < 0)
1073 return PyUnicode_FromFormat("<_io.FileIO [closed]>");
Antoine Pitrou716c4442009-05-23 19:04:03 +00001074
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001075 if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) {
1076 return NULL;
1077 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001078 if (nameobj == NULL) {
Robert Collins933430a2014-10-18 13:32:43 +13001079 res = PyUnicode_FromFormat(
Serhiy Storchaka4954f9f2014-12-02 23:39:56 +02001080 "<_io.FileIO fd=%d mode='%s' closefd=%s>",
1081 self->fd, mode_string(self), self->closefd ? "True" : "False");
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001082 }
1083 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001084 int status = Py_ReprEnter((PyObject *)self);
1085 res = NULL;
1086 if (status == 0) {
1087 res = PyUnicode_FromFormat(
1088 "<_io.FileIO name=%R mode='%s' closefd=%s>",
1089 nameobj, mode_string(self), self->closefd ? "True" : "False");
1090 Py_ReprLeave((PyObject *)self);
1091 }
1092 else if (status > 0) {
1093 PyErr_Format(PyExc_RuntimeError,
1094 "reentrant call inside %s.__repr__",
1095 Py_TYPE(self)->tp_name);
1096 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001097 Py_DECREF(nameobj);
1098 }
1099 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001100}
1101
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001102/*[clinic input]
1103_io.FileIO.isatty
1104
1105True if the file is connected to a TTY device.
1106[clinic start generated code]*/
1107
Guido van Rossuma9e20242007-03-08 00:43:48 +00001108static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001109_io_FileIO_isatty_impl(fileio *self)
1110/*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +00001111{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001112 long res;
Guido van Rossum53807da2007-04-10 19:01:47 +00001113
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001114 if (self->fd < 0)
1115 return err_closed();
1116 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001117 _Py_BEGIN_SUPPRESS_IPH
Steve Dower940f33a2016-09-08 11:21:54 -07001118 res = isatty(self->fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001119 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001120 Py_END_ALLOW_THREADS
1121 return PyBool_FromLong(res);
Guido van Rossuma9e20242007-03-08 00:43:48 +00001122}
1123
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001124#include "clinic/fileio.c.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +00001125
1126static PyMethodDef fileio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001127 _IO_FILEIO_READ_METHODDEF
1128 _IO_FILEIO_READALL_METHODDEF
1129 _IO_FILEIO_READINTO_METHODDEF
1130 _IO_FILEIO_WRITE_METHODDEF
1131 _IO_FILEIO_SEEK_METHODDEF
1132 _IO_FILEIO_TELL_METHODDEF
1133 _IO_FILEIO_TRUNCATE_METHODDEF
1134 _IO_FILEIO_CLOSE_METHODDEF
1135 _IO_FILEIO_SEEKABLE_METHODDEF
1136 _IO_FILEIO_READABLE_METHODDEF
1137 _IO_FILEIO_WRITABLE_METHODDEF
1138 _IO_FILEIO_FILENO_METHODDEF
1139 _IO_FILEIO_ISATTY_METHODDEF
Antoine Pitroue033e062010-10-29 10:38:18 +00001140 {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, 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};