blob: 52a6f49e1d325b38c034a3c4d17fe932e9767a9b [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
Steve Dowerb82e17e2019-05-23 08:45:22 -0700361 if (PySys_Audit("open", "Osi", nameobj, mode, flags) < 0) {
362 goto error;
363 }
364
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000365 if (fd >= 0) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000366 self->fd = fd;
367 self->closefd = closefd;
368 }
369 else {
370 self->closefd = 1;
371 if (!closefd) {
372 PyErr_SetString(PyExc_ValueError,
373 "Cannot use closefd=False with file name");
374 goto error;
375 }
Guido van Rossum2dced8b2007-10-30 17:27:30 +0000376
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000377 errno = 0;
Ross Lagerwall59142db2011-10-31 20:34:46 +0200378 if (opener == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000379 do {
380 Py_BEGIN_ALLOW_THREADS
Thomas Helleraf2be262007-07-12 11:03:13 +0000381#ifdef MS_WINDOWS
Steve Dowereacee982017-02-04 14:38:11 -0800382 self->fd = _wopen(widename, flags, 0666);
383#else
384 self->fd = open(name, flags, 0666);
Thomas Helleraf2be262007-07-12 11:03:13 +0000385#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000386 Py_END_ALLOW_THREADS
387 } while (self->fd < 0 && errno == EINTR &&
388 !(async_err = PyErr_CheckSignals()));
Victor Stinner9672da72015-03-04 18:40:10 +0100389
390 if (async_err)
391 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200392 }
393 else {
394 PyObject *fdobj;
395
396#ifndef MS_WINDOWS
397 /* the opener may clear the atomic flag */
398 atomic_flag_works = NULL;
399#endif
400
401 fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200402 if (fdobj == NULL)
403 goto error;
404 if (!PyLong_Check(fdobj)) {
405 Py_DECREF(fdobj);
406 PyErr_SetString(PyExc_TypeError,
407 "expected integer from opener");
408 goto error;
409 }
410
Serhiy Storchaka78980432013-01-15 01:12:17 +0200411 self->fd = _PyLong_AsInt(fdobj);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200412 Py_DECREF(fdobj);
Barry Warsaw480e2852016-06-08 17:47:26 -0400413 if (self->fd < 0) {
414 if (!PyErr_Occurred()) {
Barry Warsaw118598a2016-06-08 17:54:43 -0400415 /* The opener returned a negative but didn't set an
416 exception. See issue #27066 */
Barry Warsaw480e2852016-06-08 17:47:26 -0400417 PyErr_Format(PyExc_ValueError,
418 "opener returned %d", self->fd);
419 }
Ross Lagerwall59142db2011-10-31 20:34:46 +0200420 goto error;
421 }
422 }
423
Hynek Schlawack7f59fd72012-06-22 09:32:22 +0200424 fd_is_own = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000425 if (self->fd < 0) {
Victor Stinner9672da72015-03-04 18:40:10 +0100426 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000427 goto error;
428 }
Victor Stinnerdaf45552013-08-28 00:53:59 +0200429
430#ifndef MS_WINDOWS
431 if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0)
432 goto error;
433#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000434 }
Antoine Pitroude687222014-06-29 20:07:28 -0400435
436 self->blksize = DEFAULT_BUFFER_SIZE;
Martin Panter0bb62b12015-12-06 03:15:05 +0000437 Py_BEGIN_ALLOW_THREADS
438 fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
439 Py_END_ALLOW_THREADS
440 if (fstat_result < 0) {
Martin Panter49d3db92015-12-06 11:12:15 +0000441 /* Tolerate fstat() errors other than EBADF. See Issue #25717, where
442 an anonymous file on a Virtual Box shared folder filesystem would
443 raise ENOENT. */
Martin Panter0bb62b12015-12-06 03:15:05 +0000444#ifdef MS_WINDOWS
445 if (GetLastError() == ERROR_INVALID_HANDLE) {
446 PyErr_SetFromWindowsErr(0);
447#else
448 if (errno == EBADF) {
449 PyErr_SetFromErrno(PyExc_OSError);
450#endif
451 goto error;
452 }
Antoine Pitroude687222014-06-29 20:07:28 -0400453 }
Martin Panter0bb62b12015-12-06 03:15:05 +0000454 else {
455#if defined(S_ISDIR) && defined(EISDIR)
456 /* On Unix, open will succeed for directories.
457 In Python, there should be no file objects referring to
458 directories, so we need a check. */
459 if (S_ISDIR(fdfstat.st_mode)) {
460 errno = EISDIR;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300461 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Martin Panter0bb62b12015-12-06 03:15:05 +0000462 goto error;
463 }
Antoine Pitroude687222014-06-29 20:07:28 -0400464#endif /* defined(S_ISDIR) */
465#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin Panter0bb62b12015-12-06 03:15:05 +0000466 if (fdfstat.st_blksize > 1)
467 self->blksize = fdfstat.st_blksize;
Antoine Pitroude687222014-06-29 20:07:28 -0400468#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
Martin Panter0bb62b12015-12-06 03:15:05 +0000469 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000470
Victor Stinner89e34362011-01-07 18:47:22 +0000471#if defined(MS_WINDOWS) || defined(__CYGWIN__)
472 /* don't translate newlines (\r\n <=> \n) */
473 _setmode(self->fd, O_BINARY);
474#endif
475
Victor Stinnerd9d04192013-11-06 23:50:10 +0100476 if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000477 goto error;
Antoine Pitrou08838b62009-01-21 00:55:13 +0000478
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200479 if (self->appending) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000480 /* For consistent behaviour, we explicitly seek to the
481 end of file (otherwise, it might be done only on the
482 first write()). */
Victor Stinner99970732017-05-02 15:10:39 +0200483 PyObject *pos = portable_lseek(self, NULL, 2);
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200484 if (pos == NULL)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000485 goto error;
486 Py_DECREF(pos);
487 }
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000488
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000489 goto done;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000490
491 error:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000492 ret = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200493 if (!fd_is_own)
494 self->fd = -1;
Benjamin Petersonbbb04122010-10-30 23:16:28 +0000495 if (self->fd >= 0)
496 internal_close(self);
Guido van Rossum53807da2007-04-10 19:01:47 +0000497
Guido van Rossuma9e20242007-03-08 00:43:48 +0000498 done:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000499 Py_CLEAR(stringobj);
500 return ret;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000501}
502
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000503static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000504fileio_traverse(fileio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000505{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000506 Py_VISIT(self->dict);
507 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000508}
509
510static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000511fileio_clear(fileio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000512{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000513 Py_CLEAR(self->dict);
514 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000515}
516
Guido van Rossuma9e20242007-03-08 00:43:48 +0000517static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000518fileio_dealloc(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000519{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200520 self->finalizing = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000521 if (_PyIOBase_finalize((PyObject *) self) < 0)
522 return;
523 _PyObject_GC_UNTRACK(self);
524 if (self->weakreflist != NULL)
525 PyObject_ClearWeakRefs((PyObject *) self);
526 Py_CLEAR(self->dict);
527 Py_TYPE(self)->tp_free((PyObject *)self);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000528}
529
530static PyObject *
531err_closed(void)
532{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000533 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
534 return NULL;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000535}
536
537static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200538err_mode(const char *action)
Guido van Rossum53807da2007-04-10 19:01:47 +0000539{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100540 _PyIO_State *state = IO_STATE();
541 if (state != NULL)
542 PyErr_Format(state->unsupported_operation,
543 "File not open for %s", action);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000544 return NULL;
Guido van Rossum53807da2007-04-10 19:01:47 +0000545}
546
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300547/*[clinic input]
548_io.FileIO.fileno
549
550Return the underlying file descriptor (an integer).
551[clinic start generated code]*/
552
Guido van Rossum53807da2007-04-10 19:01:47 +0000553static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300554_io_FileIO_fileno_impl(fileio *self)
555/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000556{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000557 if (self->fd < 0)
558 return err_closed();
559 return PyLong_FromLong((long) self->fd);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000560}
561
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300562/*[clinic input]
563_io.FileIO.readable
564
565True if file was opened in a read mode.
566[clinic start generated code]*/
567
Guido van Rossuma9e20242007-03-08 00:43:48 +0000568static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300569_io_FileIO_readable_impl(fileio *self)
570/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000571{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000572 if (self->fd < 0)
573 return err_closed();
574 return PyBool_FromLong((long) self->readable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000575}
576
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300577/*[clinic input]
578_io.FileIO.writable
579
580True if file was opened in a write mode.
581[clinic start generated code]*/
582
Guido van Rossuma9e20242007-03-08 00:43:48 +0000583static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300584_io_FileIO_writable_impl(fileio *self)
585/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000586{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000587 if (self->fd < 0)
588 return err_closed();
589 return PyBool_FromLong((long) self->writable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000590}
591
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300592/*[clinic input]
593_io.FileIO.seekable
594
595True if file supports random-access.
596[clinic start generated code]*/
597
Guido van Rossuma9e20242007-03-08 00:43:48 +0000598static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300599_io_FileIO_seekable_impl(fileio *self)
600/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000601{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000602 if (self->fd < 0)
603 return err_closed();
604 if (self->seekable < 0) {
Victor Stinner99970732017-05-02 15:10:39 +0200605 /* portable_lseek() sets the seekable attribute */
606 PyObject *pos = portable_lseek(self, NULL, SEEK_CUR);
607 assert(self->seekable >= 0);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000608 if (pos == NULL) {
609 PyErr_Clear();
Victor Stinner99970732017-05-02 15:10:39 +0200610 }
611 else {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000612 Py_DECREF(pos);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000613 }
614 }
615 return PyBool_FromLong((long) self->seekable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000616}
617
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300618/*[clinic input]
619_io.FileIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700620 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300621 /
622
623Same as RawIOBase.readinto().
624[clinic start generated code]*/
625
Guido van Rossuma9e20242007-03-08 00:43:48 +0000626static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300627_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700628/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000629{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100630 Py_ssize_t n;
631 int err;
Guido van Rossum53807da2007-04-10 19:01:47 +0000632
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000633 if (self->fd < 0)
634 return err_closed();
635 if (!self->readable)
636 return err_mode("reading");
Guido van Rossum53807da2007-04-10 19:01:47 +0000637
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300638 n = _Py_read(self->fd, buffer->buf, buffer->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100639 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100640 err = errno;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100641
642 if (n == -1) {
643 if (err == EAGAIN) {
644 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000645 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100646 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000647 return NULL;
648 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000649
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000650 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000651}
652
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653static size_t
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100654new_buffersize(fileio *self, size_t currentsize)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655{
Antoine Pitroua3f44572012-04-17 13:50:58 +0200656 size_t addend;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100657
Nadeem Vawdad41a98b2011-10-13 13:34:16 +0200658 /* Expand the buffer by an amount proportional to the current size,
Antoine Pitroua3f44572012-04-17 13:50:58 +0200659 giving us amortized linear-time behavior. For bigger sizes, use a
660 less-than-double growth factor to avoid excessive allocation. */
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100661 assert(currentsize <= PY_SSIZE_T_MAX);
Antoine Pitroua3f44572012-04-17 13:50:58 +0200662 if (currentsize > 65536)
663 addend = currentsize >> 3;
664 else
665 addend = 256 + currentsize;
666 if (addend < SMALLCHUNK)
667 /* Avoid tiny read() calls. */
668 addend = SMALLCHUNK;
669 return addend + currentsize;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000670}
671
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300672/*[clinic input]
673_io.FileIO.readall
674
675Read all data from the file, returned as bytes.
676
677In non-blocking mode, returns as much as is immediately available,
678or None if no data is available. Return an empty bytes object at EOF.
679[clinic start generated code]*/
680
Guido van Rossum7165cb12007-07-10 06:54:34 +0000681static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300682_io_FileIO_readall_impl(fileio *self)
683/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/
Guido van Rossum7165cb12007-07-10 06:54:34 +0000684{
Victor Stinnere134a7f2015-03-30 10:09:31 +0200685 struct _Py_stat_struct status;
Victor Stinnera2a64772011-10-11 22:45:02 +0200686 Py_off_t pos, end;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000687 PyObject *result;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100688 Py_ssize_t bytes_read = 0;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100689 Py_ssize_t n;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100690 size_t bufsize;
Nir Soffer6a894812017-12-01 03:18:58 +0200691 int fstat_result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000692
Victor Stinnerb79f28c2011-05-25 22:09:03 +0200693 if (self->fd < 0)
694 return err_closed();
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000695
Nir Soffer6a894812017-12-01 03:18:58 +0200696 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400697 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200698#ifdef MS_WINDOWS
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200699 pos = _lseeki64(self->fd, 0L, SEEK_CUR);
700#else
701 pos = lseek(self->fd, 0L, SEEK_CUR);
702#endif
Steve Dower8fc89802015-04-12 00:26:27 -0400703 _Py_END_SUPPRESS_IPH
Nir Soffer6a894812017-12-01 03:18:58 +0200704 fstat_result = _Py_fstat_noraise(self->fd, &status);
705 Py_END_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400706
Nir Soffer6a894812017-12-01 03:18:58 +0200707 if (fstat_result == 0)
Victor Stinnere134a7f2015-03-30 10:09:31 +0200708 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
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300773 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300774 /
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)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300785/*[clinic end generated code: output=42528d39dd0ca641 input=bec9a2c704ddcbc9]*/
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
Stéphane Wirtel74a8b6e2018-10-18 01:05:04 +0200799 if (size > _PY_READ_MAX) {
800 size = _PY_READ_MAX;
801 }
Victor Stinner66aab0c2015-03-19 22:53:20 +0100802
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000803 bytes = PyBytes_FromStringAndSize(NULL, size);
804 if (bytes == NULL)
805 return NULL;
806 ptr = PyBytes_AS_STRING(bytes);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000807
Victor Stinner66aab0c2015-03-19 22:53:20 +0100808 n = _Py_read(self->fd, ptr, size);
809 if (n == -1) {
810 /* copy errno because Py_DECREF() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100811 int err = errno;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000812 Py_DECREF(bytes);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100813 if (err == EAGAIN) {
814 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000815 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100816 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000817 return NULL;
818 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000819
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000820 if (n != size) {
821 if (_PyBytes_Resize(&bytes, n) < 0) {
Victor Stinner85c761d2013-07-16 21:36:02 +0200822 Py_CLEAR(bytes);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000823 return NULL;
824 }
825 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000826
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000827 return (PyObject *) bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000828}
829
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300830/*[clinic input]
831_io.FileIO.write
832 b: Py_buffer
833 /
834
Martin Panter6bb91f32016-05-28 00:41:57 +0000835Write buffer b to file, return number of bytes written.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300836
837Only makes one system call, so not all of the data may be written.
838The number of bytes actually written is returned. In non-blocking mode,
839returns None if the write would block.
840[clinic start generated code]*/
841
Guido van Rossuma9e20242007-03-08 00:43:48 +0000842static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300843_io_FileIO_write_impl(fileio *self, Py_buffer *b)
Martin Panter6bb91f32016-05-28 00:41:57 +0000844/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000845{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100846 Py_ssize_t n;
847 int err;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000848
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000849 if (self->fd < 0)
850 return err_closed();
851 if (!self->writable)
852 return err_mode("writing");
Guido van Rossum53807da2007-04-10 19:01:47 +0000853
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300854 n = _Py_write(self->fd, b->buf, b->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100855 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100856 err = errno;
Martin v. Löwis423be952008-08-13 15:53:07 +0000857
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000858 if (n < 0) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100859 if (err == EAGAIN) {
860 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000861 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100862 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000863 return NULL;
864 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000865
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000866 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000867}
868
Guido van Rossum53807da2007-04-10 19:01:47 +0000869/* XXX Windows support below is likely incomplete */
870
Guido van Rossum53807da2007-04-10 19:01:47 +0000871/* Cribbed from posix_lseek() */
872static PyObject *
Victor Stinner99970732017-05-02 15:10:39 +0200873portable_lseek(fileio *self, PyObject *posobj, int whence)
Guido van Rossum53807da2007-04-10 19:01:47 +0000874{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000875 Py_off_t pos, res;
Victor Stinner99970732017-05-02 15:10:39 +0200876 int fd = self->fd;
Guido van Rossum53807da2007-04-10 19:01:47 +0000877
878#ifdef SEEK_SET
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000879 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
880 switch (whence) {
Guido van Rossum53807da2007-04-10 19:01:47 +0000881#if SEEK_SET != 0
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000882 case 0: whence = SEEK_SET; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000883#endif
884#if SEEK_CUR != 1
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000885 case 1: whence = SEEK_CUR; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000886#endif
Antoine Pitrou4f7945f2009-01-20 11:42:11 +0000887#if SEEK_END != 2
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000888 case 2: whence = SEEK_END; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000889#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000890 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000891#endif /* SEEK_SET */
892
Victor Stinner99970732017-05-02 15:10:39 +0200893 if (posobj == NULL) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000894 pos = 0;
Victor Stinner99970732017-05-02 15:10:39 +0200895 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000896 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
Victor Stinner99970732017-05-02 15:10:39 +0200919
920 if (self->seekable < 0) {
921 self->seekable = (res >= 0);
922 }
923
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000924 if (res < 0)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300925 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum53807da2007-04-10 19:01:47 +0000926
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000927#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000928 return PyLong_FromLongLong(res);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000929#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000930 return PyLong_FromLong(res);
Guido van Rossum53807da2007-04-10 19:01:47 +0000931#endif
932}
933
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300934/*[clinic input]
935_io.FileIO.seek
936 pos: object
937 whence: int = 0
938 /
Guido van Rossuma9e20242007-03-08 00:43:48 +0000939
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300940Move to new file position and return the file position.
941
942Argument offset is a byte count. Optional argument whence defaults to
943SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
944are SEEK_CUR or 1 (move relative to current position, positive or negative),
945and SEEK_END or 2 (move relative to end of file, usually negative, although
946many platforms allow seeking beyond the end of a file).
947
948Note that not all file objects are seekable.
949[clinic start generated code]*/
950
951static PyObject *
952_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
953/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/
954{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000955 if (self->fd < 0)
956 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000957
Victor Stinner99970732017-05-02 15:10:39 +0200958 return portable_lseek(self, pos, whence);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000959}
960
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300961/*[clinic input]
962_io.FileIO.tell
963
964Current file position.
965
966Can raise OSError for non seekable files.
967[clinic start generated code]*/
968
Guido van Rossuma9e20242007-03-08 00:43:48 +0000969static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300970_io_FileIO_tell_impl(fileio *self)
971/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000972{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000973 if (self->fd < 0)
974 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000975
Victor Stinner99970732017-05-02 15:10:39 +0200976 return portable_lseek(self, NULL, 1);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000977}
978
Thomas Hellerc6a55ee2007-07-11 12:45:46 +0000979#ifdef HAVE_FTRUNCATE
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300980/*[clinic input]
981_io.FileIO.truncate
982 size as posobj: object = NULL
983 /
984
985Truncate the file to at most size bytes and return the truncated size.
986
987Size defaults to the current file position, as returned by tell().
988The current file position is changed to the value of size.
989[clinic start generated code]*/
990
Guido van Rossuma9e20242007-03-08 00:43:48 +0000991static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300992_io_FileIO_truncate_impl(fileio *self, PyObject *posobj)
993/*[clinic end generated code: output=e49ca7a916c176fa input=9026af44686b7318]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000994{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000995 Py_off_t pos;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000996 int ret;
997 int fd;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000998
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000999 fd = self->fd;
1000 if (fd < 0)
1001 return err_closed();
1002 if (!self->writable)
1003 return err_mode("writing");
Guido van Rossuma9e20242007-03-08 00:43:48 +00001004
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001005 if (posobj == Py_None || posobj == NULL) {
1006 /* Get the current position. */
Victor Stinner99970732017-05-02 15:10:39 +02001007 posobj = portable_lseek(self, NULL, 1);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001008 if (posobj == NULL)
1009 return NULL;
1010 }
1011 else {
1012 Py_INCREF(posobj);
1013 }
Guido van Rossum53807da2007-04-10 19:01:47 +00001014
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001015#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001016 pos = PyLong_AsLongLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001017#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001018 pos = PyLong_AsLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001019#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001020 if (PyErr_Occurred()){
1021 Py_DECREF(posobj);
1022 return NULL;
1023 }
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001024
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001025 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04001026 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001027 errno = 0;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001028#ifdef MS_WINDOWS
1029 ret = _chsize_s(fd, pos);
1030#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001031 ret = ftruncate(fd, pos);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001032#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04001033 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001034 Py_END_ALLOW_THREADS
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001035
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001036 if (ret != 0) {
1037 Py_DECREF(posobj);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001038 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001039 return NULL;
1040 }
Guido van Rossuma9e20242007-03-08 00:43:48 +00001041
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001042 return posobj;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001043}
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001044#endif /* HAVE_FTRUNCATE */
Guido van Rossum53807da2007-04-10 19:01:47 +00001045
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001046static const char *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001047mode_string(fileio *self)
Guido van Rossum53807da2007-04-10 19:01:47 +00001048{
Charles-François Natalidc3044c2012-01-09 22:40:02 +01001049 if (self->created) {
1050 if (self->readable)
1051 return "xb+";
1052 else
1053 return "xb";
1054 }
Antoine Pitroue93b63b2013-09-04 20:46:33 +02001055 if (self->appending) {
1056 if (self->readable)
1057 return "ab+";
1058 else
1059 return "ab";
1060 }
1061 else if (self->readable) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001062 if (self->writable)
1063 return "rb+";
1064 else
1065 return "rb";
1066 }
1067 else
1068 return "wb";
Guido van Rossum53807da2007-04-10 19:01:47 +00001069}
Guido van Rossuma9e20242007-03-08 00:43:48 +00001070
1071static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001072fileio_repr(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +00001073{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001074 PyObject *nameobj, *res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001075
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001076 if (self->fd < 0)
1077 return PyUnicode_FromFormat("<_io.FileIO [closed]>");
Antoine Pitrou716c4442009-05-23 19:04:03 +00001078
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001079 if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) {
1080 return NULL;
1081 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001082 if (nameobj == NULL) {
Robert Collins933430a2014-10-18 13:32:43 +13001083 res = PyUnicode_FromFormat(
Serhiy Storchaka4954f9f2014-12-02 23:39:56 +02001084 "<_io.FileIO fd=%d mode='%s' closefd=%s>",
1085 self->fd, mode_string(self), self->closefd ? "True" : "False");
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001086 }
1087 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001088 int status = Py_ReprEnter((PyObject *)self);
1089 res = NULL;
1090 if (status == 0) {
1091 res = PyUnicode_FromFormat(
1092 "<_io.FileIO name=%R mode='%s' closefd=%s>",
1093 nameobj, mode_string(self), self->closefd ? "True" : "False");
1094 Py_ReprLeave((PyObject *)self);
1095 }
1096 else if (status > 0) {
1097 PyErr_Format(PyExc_RuntimeError,
1098 "reentrant call inside %s.__repr__",
1099 Py_TYPE(self)->tp_name);
1100 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001101 Py_DECREF(nameobj);
1102 }
1103 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001104}
1105
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001106/*[clinic input]
1107_io.FileIO.isatty
1108
1109True if the file is connected to a TTY device.
1110[clinic start generated code]*/
1111
Guido van Rossuma9e20242007-03-08 00:43:48 +00001112static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001113_io_FileIO_isatty_impl(fileio *self)
1114/*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +00001115{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001116 long res;
Guido van Rossum53807da2007-04-10 19:01:47 +00001117
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001118 if (self->fd < 0)
1119 return err_closed();
1120 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001121 _Py_BEGIN_SUPPRESS_IPH
Steve Dower940f33a2016-09-08 11:21:54 -07001122 res = isatty(self->fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001123 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001124 Py_END_ALLOW_THREADS
1125 return PyBool_FromLong(res);
Guido van Rossuma9e20242007-03-08 00:43:48 +00001126}
1127
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001128#include "clinic/fileio.c.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +00001129
1130static PyMethodDef fileio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001131 _IO_FILEIO_READ_METHODDEF
1132 _IO_FILEIO_READALL_METHODDEF
1133 _IO_FILEIO_READINTO_METHODDEF
1134 _IO_FILEIO_WRITE_METHODDEF
1135 _IO_FILEIO_SEEK_METHODDEF
1136 _IO_FILEIO_TELL_METHODDEF
1137 _IO_FILEIO_TRUNCATE_METHODDEF
1138 _IO_FILEIO_CLOSE_METHODDEF
1139 _IO_FILEIO_SEEKABLE_METHODDEF
1140 _IO_FILEIO_READABLE_METHODDEF
1141 _IO_FILEIO_WRITABLE_METHODDEF
1142 _IO_FILEIO_FILENO_METHODDEF
1143 _IO_FILEIO_ISATTY_METHODDEF
Antoine Pitroue033e062010-10-29 10:38:18 +00001144 {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001145 {NULL, NULL} /* sentinel */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001146};
1147
Guido van Rossum53807da2007-04-10 19:01:47 +00001148/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */
1149
Guido van Rossumb0428152007-04-08 17:44:42 +00001150static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001151get_closed(fileio *self, void *closure)
Guido van Rossumb0428152007-04-08 17:44:42 +00001152{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001153 return PyBool_FromLong((long)(self->fd < 0));
Guido van Rossum53807da2007-04-10 19:01:47 +00001154}
1155
1156static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001157get_closefd(fileio *self, void *closure)
Christian Heimesecc42a22008-11-05 19:30:32 +00001158{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001159 return PyBool_FromLong((long)(self->closefd));
Christian Heimesecc42a22008-11-05 19:30:32 +00001160}
1161
1162static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001163get_mode(fileio *self, void *closure)
Guido van Rossum53807da2007-04-10 19:01:47 +00001164{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001165 return PyUnicode_FromString(mode_string(self));
Guido van Rossumb0428152007-04-08 17:44:42 +00001166}
1167
1168static PyGetSetDef fileio_getsetlist[] = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001169 {"closed", (getter)get_closed, NULL, "True if the file is closed"},
1170 {"closefd", (getter)get_closefd, NULL,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +03001171 "True if the file descriptor will be closed by close()."},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001172 {"mode", (getter)get_mode, NULL, "String giving the file mode"},
1173 {NULL},
Guido van Rossumb0428152007-04-08 17:44:42 +00001174};
1175
Antoine Pitrou796564c2013-07-30 19:59:21 +02001176static PyMemberDef fileio_members[] = {
Antoine Pitroude687222014-06-29 20:07:28 -04001177 {"_blksize", T_UINT, offsetof(fileio, blksize), 0},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001178 {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
1179 {NULL}
1180};
1181
Guido van Rossuma9e20242007-03-08 00:43:48 +00001182PyTypeObject PyFileIO_Type = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001183 PyVarObject_HEAD_INIT(NULL, 0)
1184 "_io.FileIO",
1185 sizeof(fileio),
1186 0,
1187 (destructor)fileio_dealloc, /* tp_dealloc */
1188 0, /* tp_print */
1189 0, /* tp_getattr */
1190 0, /* tp_setattr */
1191 0, /* tp_reserved */
1192 (reprfunc)fileio_repr, /* tp_repr */
1193 0, /* tp_as_number */
1194 0, /* tp_as_sequence */
1195 0, /* tp_as_mapping */
1196 0, /* tp_hash */
1197 0, /* tp_call */
1198 0, /* tp_str */
1199 PyObject_GenericGetAttr, /* tp_getattro */
1200 0, /* tp_setattro */
1201 0, /* tp_as_buffer */
1202 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001203 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001204 _io_FileIO___init____doc__, /* tp_doc */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001205 (traverseproc)fileio_traverse, /* tp_traverse */
1206 (inquiry)fileio_clear, /* tp_clear */
1207 0, /* tp_richcompare */
1208 offsetof(fileio, weakreflist), /* tp_weaklistoffset */
1209 0, /* tp_iter */
1210 0, /* tp_iternext */
1211 fileio_methods, /* tp_methods */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001212 fileio_members, /* tp_members */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001213 fileio_getsetlist, /* tp_getset */
1214 0, /* tp_base */
1215 0, /* tp_dict */
1216 0, /* tp_descr_get */
1217 0, /* tp_descr_set */
1218 offsetof(fileio, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001219 _io_FileIO___init__, /* tp_init */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001220 PyType_GenericAlloc, /* tp_alloc */
1221 fileio_new, /* tp_new */
1222 PyObject_GC_Del, /* tp_free */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001223 0, /* tp_is_gc */
1224 0, /* tp_bases */
1225 0, /* tp_mro */
1226 0, /* tp_cache */
1227 0, /* tp_subclasses */
1228 0, /* tp_weaklist */
1229 0, /* tp_del */
1230 0, /* tp_version_tag */
1231 0, /* tp_finalize */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001232};