blob: 7c8ba37c4fe9409fbf2b573a6ee572f761f17288 [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"
Victor Stinner4a21e572020-04-15 02:35:41 +02006#include "structmember.h" // PyMemberDef
Benjamin Peterson74fa9f72019-11-12 14:51:34 -08007#include <stdbool.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +00008#ifdef HAVE_SYS_TYPES_H
Guido van Rossuma9e20242007-03-08 00:43:48 +00009#include <sys/types.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +000010#endif
11#ifdef HAVE_SYS_STAT_H
Guido van Rossuma9e20242007-03-08 00:43:48 +000012#include <sys/stat.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +000013#endif
Steve Dowerbfce0f92016-12-28 15:41:09 -080014#ifdef HAVE_IO_H
15#include <io.h>
16#endif
Benjamin Peterson2614cda2010-03-21 22:36:19 +000017#ifdef HAVE_FCNTL_H
Guido van Rossuma9e20242007-03-08 00:43:48 +000018#include <fcntl.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +000019#endif
Guido van Rossuma9e20242007-03-08 00:43:48 +000020#include <stddef.h> /* For offsetof */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000021#include "_iomodule.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +000022
23/*
24 * Known likely problems:
25 *
26 * - Files larger then 2**32-1
27 * - Files with unicode filenames
28 * - Passing numbers greater than 2**32-1 when an integer is expected
29 * - Making it work on Windows and other oddball platforms
30 *
31 * To Do:
32 *
33 * - autoconfify header file inclusion
Guido van Rossuma9e20242007-03-08 00:43:48 +000034 */
35
36#ifdef MS_WINDOWS
37/* can simulate truncate with Win32 API functions; see file_truncate */
Thomas Hellerfdeee3a2007-07-12 11:21:36 +000038#define HAVE_FTRUNCATE
Guido van Rossuma9e20242007-03-08 00:43:48 +000039#define WIN32_LEAN_AND_MEAN
40#include <windows.h>
41#endif
42
Christian Heimesa872de52008-12-05 08:26:55 +000043#if BUFSIZ < (8*1024)
44#define SMALLCHUNK (8*1024)
45#elif (BUFSIZ >= (2 << 25))
Victor Stinner8c663fd2017-11-08 14:44:44 -080046#error "unreasonable BUFSIZ > 64 MiB defined"
Christian Heimesa872de52008-12-05 08:26:55 +000047#else
48#define SMALLCHUNK BUFSIZ
49#endif
50
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030051/*[clinic input]
52module _io
53class _io.FileIO "fileio *" "&PyFileIO_Type"
54[clinic start generated code]*/
55/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/
56
Guido van Rossuma9e20242007-03-08 00:43:48 +000057typedef struct {
Antoine Pitrouae4b4722010-05-05 16:31:07 +000058 PyObject_HEAD
59 int fd;
Charles-François Natalidc3044c2012-01-09 22:40:02 +010060 unsigned int created : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000061 unsigned int readable : 1;
62 unsigned int writable : 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +020063 unsigned int appending : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000064 signed int seekable : 2; /* -1 means unknown */
65 unsigned int closefd : 1;
Antoine Pitrou796564c2013-07-30 19:59:21 +020066 char finalizing;
Antoine Pitroude687222014-06-29 20:07:28 -040067 unsigned int blksize;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000068 PyObject *weakreflist;
69 PyObject *dict;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000070} fileio;
Guido van Rossuma9e20242007-03-08 00:43:48 +000071
Collin Winteraf334382007-03-08 21:46:15 +000072PyTypeObject PyFileIO_Type;
73
Victor Stinnerd9d04192013-11-06 23:50:10 +010074_Py_IDENTIFIER(name);
75
Guido van Rossuma9e20242007-03-08 00:43:48 +000076#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
77
Victor Stinner99970732017-05-02 15:10:39 +020078/* Forward declarations */
Benjamin Peterson74fa9f72019-11-12 14:51:34 -080079static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error);
Victor Stinner99970732017-05-02 15:10:39 +020080
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000081int
82_PyFileIO_closed(PyObject *self)
83{
Antoine Pitrouae4b4722010-05-05 16:31:07 +000084 return ((fileio *)self)->fd < 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000085}
Antoine Pitrou08838b62009-01-21 00:55:13 +000086
Antoine Pitroue033e062010-10-29 10:38:18 +000087/* Because this can call arbitrary code, it shouldn't be called when
88 the refcount is 0 (that is, not directly from tp_dealloc unless
89 the refcount has been temporarily re-incremented). */
90static PyObject *
91fileio_dealloc_warn(fileio *self, PyObject *source)
92{
93 if (self->fd >= 0 && self->closefd) {
94 PyObject *exc, *val, *tb;
95 PyErr_Fetch(&exc, &val, &tb);
Victor Stinner914cde82016-03-19 01:03:51 +010096 if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) {
Antoine Pitroue033e062010-10-29 10:38:18 +000097 /* Spurious errors can appear at shutdown */
98 if (PyErr_ExceptionMatches(PyExc_Warning))
99 PyErr_WriteUnraisable((PyObject *) self);
100 }
101 PyErr_Restore(exc, val, tb);
102 }
103 Py_RETURN_NONE;
104}
105
Kristján Valur Jónsson19288c22008-12-18 17:15:54 +0000106/* Returns 0 on success, -1 with exception set on failure. */
Neal Norwitz88b44da2007-08-12 17:23:54 +0000107static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000108internal_close(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000109{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000110 int err = 0;
111 int save_errno = 0;
112 if (self->fd >= 0) {
113 int fd = self->fd;
114 self->fd = -1;
115 /* fd is accessible and someone else may have closed it */
Steve Dower940f33a2016-09-08 11:21:54 -0700116 Py_BEGIN_ALLOW_THREADS
117 _Py_BEGIN_SUPPRESS_IPH
118 err = close(fd);
119 if (err < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000120 save_errno = errno;
Steve Dower940f33a2016-09-08 11:21:54 -0700121 _Py_END_SUPPRESS_IPH
122 Py_END_ALLOW_THREADS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000123 }
124 if (err < 0) {
125 errno = save_errno;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300126 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000127 return -1;
128 }
129 return 0;
Neal Norwitz88b44da2007-08-12 17:23:54 +0000130}
131
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300132/*[clinic input]
133_io.FileIO.close
134
135Close the file.
136
137A closed file cannot be used for further I/O operations. close() may be
138called more than once without error.
139[clinic start generated code]*/
140
Neal Norwitz88b44da2007-08-12 17:23:54 +0000141static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300142_io_FileIO_close_impl(fileio *self)
143/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/
Neal Norwitz88b44da2007-08-12 17:23:54 +0000144{
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200145 PyObject *res;
146 PyObject *exc, *val, *tb;
147 int rc;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200148 _Py_IDENTIFIER(close);
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200149 res = _PyObject_CallMethodIdOneArg((PyObject*)&PyRawIOBase_Type,
150 &PyId_close, (PyObject *)self);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000151 if (!self->closefd) {
152 self->fd = -1;
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200153 return res;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000154 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200155 if (res == NULL)
156 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou796564c2013-07-30 19:59:21 +0200157 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000158 PyObject *r = fileio_dealloc_warn(self, (PyObject *) self);
159 if (r)
160 Py_DECREF(r);
161 else
162 PyErr_Clear();
163 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200164 rc = internal_close(self);
165 if (res == NULL)
166 _PyErr_ChainExceptions(exc, val, tb);
167 if (rc < 0)
168 Py_CLEAR(res);
169 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000170}
171
172static PyObject *
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000173fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000174{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000175 fileio *self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000176
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000177 assert(type != NULL && type->tp_alloc != NULL);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000178
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000179 self = (fileio *) type->tp_alloc(type, 0);
180 if (self != NULL) {
181 self->fd = -1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100182 self->created = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000183 self->readable = 0;
184 self->writable = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200185 self->appending = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000186 self->seekable = -1;
Antoine Pitroude687222014-06-29 20:07:28 -0400187 self->blksize = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000188 self->closefd = 1;
189 self->weakreflist = NULL;
190 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000191
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000192 return (PyObject *) self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000193}
194
Victor Stinnerdaf45552013-08-28 00:53:59 +0200195#ifdef O_CLOEXEC
196extern int _Py_open_cloexec_works;
197#endif
Guido van Rossuma9e20242007-03-08 00:43:48 +0000198
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300199/*[clinic input]
200_io.FileIO.__init__
201 file as nameobj: object
202 mode: str = "r"
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200203 closefd: bool(accept={int}) = True
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300204 opener: object = None
205
206Open a file.
207
208The mode can be 'r' (default), 'w', 'x' or 'a' for reading,
209writing, exclusive creation or appending. The file will be created if it
210doesn't exist when opened for writing or appending; it will be truncated
211when opened for writing. A FileExistsError will be raised if it already
212exists when opened for creating. Opening a file for creating implies
213writing so this mode behaves in a similar way to 'w'.Add a '+' to the mode
214to allow simultaneous reading and writing. A custom opener can be used by
215passing a callable as *opener*. The underlying file descriptor for the file
216object is then obtained by calling opener with (*name*, *flags*).
217*opener* must return an open file descriptor (passing os.open as *opener*
218results in functionality similar to passing None).
219[clinic start generated code]*/
220
Guido van Rossuma9e20242007-03-08 00:43:48 +0000221static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300222_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
223 int closefd, PyObject *opener)
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200224/*[clinic end generated code: output=23413f68e6484bbd input=1596c9157a042a39]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000225{
Thomas Helleraf2be262007-07-12 11:03:13 +0000226#ifdef MS_WINDOWS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000227 Py_UNICODE *widename = NULL;
Steve Dowereacee982017-02-04 14:38:11 -0800228#else
229 const char *name = NULL;
Thomas Helleraf2be262007-07-12 11:03:13 +0000230#endif
Steve Dowereacee982017-02-04 14:38:11 -0800231 PyObject *stringobj = NULL;
232 const char *s;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000233 int ret = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200234 int rwa = 0, plus = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000235 int flags = 0;
236 int fd = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200237 int fd_is_own = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200238#ifdef O_CLOEXEC
239 int *atomic_flag_works = &_Py_open_cloexec_works;
240#elif !defined(MS_WINDOWS)
241 int *atomic_flag_works = NULL;
242#endif
Steve Dowerf2f373f2015-02-21 08:44:05 -0800243 struct _Py_stat_struct fdfstat;
Martin Panter0bb62b12015-12-06 03:15:05 +0000244 int fstat_result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000245 int async_err = 0;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000246
Christian Heimes82adeff2015-04-16 17:21:54 +0200247 assert(PyFileIO_Check(self));
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000248 if (self->fd >= 0) {
Hynek Schlawack2cc71562012-05-25 10:05:53 +0200249 if (self->closefd) {
250 /* Have to close the existing file first. */
251 if (internal_close(self) < 0)
252 return -1;
253 }
254 else
255 self->fd = -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000256 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000257
Serhiy Storchaka78980432013-01-15 01:12:17 +0200258 fd = _PyLong_AsInt(nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000259 if (fd < 0) {
260 if (!PyErr_Occurred()) {
261 PyErr_SetString(PyExc_ValueError,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +0300262 "negative file descriptor");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000263 return -1;
264 }
265 PyErr_Clear();
266 }
Guido van Rossumb0428152007-04-08 17:44:42 +0000267
Steve Dowereacee982017-02-04 14:38:11 -0800268 if (fd < 0) {
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000269#ifdef MS_WINDOWS
Steve Dowereacee982017-02-04 14:38:11 -0800270 if (!PyUnicode_FSDecoder(nameobj, &stringobj)) {
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300271 return -1;
272 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300273 widename = PyUnicode_AsUnicode(stringobj);
Steve Dowereacee982017-02-04 14:38:11 -0800274 if (widename == NULL)
275 return -1;
276#else
Antoine Pitrou13348842012-01-29 18:36:34 +0100277 if (!PyUnicode_FSConverter(nameobj, &stringobj)) {
278 return -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000279 }
Antoine Pitrou13348842012-01-29 18:36:34 +0100280 name = PyBytes_AS_STRING(stringobj);
Steve Dowereacee982017-02-04 14:38:11 -0800281#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000282 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000283
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000284 s = mode;
285 while (*s) {
286 switch (*s++) {
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100287 case 'x':
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000288 if (rwa) {
289 bad_mode:
290 PyErr_SetString(PyExc_ValueError,
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100291 "Must have exactly one of create/read/write/append "
Georg Brandl28928ae2010-10-21 13:45:52 +0000292 "mode and at most one plus");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000293 goto error;
294 }
295 rwa = 1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100296 self->created = 1;
297 self->writable = 1;
298 flags |= O_EXCL | O_CREAT;
299 break;
300 case 'r':
301 if (rwa)
302 goto bad_mode;
303 rwa = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000304 self->readable = 1;
305 break;
306 case 'w':
307 if (rwa)
308 goto bad_mode;
309 rwa = 1;
310 self->writable = 1;
311 flags |= O_CREAT | O_TRUNC;
312 break;
313 case 'a':
314 if (rwa)
315 goto bad_mode;
316 rwa = 1;
317 self->writable = 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200318 self->appending = 1;
319 flags |= O_APPEND | O_CREAT;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000320 break;
321 case 'b':
322 break;
323 case '+':
324 if (plus)
325 goto bad_mode;
326 self->readable = self->writable = 1;
327 plus = 1;
328 break;
329 default:
330 PyErr_Format(PyExc_ValueError,
331 "invalid mode: %.200s", mode);
332 goto error;
333 }
334 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000335
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000336 if (!rwa)
337 goto bad_mode;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000338
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000339 if (self->readable && self->writable)
340 flags |= O_RDWR;
341 else if (self->readable)
342 flags |= O_RDONLY;
343 else
344 flags |= O_WRONLY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000345
346#ifdef O_BINARY
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000347 flags |= O_BINARY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000348#endif
349
Victor Stinnerdaf45552013-08-28 00:53:59 +0200350#ifdef MS_WINDOWS
351 flags |= O_NOINHERIT;
352#elif defined(O_CLOEXEC)
353 flags |= O_CLOEXEC;
354#endif
Walter Dörwald0e411482007-06-06 16:55:38 +0000355
Steve Dowerb82e17e2019-05-23 08:45:22 -0700356 if (PySys_Audit("open", "Osi", nameobj, mode, flags) < 0) {
357 goto error;
358 }
359
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000360 if (fd >= 0) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000361 self->fd = fd;
362 self->closefd = closefd;
363 }
364 else {
365 self->closefd = 1;
366 if (!closefd) {
367 PyErr_SetString(PyExc_ValueError,
368 "Cannot use closefd=False with file name");
369 goto error;
370 }
Guido van Rossum2dced8b2007-10-30 17:27:30 +0000371
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000372 errno = 0;
Ross Lagerwall59142db2011-10-31 20:34:46 +0200373 if (opener == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000374 do {
375 Py_BEGIN_ALLOW_THREADS
Thomas Helleraf2be262007-07-12 11:03:13 +0000376#ifdef MS_WINDOWS
Steve Dowereacee982017-02-04 14:38:11 -0800377 self->fd = _wopen(widename, flags, 0666);
378#else
379 self->fd = open(name, flags, 0666);
Thomas Helleraf2be262007-07-12 11:03:13 +0000380#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000381 Py_END_ALLOW_THREADS
382 } while (self->fd < 0 && errno == EINTR &&
383 !(async_err = PyErr_CheckSignals()));
Victor Stinner9672da72015-03-04 18:40:10 +0100384
385 if (async_err)
386 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200387 }
388 else {
389 PyObject *fdobj;
390
391#ifndef MS_WINDOWS
392 /* the opener may clear the atomic flag */
393 atomic_flag_works = NULL;
394#endif
395
396 fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200397 if (fdobj == NULL)
398 goto error;
399 if (!PyLong_Check(fdobj)) {
400 Py_DECREF(fdobj);
401 PyErr_SetString(PyExc_TypeError,
402 "expected integer from opener");
403 goto error;
404 }
405
Serhiy Storchaka78980432013-01-15 01:12:17 +0200406 self->fd = _PyLong_AsInt(fdobj);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200407 Py_DECREF(fdobj);
Barry Warsaw480e2852016-06-08 17:47:26 -0400408 if (self->fd < 0) {
409 if (!PyErr_Occurred()) {
Barry Warsaw118598a2016-06-08 17:54:43 -0400410 /* The opener returned a negative but didn't set an
411 exception. See issue #27066 */
Barry Warsaw480e2852016-06-08 17:47:26 -0400412 PyErr_Format(PyExc_ValueError,
413 "opener returned %d", self->fd);
414 }
Ross Lagerwall59142db2011-10-31 20:34:46 +0200415 goto error;
416 }
417 }
418
Hynek Schlawack7f59fd72012-06-22 09:32:22 +0200419 fd_is_own = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000420 if (self->fd < 0) {
Victor Stinner9672da72015-03-04 18:40:10 +0100421 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000422 goto error;
423 }
Victor Stinnerdaf45552013-08-28 00:53:59 +0200424
425#ifndef MS_WINDOWS
426 if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0)
427 goto error;
428#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000429 }
Antoine Pitroude687222014-06-29 20:07:28 -0400430
431 self->blksize = DEFAULT_BUFFER_SIZE;
Martin Panter0bb62b12015-12-06 03:15:05 +0000432 Py_BEGIN_ALLOW_THREADS
433 fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
434 Py_END_ALLOW_THREADS
435 if (fstat_result < 0) {
Martin Panter49d3db92015-12-06 11:12:15 +0000436 /* Tolerate fstat() errors other than EBADF. See Issue #25717, where
437 an anonymous file on a Virtual Box shared folder filesystem would
438 raise ENOENT. */
Martin Panter0bb62b12015-12-06 03:15:05 +0000439#ifdef MS_WINDOWS
440 if (GetLastError() == ERROR_INVALID_HANDLE) {
441 PyErr_SetFromWindowsErr(0);
442#else
443 if (errno == EBADF) {
444 PyErr_SetFromErrno(PyExc_OSError);
445#endif
446 goto error;
447 }
Antoine Pitroude687222014-06-29 20:07:28 -0400448 }
Martin Panter0bb62b12015-12-06 03:15:05 +0000449 else {
450#if defined(S_ISDIR) && defined(EISDIR)
451 /* On Unix, open will succeed for directories.
452 In Python, there should be no file objects referring to
453 directories, so we need a check. */
454 if (S_ISDIR(fdfstat.st_mode)) {
455 errno = EISDIR;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300456 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Martin Panter0bb62b12015-12-06 03:15:05 +0000457 goto error;
458 }
Antoine Pitroude687222014-06-29 20:07:28 -0400459#endif /* defined(S_ISDIR) */
460#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin Panter0bb62b12015-12-06 03:15:05 +0000461 if (fdfstat.st_blksize > 1)
462 self->blksize = fdfstat.st_blksize;
Antoine Pitroude687222014-06-29 20:07:28 -0400463#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
Martin Panter0bb62b12015-12-06 03:15:05 +0000464 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000465
Victor Stinner89e34362011-01-07 18:47:22 +0000466#if defined(MS_WINDOWS) || defined(__CYGWIN__)
467 /* don't translate newlines (\r\n <=> \n) */
468 _setmode(self->fd, O_BINARY);
469#endif
470
Victor Stinnerd9d04192013-11-06 23:50:10 +0100471 if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000472 goto error;
Antoine Pitrou08838b62009-01-21 00:55:13 +0000473
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200474 if (self->appending) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000475 /* For consistent behaviour, we explicitly seek to the
476 end of file (otherwise, it might be done only on the
477 first write()). */
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800478 PyObject *pos = portable_lseek(self, NULL, 2, true);
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200479 if (pos == NULL)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000480 goto error;
481 Py_DECREF(pos);
482 }
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000483
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000484 goto done;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000485
486 error:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000487 ret = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200488 if (!fd_is_own)
489 self->fd = -1;
Benjamin Petersonbbb04122010-10-30 23:16:28 +0000490 if (self->fd >= 0)
491 internal_close(self);
Guido van Rossum53807da2007-04-10 19:01:47 +0000492
Guido van Rossuma9e20242007-03-08 00:43:48 +0000493 done:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000494 Py_CLEAR(stringobj);
495 return ret;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000496}
497
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000498static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000499fileio_traverse(fileio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000500{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000501 Py_VISIT(self->dict);
502 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000503}
504
505static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000506fileio_clear(fileio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000507{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000508 Py_CLEAR(self->dict);
509 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000510}
511
Guido van Rossuma9e20242007-03-08 00:43:48 +0000512static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000513fileio_dealloc(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000514{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200515 self->finalizing = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000516 if (_PyIOBase_finalize((PyObject *) self) < 0)
517 return;
518 _PyObject_GC_UNTRACK(self);
519 if (self->weakreflist != NULL)
520 PyObject_ClearWeakRefs((PyObject *) self);
521 Py_CLEAR(self->dict);
522 Py_TYPE(self)->tp_free((PyObject *)self);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000523}
524
525static PyObject *
526err_closed(void)
527{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000528 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
529 return NULL;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000530}
531
532static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200533err_mode(const char *action)
Guido van Rossum53807da2007-04-10 19:01:47 +0000534{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100535 _PyIO_State *state = IO_STATE();
536 if (state != NULL)
537 PyErr_Format(state->unsupported_operation,
538 "File not open for %s", action);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000539 return NULL;
Guido van Rossum53807da2007-04-10 19:01:47 +0000540}
541
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300542/*[clinic input]
543_io.FileIO.fileno
544
545Return the underlying file descriptor (an integer).
546[clinic start generated code]*/
547
Guido van Rossum53807da2007-04-10 19:01:47 +0000548static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300549_io_FileIO_fileno_impl(fileio *self)
550/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000551{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000552 if (self->fd < 0)
553 return err_closed();
554 return PyLong_FromLong((long) self->fd);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000555}
556
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300557/*[clinic input]
558_io.FileIO.readable
559
560True if file was opened in a read mode.
561[clinic start generated code]*/
562
Guido van Rossuma9e20242007-03-08 00:43:48 +0000563static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300564_io_FileIO_readable_impl(fileio *self)
565/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000566{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000567 if (self->fd < 0)
568 return err_closed();
569 return PyBool_FromLong((long) self->readable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000570}
571
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300572/*[clinic input]
573_io.FileIO.writable
574
575True if file was opened in a write mode.
576[clinic start generated code]*/
577
Guido van Rossuma9e20242007-03-08 00:43:48 +0000578static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300579_io_FileIO_writable_impl(fileio *self)
580/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000581{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000582 if (self->fd < 0)
583 return err_closed();
584 return PyBool_FromLong((long) self->writable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000585}
586
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300587/*[clinic input]
588_io.FileIO.seekable
589
590True if file supports random-access.
591[clinic start generated code]*/
592
Guido van Rossuma9e20242007-03-08 00:43:48 +0000593static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300594_io_FileIO_seekable_impl(fileio *self)
595/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000596{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000597 if (self->fd < 0)
598 return err_closed();
599 if (self->seekable < 0) {
Victor Stinner99970732017-05-02 15:10:39 +0200600 /* portable_lseek() sets the seekable attribute */
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800601 PyObject *pos = portable_lseek(self, NULL, SEEK_CUR, false);
Victor Stinner99970732017-05-02 15:10:39 +0200602 assert(self->seekable >= 0);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000603 if (pos == NULL) {
604 PyErr_Clear();
Victor Stinner99970732017-05-02 15:10:39 +0200605 }
606 else {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000607 Py_DECREF(pos);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000608 }
609 }
610 return PyBool_FromLong((long) self->seekable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000611}
612
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300613/*[clinic input]
614_io.FileIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700615 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300616 /
617
618Same as RawIOBase.readinto().
619[clinic start generated code]*/
620
Guido van Rossuma9e20242007-03-08 00:43:48 +0000621static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300622_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700623/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000624{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100625 Py_ssize_t n;
626 int err;
Guido van Rossum53807da2007-04-10 19:01:47 +0000627
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000628 if (self->fd < 0)
629 return err_closed();
630 if (!self->readable)
631 return err_mode("reading");
Guido van Rossum53807da2007-04-10 19:01:47 +0000632
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300633 n = _Py_read(self->fd, buffer->buf, buffer->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100634 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100635 err = errno;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100636
637 if (n == -1) {
638 if (err == EAGAIN) {
639 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000640 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100641 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000642 return NULL;
643 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000644
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000645 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000646}
647
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648static size_t
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100649new_buffersize(fileio *self, size_t currentsize)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000650{
Antoine Pitroua3f44572012-04-17 13:50:58 +0200651 size_t addend;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100652
Nadeem Vawdad41a98b2011-10-13 13:34:16 +0200653 /* Expand the buffer by an amount proportional to the current size,
Antoine Pitroua3f44572012-04-17 13:50:58 +0200654 giving us amortized linear-time behavior. For bigger sizes, use a
655 less-than-double growth factor to avoid excessive allocation. */
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100656 assert(currentsize <= PY_SSIZE_T_MAX);
Antoine Pitroua3f44572012-04-17 13:50:58 +0200657 if (currentsize > 65536)
658 addend = currentsize >> 3;
659 else
660 addend = 256 + currentsize;
661 if (addend < SMALLCHUNK)
662 /* Avoid tiny read() calls. */
663 addend = SMALLCHUNK;
664 return addend + currentsize;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000665}
666
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300667/*[clinic input]
668_io.FileIO.readall
669
670Read all data from the file, returned as bytes.
671
672In non-blocking mode, returns as much as is immediately available,
673or None if no data is available. Return an empty bytes object at EOF.
674[clinic start generated code]*/
675
Guido van Rossum7165cb12007-07-10 06:54:34 +0000676static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300677_io_FileIO_readall_impl(fileio *self)
678/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/
Guido van Rossum7165cb12007-07-10 06:54:34 +0000679{
Victor Stinnere134a7f2015-03-30 10:09:31 +0200680 struct _Py_stat_struct status;
Victor Stinnera2a64772011-10-11 22:45:02 +0200681 Py_off_t pos, end;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000682 PyObject *result;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100683 Py_ssize_t bytes_read = 0;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100684 Py_ssize_t n;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100685 size_t bufsize;
Nir Soffer6a894812017-12-01 03:18:58 +0200686 int fstat_result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000687
Victor Stinnerb79f28c2011-05-25 22:09:03 +0200688 if (self->fd < 0)
689 return err_closed();
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000690
Nir Soffer6a894812017-12-01 03:18:58 +0200691 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400692 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200693#ifdef MS_WINDOWS
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200694 pos = _lseeki64(self->fd, 0L, SEEK_CUR);
695#else
696 pos = lseek(self->fd, 0L, SEEK_CUR);
697#endif
Steve Dower8fc89802015-04-12 00:26:27 -0400698 _Py_END_SUPPRESS_IPH
Nir Soffer6a894812017-12-01 03:18:58 +0200699 fstat_result = _Py_fstat_noraise(self->fd, &status);
700 Py_END_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400701
Nir Soffer6a894812017-12-01 03:18:58 +0200702 if (fstat_result == 0)
Victor Stinnere134a7f2015-03-30 10:09:31 +0200703 end = status.st_size;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200704 else
Victor Stinnera2a64772011-10-11 22:45:02 +0200705 end = (Py_off_t)-1;
Christian Heimesa872de52008-12-05 08:26:55 +0000706
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100707 if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) {
708 /* This is probably a real file, so we try to allocate a
709 buffer one byte larger than the rest of the file. If the
710 calculation is right then we should get EOF without having
711 to enlarge the buffer. */
712 bufsize = (size_t)(end - pos + 1);
713 } else {
714 bufsize = SMALLCHUNK;
715 }
716
717 result = PyBytes_FromStringAndSize(NULL, bufsize);
718 if (result == NULL)
719 return NULL;
720
721 while (1) {
722 if (bytes_read >= (Py_ssize_t)bufsize) {
723 bufsize = new_buffersize(self, bytes_read);
724 if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) {
725 PyErr_SetString(PyExc_OverflowError,
726 "unbounded read returned more bytes "
Serhiy Storchakab817b772015-04-10 02:18:44 +0300727 "than a Python bytes object can hold");
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100728 Py_DECREF(result);
729 return NULL;
730 }
731
732 if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) {
733 if (_PyBytes_Resize(&result, bufsize) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000734 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000735 }
736 }
Victor Stinner9672da72015-03-04 18:40:10 +0100737
Victor Stinner66aab0c2015-03-19 22:53:20 +0100738 n = _Py_read(self->fd,
739 PyBytes_AS_STRING(result) + bytes_read,
740 bufsize - bytes_read);
Victor Stinner9672da72015-03-04 18:40:10 +0100741
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000742 if (n == 0)
743 break;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100744 if (n == -1) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000745 if (errno == EAGAIN) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100746 PyErr_Clear();
Victor Stinnere10920f2014-07-02 22:59:31 +0200747 if (bytes_read > 0)
748 break;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000749 Py_DECREF(result);
750 Py_RETURN_NONE;
751 }
752 Py_DECREF(result);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000753 return NULL;
754 }
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100755 bytes_read += n;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200756 pos += n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000757 }
Guido van Rossum7165cb12007-07-10 06:54:34 +0000758
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100759 if (PyBytes_GET_SIZE(result) > bytes_read) {
760 if (_PyBytes_Resize(&result, bytes_read) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000761 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000762 }
763 return result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000764}
765
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300766/*[clinic input]
767_io.FileIO.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300768 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300769 /
770
771Read at most size bytes, returned as bytes.
772
773Only makes one system call, so less data may be returned than requested.
774In non-blocking mode, returns None if no data is available.
775Return an empty bytes object at EOF.
776[clinic start generated code]*/
777
Guido van Rossuma9e20242007-03-08 00:43:48 +0000778static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300779_io_FileIO_read_impl(fileio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300780/*[clinic end generated code: output=42528d39dd0ca641 input=bec9a2c704ddcbc9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000781{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000782 char *ptr;
783 Py_ssize_t n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000784 PyObject *bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000785
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000786 if (self->fd < 0)
787 return err_closed();
788 if (!self->readable)
789 return err_mode("reading");
Guido van Rossuma9e20242007-03-08 00:43:48 +0000790
Victor Stinner66aab0c2015-03-19 22:53:20 +0100791 if (size < 0)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300792 return _io_FileIO_readall_impl(self);
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000793
Stéphane Wirtel74a8b6e2018-10-18 01:05:04 +0200794 if (size > _PY_READ_MAX) {
795 size = _PY_READ_MAX;
796 }
Victor Stinner66aab0c2015-03-19 22:53:20 +0100797
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000798 bytes = PyBytes_FromStringAndSize(NULL, size);
799 if (bytes == NULL)
800 return NULL;
801 ptr = PyBytes_AS_STRING(bytes);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000802
Victor Stinner66aab0c2015-03-19 22:53:20 +0100803 n = _Py_read(self->fd, ptr, size);
804 if (n == -1) {
805 /* copy errno because Py_DECREF() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100806 int err = errno;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000807 Py_DECREF(bytes);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100808 if (err == EAGAIN) {
809 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000810 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100811 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000812 return NULL;
813 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000814
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000815 if (n != size) {
816 if (_PyBytes_Resize(&bytes, n) < 0) {
Victor Stinner85c761d2013-07-16 21:36:02 +0200817 Py_CLEAR(bytes);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000818 return NULL;
819 }
820 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000821
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000822 return (PyObject *) bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000823}
824
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300825/*[clinic input]
826_io.FileIO.write
827 b: Py_buffer
828 /
829
Martin Panter6bb91f32016-05-28 00:41:57 +0000830Write buffer b to file, return number of bytes written.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300831
832Only makes one system call, so not all of the data may be written.
833The number of bytes actually written is returned. In non-blocking mode,
834returns None if the write would block.
835[clinic start generated code]*/
836
Guido van Rossuma9e20242007-03-08 00:43:48 +0000837static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300838_io_FileIO_write_impl(fileio *self, Py_buffer *b)
Martin Panter6bb91f32016-05-28 00:41:57 +0000839/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000840{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100841 Py_ssize_t n;
842 int err;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000843
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000844 if (self->fd < 0)
845 return err_closed();
846 if (!self->writable)
847 return err_mode("writing");
Guido van Rossum53807da2007-04-10 19:01:47 +0000848
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300849 n = _Py_write(self->fd, b->buf, b->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100850 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100851 err = errno;
Martin v. Löwis423be952008-08-13 15:53:07 +0000852
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000853 if (n < 0) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100854 if (err == EAGAIN) {
855 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000856 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100857 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000858 return NULL;
859 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000860
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000861 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000862}
863
Guido van Rossum53807da2007-04-10 19:01:47 +0000864/* XXX Windows support below is likely incomplete */
865
Guido van Rossum53807da2007-04-10 19:01:47 +0000866/* Cribbed from posix_lseek() */
867static PyObject *
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800868portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error)
Guido van Rossum53807da2007-04-10 19:01:47 +0000869{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000870 Py_off_t pos, res;
Victor Stinner99970732017-05-02 15:10:39 +0200871 int fd = self->fd;
Guido van Rossum53807da2007-04-10 19:01:47 +0000872
873#ifdef SEEK_SET
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000874 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
875 switch (whence) {
Guido van Rossum53807da2007-04-10 19:01:47 +0000876#if SEEK_SET != 0
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000877 case 0: whence = SEEK_SET; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000878#endif
879#if SEEK_CUR != 1
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000880 case 1: whence = SEEK_CUR; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000881#endif
Antoine Pitrou4f7945f2009-01-20 11:42:11 +0000882#if SEEK_END != 2
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000883 case 2: whence = SEEK_END; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000884#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000885 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000886#endif /* SEEK_SET */
887
Victor Stinner99970732017-05-02 15:10:39 +0200888 if (posobj == NULL) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000889 pos = 0;
Victor Stinner99970732017-05-02 15:10:39 +0200890 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000891 else {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000892#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000893 pos = PyLong_AsLongLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000894#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000895 pos = PyLong_AsLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000896#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000897 if (PyErr_Occurred())
898 return NULL;
899 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000900
Steve Dower940f33a2016-09-08 11:21:54 -0700901 Py_BEGIN_ALLOW_THREADS
902 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200903#ifdef MS_WINDOWS
Steve Dower940f33a2016-09-08 11:21:54 -0700904 res = _lseeki64(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000905#else
Steve Dower940f33a2016-09-08 11:21:54 -0700906 res = lseek(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000907#endif
Steve Dower940f33a2016-09-08 11:21:54 -0700908 _Py_END_SUPPRESS_IPH
909 Py_END_ALLOW_THREADS
Victor Stinner99970732017-05-02 15:10:39 +0200910
911 if (self->seekable < 0) {
912 self->seekable = (res >= 0);
913 }
914
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800915 if (res < 0) {
916 if (suppress_pipe_error && errno == ESPIPE) {
917 res = 0;
918 } else {
919 return PyErr_SetFromErrno(PyExc_OSError);
920 }
921 }
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
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800954 return portable_lseek(self, pos, whence, false);
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
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800972 return portable_lseek(self, NULL, 1, false);
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
Serhiy Storchaka279f4462019-09-14 12:24:05 +0300978 size as posobj: object = None
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300979 /
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)
Serhiy Storchaka279f4462019-09-14 12:24:05 +0300989/*[clinic end generated code: output=e49ca7a916c176fa input=b0ac133939823875]*/
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
Serhiy Storchaka279f4462019-09-14 12:24:05 +03001001 if (posobj == Py_None) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001002 /* Get the current position. */
Benjamin Peterson74fa9f72019-11-12 14:51:34 -08001003 posobj = portable_lseek(self, NULL, 1, false);
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 */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001184 0, /* tp_vectorcall_offset */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001185 0, /* tp_getattr */
1186 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001187 0, /* tp_as_async */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001188 (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 Pitrouada319b2019-05-29 22:12:38 +02001199 | Py_TPFLAGS_HAVE_GC, /* 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 */
Antoine Pitrouada319b2019-05-29 22:12:38 +02001204 offsetof(fileio, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001205 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 */
Antoine Pitrouada319b2019-05-29 22:12:38 +02001214 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};