blob: b9856b3b63165709384f7ce68c145ceac8de1f83 [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 Storchaka4c8f09d2020-07-10 23:26:06 +0300273#if USE_UNICODE_WCHAR_CACHE
274_Py_COMP_DIAG_PUSH
275_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300276 widename = PyUnicode_AsUnicode(stringobj);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +0300277_Py_COMP_DIAG_POP
278#else /* USE_UNICODE_WCHAR_CACHE */
279 widename = PyUnicode_AsWideCharString(stringobj, NULL);
280#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowereacee982017-02-04 14:38:11 -0800281 if (widename == NULL)
282 return -1;
283#else
Antoine Pitrou13348842012-01-29 18:36:34 +0100284 if (!PyUnicode_FSConverter(nameobj, &stringobj)) {
285 return -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000286 }
Antoine Pitrou13348842012-01-29 18:36:34 +0100287 name = PyBytes_AS_STRING(stringobj);
Steve Dowereacee982017-02-04 14:38:11 -0800288#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000289 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000290
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000291 s = mode;
292 while (*s) {
293 switch (*s++) {
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100294 case 'x':
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000295 if (rwa) {
296 bad_mode:
297 PyErr_SetString(PyExc_ValueError,
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100298 "Must have exactly one of create/read/write/append "
Georg Brandl28928ae2010-10-21 13:45:52 +0000299 "mode and at most one plus");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000300 goto error;
301 }
302 rwa = 1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100303 self->created = 1;
304 self->writable = 1;
305 flags |= O_EXCL | O_CREAT;
306 break;
307 case 'r':
308 if (rwa)
309 goto bad_mode;
310 rwa = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000311 self->readable = 1;
312 break;
313 case 'w':
314 if (rwa)
315 goto bad_mode;
316 rwa = 1;
317 self->writable = 1;
318 flags |= O_CREAT | O_TRUNC;
319 break;
320 case 'a':
321 if (rwa)
322 goto bad_mode;
323 rwa = 1;
324 self->writable = 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200325 self->appending = 1;
326 flags |= O_APPEND | O_CREAT;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000327 break;
328 case 'b':
329 break;
330 case '+':
331 if (plus)
332 goto bad_mode;
333 self->readable = self->writable = 1;
334 plus = 1;
335 break;
336 default:
337 PyErr_Format(PyExc_ValueError,
338 "invalid mode: %.200s", mode);
339 goto error;
340 }
341 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000342
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000343 if (!rwa)
344 goto bad_mode;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000345
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000346 if (self->readable && self->writable)
347 flags |= O_RDWR;
348 else if (self->readable)
349 flags |= O_RDONLY;
350 else
351 flags |= O_WRONLY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000352
353#ifdef O_BINARY
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000354 flags |= O_BINARY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000355#endif
356
Victor Stinnerdaf45552013-08-28 00:53:59 +0200357#ifdef MS_WINDOWS
358 flags |= O_NOINHERIT;
359#elif defined(O_CLOEXEC)
360 flags |= O_CLOEXEC;
361#endif
Walter Dörwald0e411482007-06-06 16:55:38 +0000362
Steve Dowerb82e17e2019-05-23 08:45:22 -0700363 if (PySys_Audit("open", "Osi", nameobj, mode, flags) < 0) {
364 goto error;
365 }
366
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000367 if (fd >= 0) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000368 self->fd = fd;
369 self->closefd = closefd;
370 }
371 else {
372 self->closefd = 1;
373 if (!closefd) {
374 PyErr_SetString(PyExc_ValueError,
375 "Cannot use closefd=False with file name");
376 goto error;
377 }
Guido van Rossum2dced8b2007-10-30 17:27:30 +0000378
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000379 errno = 0;
Ross Lagerwall59142db2011-10-31 20:34:46 +0200380 if (opener == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000381 do {
382 Py_BEGIN_ALLOW_THREADS
Thomas Helleraf2be262007-07-12 11:03:13 +0000383#ifdef MS_WINDOWS
Steve Dowereacee982017-02-04 14:38:11 -0800384 self->fd = _wopen(widename, flags, 0666);
385#else
386 self->fd = open(name, flags, 0666);
Thomas Helleraf2be262007-07-12 11:03:13 +0000387#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000388 Py_END_ALLOW_THREADS
389 } while (self->fd < 0 && errno == EINTR &&
390 !(async_err = PyErr_CheckSignals()));
Victor Stinner9672da72015-03-04 18:40:10 +0100391
392 if (async_err)
393 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200394 }
395 else {
396 PyObject *fdobj;
397
398#ifndef MS_WINDOWS
399 /* the opener may clear the atomic flag */
400 atomic_flag_works = NULL;
401#endif
402
403 fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200404 if (fdobj == NULL)
405 goto error;
406 if (!PyLong_Check(fdobj)) {
407 Py_DECREF(fdobj);
408 PyErr_SetString(PyExc_TypeError,
409 "expected integer from opener");
410 goto error;
411 }
412
Serhiy Storchaka78980432013-01-15 01:12:17 +0200413 self->fd = _PyLong_AsInt(fdobj);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200414 Py_DECREF(fdobj);
Barry Warsaw480e2852016-06-08 17:47:26 -0400415 if (self->fd < 0) {
416 if (!PyErr_Occurred()) {
Barry Warsaw118598a2016-06-08 17:54:43 -0400417 /* The opener returned a negative but didn't set an
418 exception. See issue #27066 */
Barry Warsaw480e2852016-06-08 17:47:26 -0400419 PyErr_Format(PyExc_ValueError,
420 "opener returned %d", self->fd);
421 }
Ross Lagerwall59142db2011-10-31 20:34:46 +0200422 goto error;
423 }
424 }
425
Hynek Schlawack7f59fd72012-06-22 09:32:22 +0200426 fd_is_own = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000427 if (self->fd < 0) {
Victor Stinner9672da72015-03-04 18:40:10 +0100428 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000429 goto error;
430 }
Victor Stinnerdaf45552013-08-28 00:53:59 +0200431
432#ifndef MS_WINDOWS
433 if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0)
434 goto error;
435#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000436 }
Antoine Pitroude687222014-06-29 20:07:28 -0400437
438 self->blksize = DEFAULT_BUFFER_SIZE;
Martin Panter0bb62b12015-12-06 03:15:05 +0000439 Py_BEGIN_ALLOW_THREADS
440 fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
441 Py_END_ALLOW_THREADS
442 if (fstat_result < 0) {
Martin Panter49d3db92015-12-06 11:12:15 +0000443 /* Tolerate fstat() errors other than EBADF. See Issue #25717, where
444 an anonymous file on a Virtual Box shared folder filesystem would
445 raise ENOENT. */
Martin Panter0bb62b12015-12-06 03:15:05 +0000446#ifdef MS_WINDOWS
447 if (GetLastError() == ERROR_INVALID_HANDLE) {
448 PyErr_SetFromWindowsErr(0);
449#else
450 if (errno == EBADF) {
451 PyErr_SetFromErrno(PyExc_OSError);
452#endif
453 goto error;
454 }
Antoine Pitroude687222014-06-29 20:07:28 -0400455 }
Martin Panter0bb62b12015-12-06 03:15:05 +0000456 else {
457#if defined(S_ISDIR) && defined(EISDIR)
458 /* On Unix, open will succeed for directories.
459 In Python, there should be no file objects referring to
460 directories, so we need a check. */
461 if (S_ISDIR(fdfstat.st_mode)) {
462 errno = EISDIR;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300463 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Martin Panter0bb62b12015-12-06 03:15:05 +0000464 goto error;
465 }
Antoine Pitroude687222014-06-29 20:07:28 -0400466#endif /* defined(S_ISDIR) */
467#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin Panter0bb62b12015-12-06 03:15:05 +0000468 if (fdfstat.st_blksize > 1)
469 self->blksize = fdfstat.st_blksize;
Antoine Pitroude687222014-06-29 20:07:28 -0400470#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
Martin Panter0bb62b12015-12-06 03:15:05 +0000471 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000472
Victor Stinner89e34362011-01-07 18:47:22 +0000473#if defined(MS_WINDOWS) || defined(__CYGWIN__)
474 /* don't translate newlines (\r\n <=> \n) */
475 _setmode(self->fd, O_BINARY);
476#endif
477
Victor Stinnerd9d04192013-11-06 23:50:10 +0100478 if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000479 goto error;
Antoine Pitrou08838b62009-01-21 00:55:13 +0000480
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200481 if (self->appending) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000482 /* For consistent behaviour, we explicitly seek to the
483 end of file (otherwise, it might be done only on the
484 first write()). */
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800485 PyObject *pos = portable_lseek(self, NULL, 2, true);
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200486 if (pos == NULL)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000487 goto error;
488 Py_DECREF(pos);
489 }
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000490
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000491 goto done;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000492
493 error:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000494 ret = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200495 if (!fd_is_own)
496 self->fd = -1;
Benjamin Petersonbbb04122010-10-30 23:16:28 +0000497 if (self->fd >= 0)
498 internal_close(self);
Guido van Rossum53807da2007-04-10 19:01:47 +0000499
Guido van Rossuma9e20242007-03-08 00:43:48 +0000500 done:
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +0300501#ifdef MS_WINDOWS
502#if !USE_UNICODE_WCHAR_CACHE
503 PyMem_Free(widename);
504#endif /* USE_UNICODE_WCHAR_CACHE */
505#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000506 Py_CLEAR(stringobj);
507 return ret;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000508}
509
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000510static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000511fileio_traverse(fileio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000512{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000513 Py_VISIT(self->dict);
514 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000515}
516
517static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000518fileio_clear(fileio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000519{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000520 Py_CLEAR(self->dict);
521 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000522}
523
Guido van Rossuma9e20242007-03-08 00:43:48 +0000524static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000525fileio_dealloc(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000526{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200527 self->finalizing = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000528 if (_PyIOBase_finalize((PyObject *) self) < 0)
529 return;
530 _PyObject_GC_UNTRACK(self);
531 if (self->weakreflist != NULL)
532 PyObject_ClearWeakRefs((PyObject *) self);
533 Py_CLEAR(self->dict);
534 Py_TYPE(self)->tp_free((PyObject *)self);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000535}
536
537static PyObject *
538err_closed(void)
539{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000540 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
541 return NULL;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000542}
543
544static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200545err_mode(const char *action)
Guido van Rossum53807da2007-04-10 19:01:47 +0000546{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100547 _PyIO_State *state = IO_STATE();
548 if (state != NULL)
549 PyErr_Format(state->unsupported_operation,
550 "File not open for %s", action);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000551 return NULL;
Guido van Rossum53807da2007-04-10 19:01:47 +0000552}
553
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300554/*[clinic input]
555_io.FileIO.fileno
556
557Return the underlying file descriptor (an integer).
558[clinic start generated code]*/
559
Guido van Rossum53807da2007-04-10 19:01:47 +0000560static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300561_io_FileIO_fileno_impl(fileio *self)
562/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000563{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000564 if (self->fd < 0)
565 return err_closed();
566 return PyLong_FromLong((long) self->fd);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000567}
568
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300569/*[clinic input]
570_io.FileIO.readable
571
572True if file was opened in a read mode.
573[clinic start generated code]*/
574
Guido van Rossuma9e20242007-03-08 00:43:48 +0000575static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300576_io_FileIO_readable_impl(fileio *self)
577/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000578{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000579 if (self->fd < 0)
580 return err_closed();
581 return PyBool_FromLong((long) self->readable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000582}
583
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300584/*[clinic input]
585_io.FileIO.writable
586
587True if file was opened in a write mode.
588[clinic start generated code]*/
589
Guido van Rossuma9e20242007-03-08 00:43:48 +0000590static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300591_io_FileIO_writable_impl(fileio *self)
592/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000593{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000594 if (self->fd < 0)
595 return err_closed();
596 return PyBool_FromLong((long) self->writable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000597}
598
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300599/*[clinic input]
600_io.FileIO.seekable
601
602True if file supports random-access.
603[clinic start generated code]*/
604
Guido van Rossuma9e20242007-03-08 00:43:48 +0000605static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300606_io_FileIO_seekable_impl(fileio *self)
607/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000608{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000609 if (self->fd < 0)
610 return err_closed();
611 if (self->seekable < 0) {
Victor Stinner99970732017-05-02 15:10:39 +0200612 /* portable_lseek() sets the seekable attribute */
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800613 PyObject *pos = portable_lseek(self, NULL, SEEK_CUR, false);
Victor Stinner99970732017-05-02 15:10:39 +0200614 assert(self->seekable >= 0);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000615 if (pos == NULL) {
616 PyErr_Clear();
Victor Stinner99970732017-05-02 15:10:39 +0200617 }
618 else {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000619 Py_DECREF(pos);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000620 }
621 }
622 return PyBool_FromLong((long) self->seekable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000623}
624
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300625/*[clinic input]
626_io.FileIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700627 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300628 /
629
630Same as RawIOBase.readinto().
631[clinic start generated code]*/
632
Guido van Rossuma9e20242007-03-08 00:43:48 +0000633static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300634_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700635/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000636{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100637 Py_ssize_t n;
638 int err;
Guido van Rossum53807da2007-04-10 19:01:47 +0000639
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000640 if (self->fd < 0)
641 return err_closed();
642 if (!self->readable)
643 return err_mode("reading");
Guido van Rossum53807da2007-04-10 19:01:47 +0000644
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300645 n = _Py_read(self->fd, buffer->buf, buffer->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100646 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100647 err = errno;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100648
649 if (n == -1) {
650 if (err == EAGAIN) {
651 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000652 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100653 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000654 return NULL;
655 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000656
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000657 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000658}
659
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000660static size_t
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100661new_buffersize(fileio *self, size_t currentsize)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000662{
Antoine Pitroua3f44572012-04-17 13:50:58 +0200663 size_t addend;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100664
Nadeem Vawdad41a98b2011-10-13 13:34:16 +0200665 /* Expand the buffer by an amount proportional to the current size,
Antoine Pitroua3f44572012-04-17 13:50:58 +0200666 giving us amortized linear-time behavior. For bigger sizes, use a
667 less-than-double growth factor to avoid excessive allocation. */
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100668 assert(currentsize <= PY_SSIZE_T_MAX);
Antoine Pitroua3f44572012-04-17 13:50:58 +0200669 if (currentsize > 65536)
670 addend = currentsize >> 3;
671 else
672 addend = 256 + currentsize;
673 if (addend < SMALLCHUNK)
674 /* Avoid tiny read() calls. */
675 addend = SMALLCHUNK;
676 return addend + currentsize;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000677}
678
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300679/*[clinic input]
680_io.FileIO.readall
681
682Read all data from the file, returned as bytes.
683
684In non-blocking mode, returns as much as is immediately available,
685or None if no data is available. Return an empty bytes object at EOF.
686[clinic start generated code]*/
687
Guido van Rossum7165cb12007-07-10 06:54:34 +0000688static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300689_io_FileIO_readall_impl(fileio *self)
690/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/
Guido van Rossum7165cb12007-07-10 06:54:34 +0000691{
Victor Stinnere134a7f2015-03-30 10:09:31 +0200692 struct _Py_stat_struct status;
Victor Stinnera2a64772011-10-11 22:45:02 +0200693 Py_off_t pos, end;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000694 PyObject *result;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100695 Py_ssize_t bytes_read = 0;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100696 Py_ssize_t n;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100697 size_t bufsize;
Nir Soffer6a894812017-12-01 03:18:58 +0200698 int fstat_result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000699
Victor Stinnerb79f28c2011-05-25 22:09:03 +0200700 if (self->fd < 0)
701 return err_closed();
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000702
Nir Soffer6a894812017-12-01 03:18:58 +0200703 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400704 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200705#ifdef MS_WINDOWS
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200706 pos = _lseeki64(self->fd, 0L, SEEK_CUR);
707#else
708 pos = lseek(self->fd, 0L, SEEK_CUR);
709#endif
Steve Dower8fc89802015-04-12 00:26:27 -0400710 _Py_END_SUPPRESS_IPH
Nir Soffer6a894812017-12-01 03:18:58 +0200711 fstat_result = _Py_fstat_noraise(self->fd, &status);
712 Py_END_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400713
Nir Soffer6a894812017-12-01 03:18:58 +0200714 if (fstat_result == 0)
Victor Stinnere134a7f2015-03-30 10:09:31 +0200715 end = status.st_size;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200716 else
Victor Stinnera2a64772011-10-11 22:45:02 +0200717 end = (Py_off_t)-1;
Christian Heimesa872de52008-12-05 08:26:55 +0000718
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100719 if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) {
720 /* This is probably a real file, so we try to allocate a
721 buffer one byte larger than the rest of the file. If the
722 calculation is right then we should get EOF without having
723 to enlarge the buffer. */
724 bufsize = (size_t)(end - pos + 1);
725 } else {
726 bufsize = SMALLCHUNK;
727 }
728
729 result = PyBytes_FromStringAndSize(NULL, bufsize);
730 if (result == NULL)
731 return NULL;
732
733 while (1) {
734 if (bytes_read >= (Py_ssize_t)bufsize) {
735 bufsize = new_buffersize(self, bytes_read);
736 if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) {
737 PyErr_SetString(PyExc_OverflowError,
738 "unbounded read returned more bytes "
Serhiy Storchakab817b772015-04-10 02:18:44 +0300739 "than a Python bytes object can hold");
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100740 Py_DECREF(result);
741 return NULL;
742 }
743
744 if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) {
745 if (_PyBytes_Resize(&result, bufsize) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000746 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000747 }
748 }
Victor Stinner9672da72015-03-04 18:40:10 +0100749
Victor Stinner66aab0c2015-03-19 22:53:20 +0100750 n = _Py_read(self->fd,
751 PyBytes_AS_STRING(result) + bytes_read,
752 bufsize - bytes_read);
Victor Stinner9672da72015-03-04 18:40:10 +0100753
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000754 if (n == 0)
755 break;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100756 if (n == -1) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000757 if (errno == EAGAIN) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100758 PyErr_Clear();
Victor Stinnere10920f2014-07-02 22:59:31 +0200759 if (bytes_read > 0)
760 break;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000761 Py_DECREF(result);
762 Py_RETURN_NONE;
763 }
764 Py_DECREF(result);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000765 return NULL;
766 }
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100767 bytes_read += n;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200768 pos += n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000769 }
Guido van Rossum7165cb12007-07-10 06:54:34 +0000770
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100771 if (PyBytes_GET_SIZE(result) > bytes_read) {
772 if (_PyBytes_Resize(&result, bytes_read) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000773 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000774 }
775 return result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000776}
777
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300778/*[clinic input]
779_io.FileIO.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300780 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300781 /
782
783Read at most size bytes, returned as bytes.
784
785Only makes one system call, so less data may be returned than requested.
786In non-blocking mode, returns None if no data is available.
787Return an empty bytes object at EOF.
788[clinic start generated code]*/
789
Guido van Rossuma9e20242007-03-08 00:43:48 +0000790static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300791_io_FileIO_read_impl(fileio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300792/*[clinic end generated code: output=42528d39dd0ca641 input=bec9a2c704ddcbc9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000793{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000794 char *ptr;
795 Py_ssize_t n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000796 PyObject *bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000797
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000798 if (self->fd < 0)
799 return err_closed();
800 if (!self->readable)
801 return err_mode("reading");
Guido van Rossuma9e20242007-03-08 00:43:48 +0000802
Victor Stinner66aab0c2015-03-19 22:53:20 +0100803 if (size < 0)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300804 return _io_FileIO_readall_impl(self);
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000805
Stéphane Wirtel74a8b6e2018-10-18 01:05:04 +0200806 if (size > _PY_READ_MAX) {
807 size = _PY_READ_MAX;
808 }
Victor Stinner66aab0c2015-03-19 22:53:20 +0100809
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000810 bytes = PyBytes_FromStringAndSize(NULL, size);
811 if (bytes == NULL)
812 return NULL;
813 ptr = PyBytes_AS_STRING(bytes);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000814
Victor Stinner66aab0c2015-03-19 22:53:20 +0100815 n = _Py_read(self->fd, ptr, size);
816 if (n == -1) {
817 /* copy errno because Py_DECREF() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100818 int err = errno;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000819 Py_DECREF(bytes);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100820 if (err == EAGAIN) {
821 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000822 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100823 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000824 return NULL;
825 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000826
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000827 if (n != size) {
828 if (_PyBytes_Resize(&bytes, n) < 0) {
Victor Stinner85c761d2013-07-16 21:36:02 +0200829 Py_CLEAR(bytes);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000830 return NULL;
831 }
832 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000833
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000834 return (PyObject *) bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000835}
836
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300837/*[clinic input]
838_io.FileIO.write
839 b: Py_buffer
840 /
841
Martin Panter6bb91f32016-05-28 00:41:57 +0000842Write buffer b to file, return number of bytes written.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300843
844Only makes one system call, so not all of the data may be written.
845The number of bytes actually written is returned. In non-blocking mode,
846returns None if the write would block.
847[clinic start generated code]*/
848
Guido van Rossuma9e20242007-03-08 00:43:48 +0000849static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300850_io_FileIO_write_impl(fileio *self, Py_buffer *b)
Martin Panter6bb91f32016-05-28 00:41:57 +0000851/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000852{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100853 Py_ssize_t n;
854 int err;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000855
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000856 if (self->fd < 0)
857 return err_closed();
858 if (!self->writable)
859 return err_mode("writing");
Guido van Rossum53807da2007-04-10 19:01:47 +0000860
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300861 n = _Py_write(self->fd, b->buf, b->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100862 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100863 err = errno;
Martin v. Löwis423be952008-08-13 15:53:07 +0000864
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000865 if (n < 0) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100866 if (err == EAGAIN) {
867 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000868 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100869 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000870 return NULL;
871 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000872
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000873 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000874}
875
Guido van Rossum53807da2007-04-10 19:01:47 +0000876/* XXX Windows support below is likely incomplete */
877
Guido van Rossum53807da2007-04-10 19:01:47 +0000878/* Cribbed from posix_lseek() */
879static PyObject *
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800880portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error)
Guido van Rossum53807da2007-04-10 19:01:47 +0000881{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000882 Py_off_t pos, res;
Victor Stinner99970732017-05-02 15:10:39 +0200883 int fd = self->fd;
Guido van Rossum53807da2007-04-10 19:01:47 +0000884
885#ifdef SEEK_SET
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000886 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
887 switch (whence) {
Guido van Rossum53807da2007-04-10 19:01:47 +0000888#if SEEK_SET != 0
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000889 case 0: whence = SEEK_SET; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000890#endif
891#if SEEK_CUR != 1
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000892 case 1: whence = SEEK_CUR; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000893#endif
Antoine Pitrou4f7945f2009-01-20 11:42:11 +0000894#if SEEK_END != 2
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000895 case 2: whence = SEEK_END; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000896#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000897 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000898#endif /* SEEK_SET */
899
Victor Stinner99970732017-05-02 15:10:39 +0200900 if (posobj == NULL) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000901 pos = 0;
Victor Stinner99970732017-05-02 15:10:39 +0200902 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000903 else {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000904#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000905 pos = PyLong_AsLongLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000906#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000907 pos = PyLong_AsLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000908#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000909 if (PyErr_Occurred())
910 return NULL;
911 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000912
Steve Dower940f33a2016-09-08 11:21:54 -0700913 Py_BEGIN_ALLOW_THREADS
914 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200915#ifdef MS_WINDOWS
Steve Dower940f33a2016-09-08 11:21:54 -0700916 res = _lseeki64(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000917#else
Steve Dower940f33a2016-09-08 11:21:54 -0700918 res = lseek(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000919#endif
Steve Dower940f33a2016-09-08 11:21:54 -0700920 _Py_END_SUPPRESS_IPH
921 Py_END_ALLOW_THREADS
Victor Stinner99970732017-05-02 15:10:39 +0200922
923 if (self->seekable < 0) {
924 self->seekable = (res >= 0);
925 }
926
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800927 if (res < 0) {
928 if (suppress_pipe_error && errno == ESPIPE) {
929 res = 0;
930 } else {
931 return PyErr_SetFromErrno(PyExc_OSError);
932 }
933 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000934
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000935#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000936 return PyLong_FromLongLong(res);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000937#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000938 return PyLong_FromLong(res);
Guido van Rossum53807da2007-04-10 19:01:47 +0000939#endif
940}
941
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300942/*[clinic input]
943_io.FileIO.seek
944 pos: object
945 whence: int = 0
946 /
Guido van Rossuma9e20242007-03-08 00:43:48 +0000947
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300948Move to new file position and return the file position.
949
950Argument offset is a byte count. Optional argument whence defaults to
951SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
952are SEEK_CUR or 1 (move relative to current position, positive or negative),
953and SEEK_END or 2 (move relative to end of file, usually negative, although
954many platforms allow seeking beyond the end of a file).
955
956Note that not all file objects are seekable.
957[clinic start generated code]*/
958
959static PyObject *
960_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
961/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/
962{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000963 if (self->fd < 0)
964 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000965
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800966 return portable_lseek(self, pos, whence, false);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000967}
968
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300969/*[clinic input]
970_io.FileIO.tell
971
972Current file position.
973
974Can raise OSError for non seekable files.
975[clinic start generated code]*/
976
Guido van Rossuma9e20242007-03-08 00:43:48 +0000977static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300978_io_FileIO_tell_impl(fileio *self)
979/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000980{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000981 if (self->fd < 0)
982 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000983
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800984 return portable_lseek(self, NULL, 1, false);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000985}
986
Thomas Hellerc6a55ee2007-07-11 12:45:46 +0000987#ifdef HAVE_FTRUNCATE
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300988/*[clinic input]
989_io.FileIO.truncate
Serhiy Storchaka279f4462019-09-14 12:24:05 +0300990 size as posobj: object = None
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300991 /
992
993Truncate the file to at most size bytes and return the truncated size.
994
995Size defaults to the current file position, as returned by tell().
996The current file position is changed to the value of size.
997[clinic start generated code]*/
998
Guido van Rossuma9e20242007-03-08 00:43:48 +0000999static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001000_io_FileIO_truncate_impl(fileio *self, PyObject *posobj)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03001001/*[clinic end generated code: output=e49ca7a916c176fa input=b0ac133939823875]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +00001002{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001003 Py_off_t pos;
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001004 int ret;
1005 int fd;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001006
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001007 fd = self->fd;
1008 if (fd < 0)
1009 return err_closed();
1010 if (!self->writable)
1011 return err_mode("writing");
Guido van Rossuma9e20242007-03-08 00:43:48 +00001012
Serhiy Storchaka279f4462019-09-14 12:24:05 +03001013 if (posobj == Py_None) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001014 /* Get the current position. */
Benjamin Peterson74fa9f72019-11-12 14:51:34 -08001015 posobj = portable_lseek(self, NULL, 1, false);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001016 if (posobj == NULL)
1017 return NULL;
1018 }
1019 else {
1020 Py_INCREF(posobj);
1021 }
Guido van Rossum53807da2007-04-10 19:01:47 +00001022
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001023#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001024 pos = PyLong_AsLongLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001025#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001026 pos = PyLong_AsLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001027#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001028 if (PyErr_Occurred()){
1029 Py_DECREF(posobj);
1030 return NULL;
1031 }
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001032
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001033 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04001034 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001035 errno = 0;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001036#ifdef MS_WINDOWS
1037 ret = _chsize_s(fd, pos);
1038#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001039 ret = ftruncate(fd, pos);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001040#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04001041 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001042 Py_END_ALLOW_THREADS
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001043
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001044 if (ret != 0) {
1045 Py_DECREF(posobj);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001046 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001047 return NULL;
1048 }
Guido van Rossuma9e20242007-03-08 00:43:48 +00001049
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001050 return posobj;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001051}
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001052#endif /* HAVE_FTRUNCATE */
Guido van Rossum53807da2007-04-10 19:01:47 +00001053
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001054static const char *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001055mode_string(fileio *self)
Guido van Rossum53807da2007-04-10 19:01:47 +00001056{
Charles-François Natalidc3044c2012-01-09 22:40:02 +01001057 if (self->created) {
1058 if (self->readable)
1059 return "xb+";
1060 else
1061 return "xb";
1062 }
Antoine Pitroue93b63b2013-09-04 20:46:33 +02001063 if (self->appending) {
1064 if (self->readable)
1065 return "ab+";
1066 else
1067 return "ab";
1068 }
1069 else if (self->readable) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001070 if (self->writable)
1071 return "rb+";
1072 else
1073 return "rb";
1074 }
1075 else
1076 return "wb";
Guido van Rossum53807da2007-04-10 19:01:47 +00001077}
Guido van Rossuma9e20242007-03-08 00:43:48 +00001078
1079static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001080fileio_repr(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +00001081{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001082 PyObject *nameobj, *res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001083
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001084 if (self->fd < 0)
1085 return PyUnicode_FromFormat("<_io.FileIO [closed]>");
Antoine Pitrou716c4442009-05-23 19:04:03 +00001086
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001087 if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) {
1088 return NULL;
1089 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001090 if (nameobj == NULL) {
Robert Collins933430a2014-10-18 13:32:43 +13001091 res = PyUnicode_FromFormat(
Serhiy Storchaka4954f9f2014-12-02 23:39:56 +02001092 "<_io.FileIO fd=%d mode='%s' closefd=%s>",
1093 self->fd, mode_string(self), self->closefd ? "True" : "False");
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001094 }
1095 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001096 int status = Py_ReprEnter((PyObject *)self);
1097 res = NULL;
1098 if (status == 0) {
1099 res = PyUnicode_FromFormat(
1100 "<_io.FileIO name=%R mode='%s' closefd=%s>",
1101 nameobj, mode_string(self), self->closefd ? "True" : "False");
1102 Py_ReprLeave((PyObject *)self);
1103 }
1104 else if (status > 0) {
1105 PyErr_Format(PyExc_RuntimeError,
1106 "reentrant call inside %s.__repr__",
1107 Py_TYPE(self)->tp_name);
1108 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001109 Py_DECREF(nameobj);
1110 }
1111 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001112}
1113
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001114/*[clinic input]
1115_io.FileIO.isatty
1116
1117True if the file is connected to a TTY device.
1118[clinic start generated code]*/
1119
Guido van Rossuma9e20242007-03-08 00:43:48 +00001120static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001121_io_FileIO_isatty_impl(fileio *self)
1122/*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +00001123{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001124 long res;
Guido van Rossum53807da2007-04-10 19:01:47 +00001125
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001126 if (self->fd < 0)
1127 return err_closed();
1128 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001129 _Py_BEGIN_SUPPRESS_IPH
Steve Dower940f33a2016-09-08 11:21:54 -07001130 res = isatty(self->fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001131 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001132 Py_END_ALLOW_THREADS
1133 return PyBool_FromLong(res);
Guido van Rossuma9e20242007-03-08 00:43:48 +00001134}
1135
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001136#include "clinic/fileio.c.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +00001137
1138static PyMethodDef fileio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001139 _IO_FILEIO_READ_METHODDEF
1140 _IO_FILEIO_READALL_METHODDEF
1141 _IO_FILEIO_READINTO_METHODDEF
1142 _IO_FILEIO_WRITE_METHODDEF
1143 _IO_FILEIO_SEEK_METHODDEF
1144 _IO_FILEIO_TELL_METHODDEF
1145 _IO_FILEIO_TRUNCATE_METHODDEF
1146 _IO_FILEIO_CLOSE_METHODDEF
1147 _IO_FILEIO_SEEKABLE_METHODDEF
1148 _IO_FILEIO_READABLE_METHODDEF
1149 _IO_FILEIO_WRITABLE_METHODDEF
1150 _IO_FILEIO_FILENO_METHODDEF
1151 _IO_FILEIO_ISATTY_METHODDEF
Antoine Pitroue033e062010-10-29 10:38:18 +00001152 {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001153 {NULL, NULL} /* sentinel */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001154};
1155
Guido van Rossum53807da2007-04-10 19:01:47 +00001156/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */
1157
Guido van Rossumb0428152007-04-08 17:44:42 +00001158static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001159get_closed(fileio *self, void *closure)
Guido van Rossumb0428152007-04-08 17:44:42 +00001160{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001161 return PyBool_FromLong((long)(self->fd < 0));
Guido van Rossum53807da2007-04-10 19:01:47 +00001162}
1163
1164static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001165get_closefd(fileio *self, void *closure)
Christian Heimesecc42a22008-11-05 19:30:32 +00001166{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001167 return PyBool_FromLong((long)(self->closefd));
Christian Heimesecc42a22008-11-05 19:30:32 +00001168}
1169
1170static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001171get_mode(fileio *self, void *closure)
Guido van Rossum53807da2007-04-10 19:01:47 +00001172{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001173 return PyUnicode_FromString(mode_string(self));
Guido van Rossumb0428152007-04-08 17:44:42 +00001174}
1175
1176static PyGetSetDef fileio_getsetlist[] = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001177 {"closed", (getter)get_closed, NULL, "True if the file is closed"},
1178 {"closefd", (getter)get_closefd, NULL,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +03001179 "True if the file descriptor will be closed by close()."},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001180 {"mode", (getter)get_mode, NULL, "String giving the file mode"},
1181 {NULL},
Guido van Rossumb0428152007-04-08 17:44:42 +00001182};
1183
Antoine Pitrou796564c2013-07-30 19:59:21 +02001184static PyMemberDef fileio_members[] = {
Antoine Pitroude687222014-06-29 20:07:28 -04001185 {"_blksize", T_UINT, offsetof(fileio, blksize), 0},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001186 {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
1187 {NULL}
1188};
1189
Guido van Rossuma9e20242007-03-08 00:43:48 +00001190PyTypeObject PyFileIO_Type = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001191 PyVarObject_HEAD_INIT(NULL, 0)
1192 "_io.FileIO",
1193 sizeof(fileio),
1194 0,
1195 (destructor)fileio_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001196 0, /* tp_vectorcall_offset */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001197 0, /* tp_getattr */
1198 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001199 0, /* tp_as_async */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001200 (reprfunc)fileio_repr, /* tp_repr */
1201 0, /* tp_as_number */
1202 0, /* tp_as_sequence */
1203 0, /* tp_as_mapping */
1204 0, /* tp_hash */
1205 0, /* tp_call */
1206 0, /* tp_str */
1207 PyObject_GenericGetAttr, /* tp_getattro */
1208 0, /* tp_setattro */
1209 0, /* tp_as_buffer */
1210 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02001211 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001212 _io_FileIO___init____doc__, /* tp_doc */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001213 (traverseproc)fileio_traverse, /* tp_traverse */
1214 (inquiry)fileio_clear, /* tp_clear */
1215 0, /* tp_richcompare */
Antoine Pitrouada319b2019-05-29 22:12:38 +02001216 offsetof(fileio, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001217 0, /* tp_iter */
1218 0, /* tp_iternext */
1219 fileio_methods, /* tp_methods */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001220 fileio_members, /* tp_members */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001221 fileio_getsetlist, /* tp_getset */
1222 0, /* tp_base */
1223 0, /* tp_dict */
1224 0, /* tp_descr_get */
1225 0, /* tp_descr_set */
Antoine Pitrouada319b2019-05-29 22:12:38 +02001226 offsetof(fileio, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001227 _io_FileIO___init__, /* tp_init */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001228 PyType_GenericAlloc, /* tp_alloc */
1229 fileio_new, /* tp_new */
1230 PyObject_GC_Del, /* tp_free */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001231 0, /* tp_is_gc */
1232 0, /* tp_bases */
1233 0, /* tp_mro */
1234 0, /* tp_cache */
1235 0, /* tp_subclasses */
1236 0, /* tp_weaklist */
1237 0, /* tp_del */
1238 0, /* tp_version_tag */
1239 0, /* tp_finalize */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001240};