blob: 1855b83449d2a74b66b13b84621c78605045ea1a [file] [log] [blame]
Guido van Rossuma9e20242007-03-08 00:43:48 +00001/* Author: Daniel Stutzbach */
2
3#define PY_SSIZE_T_CLEAN
4#include "Python.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +01005#include "pycore_object.h"
Antoine Pitroue033e062010-10-29 10:38:18 +00006#include "structmember.h"
Benjamin 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
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000258 if (PyFloat_Check(nameobj)) {
259 PyErr_SetString(PyExc_TypeError,
260 "integer argument expected, got float");
261 return -1;
262 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000263
Serhiy Storchaka78980432013-01-15 01:12:17 +0200264 fd = _PyLong_AsInt(nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000265 if (fd < 0) {
266 if (!PyErr_Occurred()) {
267 PyErr_SetString(PyExc_ValueError,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +0300268 "negative file descriptor");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000269 return -1;
270 }
271 PyErr_Clear();
272 }
Guido van Rossumb0428152007-04-08 17:44:42 +0000273
Steve Dowereacee982017-02-04 14:38:11 -0800274 if (fd < 0) {
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000275#ifdef MS_WINDOWS
Steve Dowereacee982017-02-04 14:38:11 -0800276 if (!PyUnicode_FSDecoder(nameobj, &stringobj)) {
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300277 return -1;
278 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300279 widename = PyUnicode_AsUnicode(stringobj);
Steve Dowereacee982017-02-04 14:38:11 -0800280 if (widename == NULL)
281 return -1;
282#else
Antoine Pitrou13348842012-01-29 18:36:34 +0100283 if (!PyUnicode_FSConverter(nameobj, &stringobj)) {
284 return -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000285 }
Antoine Pitrou13348842012-01-29 18:36:34 +0100286 name = PyBytes_AS_STRING(stringobj);
Steve Dowereacee982017-02-04 14:38:11 -0800287#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000288 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000289
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000290 s = mode;
291 while (*s) {
292 switch (*s++) {
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100293 case 'x':
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000294 if (rwa) {
295 bad_mode:
296 PyErr_SetString(PyExc_ValueError,
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100297 "Must have exactly one of create/read/write/append "
Georg Brandl28928ae2010-10-21 13:45:52 +0000298 "mode and at most one plus");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000299 goto error;
300 }
301 rwa = 1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100302 self->created = 1;
303 self->writable = 1;
304 flags |= O_EXCL | O_CREAT;
305 break;
306 case 'r':
307 if (rwa)
308 goto bad_mode;
309 rwa = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000310 self->readable = 1;
311 break;
312 case 'w':
313 if (rwa)
314 goto bad_mode;
315 rwa = 1;
316 self->writable = 1;
317 flags |= O_CREAT | O_TRUNC;
318 break;
319 case 'a':
320 if (rwa)
321 goto bad_mode;
322 rwa = 1;
323 self->writable = 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200324 self->appending = 1;
325 flags |= O_APPEND | O_CREAT;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000326 break;
327 case 'b':
328 break;
329 case '+':
330 if (plus)
331 goto bad_mode;
332 self->readable = self->writable = 1;
333 plus = 1;
334 break;
335 default:
336 PyErr_Format(PyExc_ValueError,
337 "invalid mode: %.200s", mode);
338 goto error;
339 }
340 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000341
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000342 if (!rwa)
343 goto bad_mode;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000344
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000345 if (self->readable && self->writable)
346 flags |= O_RDWR;
347 else if (self->readable)
348 flags |= O_RDONLY;
349 else
350 flags |= O_WRONLY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000351
352#ifdef O_BINARY
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000353 flags |= O_BINARY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000354#endif
355
Victor Stinnerdaf45552013-08-28 00:53:59 +0200356#ifdef MS_WINDOWS
357 flags |= O_NOINHERIT;
358#elif defined(O_CLOEXEC)
359 flags |= O_CLOEXEC;
360#endif
Walter Dörwald0e411482007-06-06 16:55:38 +0000361
Steve Dowerb82e17e2019-05-23 08:45:22 -0700362 if (PySys_Audit("open", "Osi", nameobj, mode, flags) < 0) {
363 goto error;
364 }
365
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000366 if (fd >= 0) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000367 self->fd = fd;
368 self->closefd = closefd;
369 }
370 else {
371 self->closefd = 1;
372 if (!closefd) {
373 PyErr_SetString(PyExc_ValueError,
374 "Cannot use closefd=False with file name");
375 goto error;
376 }
Guido van Rossum2dced8b2007-10-30 17:27:30 +0000377
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000378 errno = 0;
Ross Lagerwall59142db2011-10-31 20:34:46 +0200379 if (opener == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000380 do {
381 Py_BEGIN_ALLOW_THREADS
Thomas Helleraf2be262007-07-12 11:03:13 +0000382#ifdef MS_WINDOWS
Steve Dowereacee982017-02-04 14:38:11 -0800383 self->fd = _wopen(widename, flags, 0666);
384#else
385 self->fd = open(name, flags, 0666);
Thomas Helleraf2be262007-07-12 11:03:13 +0000386#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000387 Py_END_ALLOW_THREADS
388 } while (self->fd < 0 && errno == EINTR &&
389 !(async_err = PyErr_CheckSignals()));
Victor Stinner9672da72015-03-04 18:40:10 +0100390
391 if (async_err)
392 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200393 }
394 else {
395 PyObject *fdobj;
396
397#ifndef MS_WINDOWS
398 /* the opener may clear the atomic flag */
399 atomic_flag_works = NULL;
400#endif
401
402 fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200403 if (fdobj == NULL)
404 goto error;
405 if (!PyLong_Check(fdobj)) {
406 Py_DECREF(fdobj);
407 PyErr_SetString(PyExc_TypeError,
408 "expected integer from opener");
409 goto error;
410 }
411
Serhiy Storchaka78980432013-01-15 01:12:17 +0200412 self->fd = _PyLong_AsInt(fdobj);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200413 Py_DECREF(fdobj);
Barry Warsaw480e2852016-06-08 17:47:26 -0400414 if (self->fd < 0) {
415 if (!PyErr_Occurred()) {
Barry Warsaw118598a2016-06-08 17:54:43 -0400416 /* The opener returned a negative but didn't set an
417 exception. See issue #27066 */
Barry Warsaw480e2852016-06-08 17:47:26 -0400418 PyErr_Format(PyExc_ValueError,
419 "opener returned %d", self->fd);
420 }
Ross Lagerwall59142db2011-10-31 20:34:46 +0200421 goto error;
422 }
423 }
424
Hynek Schlawack7f59fd72012-06-22 09:32:22 +0200425 fd_is_own = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000426 if (self->fd < 0) {
Victor Stinner9672da72015-03-04 18:40:10 +0100427 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000428 goto error;
429 }
Victor Stinnerdaf45552013-08-28 00:53:59 +0200430
431#ifndef MS_WINDOWS
432 if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0)
433 goto error;
434#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000435 }
Antoine Pitroude687222014-06-29 20:07:28 -0400436
437 self->blksize = DEFAULT_BUFFER_SIZE;
Martin Panter0bb62b12015-12-06 03:15:05 +0000438 Py_BEGIN_ALLOW_THREADS
439 fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
440 Py_END_ALLOW_THREADS
441 if (fstat_result < 0) {
Martin Panter49d3db92015-12-06 11:12:15 +0000442 /* Tolerate fstat() errors other than EBADF. See Issue #25717, where
443 an anonymous file on a Virtual Box shared folder filesystem would
444 raise ENOENT. */
Martin Panter0bb62b12015-12-06 03:15:05 +0000445#ifdef MS_WINDOWS
446 if (GetLastError() == ERROR_INVALID_HANDLE) {
447 PyErr_SetFromWindowsErr(0);
448#else
449 if (errno == EBADF) {
450 PyErr_SetFromErrno(PyExc_OSError);
451#endif
452 goto error;
453 }
Antoine Pitroude687222014-06-29 20:07:28 -0400454 }
Martin Panter0bb62b12015-12-06 03:15:05 +0000455 else {
456#if defined(S_ISDIR) && defined(EISDIR)
457 /* On Unix, open will succeed for directories.
458 In Python, there should be no file objects referring to
459 directories, so we need a check. */
460 if (S_ISDIR(fdfstat.st_mode)) {
461 errno = EISDIR;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300462 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Martin Panter0bb62b12015-12-06 03:15:05 +0000463 goto error;
464 }
Antoine Pitroude687222014-06-29 20:07:28 -0400465#endif /* defined(S_ISDIR) */
466#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin Panter0bb62b12015-12-06 03:15:05 +0000467 if (fdfstat.st_blksize > 1)
468 self->blksize = fdfstat.st_blksize;
Antoine Pitroude687222014-06-29 20:07:28 -0400469#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
Martin Panter0bb62b12015-12-06 03:15:05 +0000470 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000471
Victor Stinner89e34362011-01-07 18:47:22 +0000472#if defined(MS_WINDOWS) || defined(__CYGWIN__)
473 /* don't translate newlines (\r\n <=> \n) */
474 _setmode(self->fd, O_BINARY);
475#endif
476
Victor Stinnerd9d04192013-11-06 23:50:10 +0100477 if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000478 goto error;
Antoine Pitrou08838b62009-01-21 00:55:13 +0000479
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200480 if (self->appending) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000481 /* For consistent behaviour, we explicitly seek to the
482 end of file (otherwise, it might be done only on the
483 first write()). */
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800484 PyObject *pos = portable_lseek(self, NULL, 2, true);
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200485 if (pos == NULL)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000486 goto error;
487 Py_DECREF(pos);
488 }
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000489
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000490 goto done;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000491
492 error:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000493 ret = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200494 if (!fd_is_own)
495 self->fd = -1;
Benjamin Petersonbbb04122010-10-30 23:16:28 +0000496 if (self->fd >= 0)
497 internal_close(self);
Guido van Rossum53807da2007-04-10 19:01:47 +0000498
Guido van Rossuma9e20242007-03-08 00:43:48 +0000499 done:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000500 Py_CLEAR(stringobj);
501 return ret;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000502}
503
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000504static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000505fileio_traverse(fileio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000506{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000507 Py_VISIT(self->dict);
508 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000509}
510
511static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000512fileio_clear(fileio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000513{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000514 Py_CLEAR(self->dict);
515 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000516}
517
Guido van Rossuma9e20242007-03-08 00:43:48 +0000518static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000519fileio_dealloc(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000520{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200521 self->finalizing = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000522 if (_PyIOBase_finalize((PyObject *) self) < 0)
523 return;
524 _PyObject_GC_UNTRACK(self);
525 if (self->weakreflist != NULL)
526 PyObject_ClearWeakRefs((PyObject *) self);
527 Py_CLEAR(self->dict);
528 Py_TYPE(self)->tp_free((PyObject *)self);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000529}
530
531static PyObject *
532err_closed(void)
533{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000534 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
535 return NULL;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000536}
537
538static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200539err_mode(const char *action)
Guido van Rossum53807da2007-04-10 19:01:47 +0000540{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100541 _PyIO_State *state = IO_STATE();
542 if (state != NULL)
543 PyErr_Format(state->unsupported_operation,
544 "File not open for %s", action);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000545 return NULL;
Guido van Rossum53807da2007-04-10 19:01:47 +0000546}
547
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300548/*[clinic input]
549_io.FileIO.fileno
550
551Return the underlying file descriptor (an integer).
552[clinic start generated code]*/
553
Guido van Rossum53807da2007-04-10 19:01:47 +0000554static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300555_io_FileIO_fileno_impl(fileio *self)
556/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000557{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000558 if (self->fd < 0)
559 return err_closed();
560 return PyLong_FromLong((long) self->fd);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000561}
562
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300563/*[clinic input]
564_io.FileIO.readable
565
566True if file was opened in a read mode.
567[clinic start generated code]*/
568
Guido van Rossuma9e20242007-03-08 00:43:48 +0000569static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300570_io_FileIO_readable_impl(fileio *self)
571/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000572{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000573 if (self->fd < 0)
574 return err_closed();
575 return PyBool_FromLong((long) self->readable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000576}
577
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300578/*[clinic input]
579_io.FileIO.writable
580
581True if file was opened in a write mode.
582[clinic start generated code]*/
583
Guido van Rossuma9e20242007-03-08 00:43:48 +0000584static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300585_io_FileIO_writable_impl(fileio *self)
586/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000587{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000588 if (self->fd < 0)
589 return err_closed();
590 return PyBool_FromLong((long) self->writable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000591}
592
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300593/*[clinic input]
594_io.FileIO.seekable
595
596True if file supports random-access.
597[clinic start generated code]*/
598
Guido van Rossuma9e20242007-03-08 00:43:48 +0000599static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300600_io_FileIO_seekable_impl(fileio *self)
601/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000602{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000603 if (self->fd < 0)
604 return err_closed();
605 if (self->seekable < 0) {
Victor Stinner99970732017-05-02 15:10:39 +0200606 /* portable_lseek() sets the seekable attribute */
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800607 PyObject *pos = portable_lseek(self, NULL, SEEK_CUR, false);
Victor Stinner99970732017-05-02 15:10:39 +0200608 assert(self->seekable >= 0);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000609 if (pos == NULL) {
610 PyErr_Clear();
Victor Stinner99970732017-05-02 15:10:39 +0200611 }
612 else {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000613 Py_DECREF(pos);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000614 }
615 }
616 return PyBool_FromLong((long) self->seekable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000617}
618
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300619/*[clinic input]
620_io.FileIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700621 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300622 /
623
624Same as RawIOBase.readinto().
625[clinic start generated code]*/
626
Guido van Rossuma9e20242007-03-08 00:43:48 +0000627static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300628_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700629/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000630{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100631 Py_ssize_t n;
632 int err;
Guido van Rossum53807da2007-04-10 19:01:47 +0000633
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000634 if (self->fd < 0)
635 return err_closed();
636 if (!self->readable)
637 return err_mode("reading");
Guido van Rossum53807da2007-04-10 19:01:47 +0000638
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300639 n = _Py_read(self->fd, buffer->buf, buffer->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100640 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100641 err = errno;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100642
643 if (n == -1) {
644 if (err == EAGAIN) {
645 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000646 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100647 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000648 return NULL;
649 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000650
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000651 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000652}
653
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000654static size_t
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100655new_buffersize(fileio *self, size_t currentsize)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656{
Antoine Pitroua3f44572012-04-17 13:50:58 +0200657 size_t addend;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100658
Nadeem Vawdad41a98b2011-10-13 13:34:16 +0200659 /* Expand the buffer by an amount proportional to the current size,
Antoine Pitroua3f44572012-04-17 13:50:58 +0200660 giving us amortized linear-time behavior. For bigger sizes, use a
661 less-than-double growth factor to avoid excessive allocation. */
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100662 assert(currentsize <= PY_SSIZE_T_MAX);
Antoine Pitroua3f44572012-04-17 13:50:58 +0200663 if (currentsize > 65536)
664 addend = currentsize >> 3;
665 else
666 addend = 256 + currentsize;
667 if (addend < SMALLCHUNK)
668 /* Avoid tiny read() calls. */
669 addend = SMALLCHUNK;
670 return addend + currentsize;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000671}
672
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300673/*[clinic input]
674_io.FileIO.readall
675
676Read all data from the file, returned as bytes.
677
678In non-blocking mode, returns as much as is immediately available,
679or None if no data is available. Return an empty bytes object at EOF.
680[clinic start generated code]*/
681
Guido van Rossum7165cb12007-07-10 06:54:34 +0000682static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300683_io_FileIO_readall_impl(fileio *self)
684/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/
Guido van Rossum7165cb12007-07-10 06:54:34 +0000685{
Victor Stinnere134a7f2015-03-30 10:09:31 +0200686 struct _Py_stat_struct status;
Victor Stinnera2a64772011-10-11 22:45:02 +0200687 Py_off_t pos, end;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000688 PyObject *result;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100689 Py_ssize_t bytes_read = 0;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100690 Py_ssize_t n;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100691 size_t bufsize;
Nir Soffer6a894812017-12-01 03:18:58 +0200692 int fstat_result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000693
Victor Stinnerb79f28c2011-05-25 22:09:03 +0200694 if (self->fd < 0)
695 return err_closed();
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000696
Nir Soffer6a894812017-12-01 03:18:58 +0200697 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400698 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200699#ifdef MS_WINDOWS
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200700 pos = _lseeki64(self->fd, 0L, SEEK_CUR);
701#else
702 pos = lseek(self->fd, 0L, SEEK_CUR);
703#endif
Steve Dower8fc89802015-04-12 00:26:27 -0400704 _Py_END_SUPPRESS_IPH
Nir Soffer6a894812017-12-01 03:18:58 +0200705 fstat_result = _Py_fstat_noraise(self->fd, &status);
706 Py_END_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400707
Nir Soffer6a894812017-12-01 03:18:58 +0200708 if (fstat_result == 0)
Victor Stinnere134a7f2015-03-30 10:09:31 +0200709 end = status.st_size;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200710 else
Victor Stinnera2a64772011-10-11 22:45:02 +0200711 end = (Py_off_t)-1;
Christian Heimesa872de52008-12-05 08:26:55 +0000712
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100713 if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) {
714 /* This is probably a real file, so we try to allocate a
715 buffer one byte larger than the rest of the file. If the
716 calculation is right then we should get EOF without having
717 to enlarge the buffer. */
718 bufsize = (size_t)(end - pos + 1);
719 } else {
720 bufsize = SMALLCHUNK;
721 }
722
723 result = PyBytes_FromStringAndSize(NULL, bufsize);
724 if (result == NULL)
725 return NULL;
726
727 while (1) {
728 if (bytes_read >= (Py_ssize_t)bufsize) {
729 bufsize = new_buffersize(self, bytes_read);
730 if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) {
731 PyErr_SetString(PyExc_OverflowError,
732 "unbounded read returned more bytes "
Serhiy Storchakab817b772015-04-10 02:18:44 +0300733 "than a Python bytes object can hold");
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100734 Py_DECREF(result);
735 return NULL;
736 }
737
738 if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) {
739 if (_PyBytes_Resize(&result, bufsize) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000740 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000741 }
742 }
Victor Stinner9672da72015-03-04 18:40:10 +0100743
Victor Stinner66aab0c2015-03-19 22:53:20 +0100744 n = _Py_read(self->fd,
745 PyBytes_AS_STRING(result) + bytes_read,
746 bufsize - bytes_read);
Victor Stinner9672da72015-03-04 18:40:10 +0100747
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000748 if (n == 0)
749 break;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100750 if (n == -1) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000751 if (errno == EAGAIN) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100752 PyErr_Clear();
Victor Stinnere10920f2014-07-02 22:59:31 +0200753 if (bytes_read > 0)
754 break;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000755 Py_DECREF(result);
756 Py_RETURN_NONE;
757 }
758 Py_DECREF(result);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000759 return NULL;
760 }
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100761 bytes_read += n;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200762 pos += n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000763 }
Guido van Rossum7165cb12007-07-10 06:54:34 +0000764
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100765 if (PyBytes_GET_SIZE(result) > bytes_read) {
766 if (_PyBytes_Resize(&result, bytes_read) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000767 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000768 }
769 return result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000770}
771
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300772/*[clinic input]
773_io.FileIO.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300774 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300775 /
776
777Read at most size bytes, returned as bytes.
778
779Only makes one system call, so less data may be returned than requested.
780In non-blocking mode, returns None if no data is available.
781Return an empty bytes object at EOF.
782[clinic start generated code]*/
783
Guido van Rossuma9e20242007-03-08 00:43:48 +0000784static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300785_io_FileIO_read_impl(fileio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300786/*[clinic end generated code: output=42528d39dd0ca641 input=bec9a2c704ddcbc9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000787{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000788 char *ptr;
789 Py_ssize_t n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000790 PyObject *bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000791
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000792 if (self->fd < 0)
793 return err_closed();
794 if (!self->readable)
795 return err_mode("reading");
Guido van Rossuma9e20242007-03-08 00:43:48 +0000796
Victor Stinner66aab0c2015-03-19 22:53:20 +0100797 if (size < 0)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300798 return _io_FileIO_readall_impl(self);
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000799
Stéphane Wirtel74a8b6e2018-10-18 01:05:04 +0200800 if (size > _PY_READ_MAX) {
801 size = _PY_READ_MAX;
802 }
Victor Stinner66aab0c2015-03-19 22:53:20 +0100803
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000804 bytes = PyBytes_FromStringAndSize(NULL, size);
805 if (bytes == NULL)
806 return NULL;
807 ptr = PyBytes_AS_STRING(bytes);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000808
Victor Stinner66aab0c2015-03-19 22:53:20 +0100809 n = _Py_read(self->fd, ptr, size);
810 if (n == -1) {
811 /* copy errno because Py_DECREF() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100812 int err = errno;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000813 Py_DECREF(bytes);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100814 if (err == EAGAIN) {
815 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000816 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100817 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000818 return NULL;
819 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000820
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000821 if (n != size) {
822 if (_PyBytes_Resize(&bytes, n) < 0) {
Victor Stinner85c761d2013-07-16 21:36:02 +0200823 Py_CLEAR(bytes);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000824 return NULL;
825 }
826 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000827
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000828 return (PyObject *) bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000829}
830
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300831/*[clinic input]
832_io.FileIO.write
833 b: Py_buffer
834 /
835
Martin Panter6bb91f32016-05-28 00:41:57 +0000836Write buffer b to file, return number of bytes written.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300837
838Only makes one system call, so not all of the data may be written.
839The number of bytes actually written is returned. In non-blocking mode,
840returns None if the write would block.
841[clinic start generated code]*/
842
Guido van Rossuma9e20242007-03-08 00:43:48 +0000843static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300844_io_FileIO_write_impl(fileio *self, Py_buffer *b)
Martin Panter6bb91f32016-05-28 00:41:57 +0000845/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000846{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100847 Py_ssize_t n;
848 int err;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000849
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000850 if (self->fd < 0)
851 return err_closed();
852 if (!self->writable)
853 return err_mode("writing");
Guido van Rossum53807da2007-04-10 19:01:47 +0000854
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300855 n = _Py_write(self->fd, b->buf, b->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100856 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100857 err = errno;
Martin v. Löwis423be952008-08-13 15:53:07 +0000858
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000859 if (n < 0) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100860 if (err == EAGAIN) {
861 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000862 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100863 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000864 return NULL;
865 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000866
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000867 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000868}
869
Guido van Rossum53807da2007-04-10 19:01:47 +0000870/* XXX Windows support below is likely incomplete */
871
Guido van Rossum53807da2007-04-10 19:01:47 +0000872/* Cribbed from posix_lseek() */
873static PyObject *
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800874portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error)
Guido van Rossum53807da2007-04-10 19:01:47 +0000875{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000876 Py_off_t pos, res;
Victor Stinner99970732017-05-02 15:10:39 +0200877 int fd = self->fd;
Guido van Rossum53807da2007-04-10 19:01:47 +0000878
879#ifdef SEEK_SET
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000880 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
881 switch (whence) {
Guido van Rossum53807da2007-04-10 19:01:47 +0000882#if SEEK_SET != 0
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000883 case 0: whence = SEEK_SET; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000884#endif
885#if SEEK_CUR != 1
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000886 case 1: whence = SEEK_CUR; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000887#endif
Antoine Pitrou4f7945f2009-01-20 11:42:11 +0000888#if SEEK_END != 2
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000889 case 2: whence = SEEK_END; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000890#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000891 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000892#endif /* SEEK_SET */
893
Victor Stinner99970732017-05-02 15:10:39 +0200894 if (posobj == NULL) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000895 pos = 0;
Victor Stinner99970732017-05-02 15:10:39 +0200896 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000897 else {
898 if(PyFloat_Check(posobj)) {
899 PyErr_SetString(PyExc_TypeError, "an integer is required");
900 return NULL;
901 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000902#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000903 pos = PyLong_AsLongLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000904#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000905 pos = PyLong_AsLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000906#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000907 if (PyErr_Occurred())
908 return NULL;
909 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000910
Steve Dower940f33a2016-09-08 11:21:54 -0700911 Py_BEGIN_ALLOW_THREADS
912 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200913#ifdef MS_WINDOWS
Steve Dower940f33a2016-09-08 11:21:54 -0700914 res = _lseeki64(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000915#else
Steve Dower940f33a2016-09-08 11:21:54 -0700916 res = lseek(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000917#endif
Steve Dower940f33a2016-09-08 11:21:54 -0700918 _Py_END_SUPPRESS_IPH
919 Py_END_ALLOW_THREADS
Victor Stinner99970732017-05-02 15:10:39 +0200920
921 if (self->seekable < 0) {
922 self->seekable = (res >= 0);
923 }
924
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800925 if (res < 0) {
926 if (suppress_pipe_error && errno == ESPIPE) {
927 res = 0;
928 } else {
929 return PyErr_SetFromErrno(PyExc_OSError);
930 }
931 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000932
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000933#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000934 return PyLong_FromLongLong(res);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000935#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000936 return PyLong_FromLong(res);
Guido van Rossum53807da2007-04-10 19:01:47 +0000937#endif
938}
939
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300940/*[clinic input]
941_io.FileIO.seek
942 pos: object
943 whence: int = 0
944 /
Guido van Rossuma9e20242007-03-08 00:43:48 +0000945
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300946Move to new file position and return the file position.
947
948Argument offset is a byte count. Optional argument whence defaults to
949SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
950are SEEK_CUR or 1 (move relative to current position, positive or negative),
951and SEEK_END or 2 (move relative to end of file, usually negative, although
952many platforms allow seeking beyond the end of a file).
953
954Note that not all file objects are seekable.
955[clinic start generated code]*/
956
957static PyObject *
958_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
959/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/
960{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000961 if (self->fd < 0)
962 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000963
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800964 return portable_lseek(self, pos, whence, false);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000965}
966
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300967/*[clinic input]
968_io.FileIO.tell
969
970Current file position.
971
972Can raise OSError for non seekable files.
973[clinic start generated code]*/
974
Guido van Rossuma9e20242007-03-08 00:43:48 +0000975static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300976_io_FileIO_tell_impl(fileio *self)
977/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000978{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000979 if (self->fd < 0)
980 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000981
Benjamin Peterson74fa9f72019-11-12 14:51:34 -0800982 return portable_lseek(self, NULL, 1, false);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000983}
984
Thomas Hellerc6a55ee2007-07-11 12:45:46 +0000985#ifdef HAVE_FTRUNCATE
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300986/*[clinic input]
987_io.FileIO.truncate
Serhiy Storchaka279f4462019-09-14 12:24:05 +0300988 size as posobj: object = None
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300989 /
990
991Truncate the file to at most size bytes and return the truncated size.
992
993Size defaults to the current file position, as returned by tell().
994The current file position is changed to the value of size.
995[clinic start generated code]*/
996
Guido van Rossuma9e20242007-03-08 00:43:48 +0000997static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300998_io_FileIO_truncate_impl(fileio *self, PyObject *posobj)
Serhiy Storchaka279f4462019-09-14 12:24:05 +0300999/*[clinic end generated code: output=e49ca7a916c176fa input=b0ac133939823875]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +00001000{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001001 Py_off_t pos;
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001002 int ret;
1003 int fd;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001004
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001005 fd = self->fd;
1006 if (fd < 0)
1007 return err_closed();
1008 if (!self->writable)
1009 return err_mode("writing");
Guido van Rossuma9e20242007-03-08 00:43:48 +00001010
Serhiy Storchaka279f4462019-09-14 12:24:05 +03001011 if (posobj == Py_None) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001012 /* Get the current position. */
Benjamin Peterson74fa9f72019-11-12 14:51:34 -08001013 posobj = portable_lseek(self, NULL, 1, false);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001014 if (posobj == NULL)
1015 return NULL;
1016 }
1017 else {
1018 Py_INCREF(posobj);
1019 }
Guido van Rossum53807da2007-04-10 19:01:47 +00001020
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001021#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001022 pos = PyLong_AsLongLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001023#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001024 pos = PyLong_AsLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001025#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001026 if (PyErr_Occurred()){
1027 Py_DECREF(posobj);
1028 return NULL;
1029 }
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001030
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001031 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04001032 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001033 errno = 0;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001034#ifdef MS_WINDOWS
1035 ret = _chsize_s(fd, pos);
1036#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001037 ret = ftruncate(fd, pos);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001038#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04001039 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001040 Py_END_ALLOW_THREADS
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001041
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001042 if (ret != 0) {
1043 Py_DECREF(posobj);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001044 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001045 return NULL;
1046 }
Guido van Rossuma9e20242007-03-08 00:43:48 +00001047
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001048 return posobj;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001049}
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001050#endif /* HAVE_FTRUNCATE */
Guido van Rossum53807da2007-04-10 19:01:47 +00001051
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001052static const char *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001053mode_string(fileio *self)
Guido van Rossum53807da2007-04-10 19:01:47 +00001054{
Charles-François Natalidc3044c2012-01-09 22:40:02 +01001055 if (self->created) {
1056 if (self->readable)
1057 return "xb+";
1058 else
1059 return "xb";
1060 }
Antoine Pitroue93b63b2013-09-04 20:46:33 +02001061 if (self->appending) {
1062 if (self->readable)
1063 return "ab+";
1064 else
1065 return "ab";
1066 }
1067 else if (self->readable) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001068 if (self->writable)
1069 return "rb+";
1070 else
1071 return "rb";
1072 }
1073 else
1074 return "wb";
Guido van Rossum53807da2007-04-10 19:01:47 +00001075}
Guido van Rossuma9e20242007-03-08 00:43:48 +00001076
1077static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001078fileio_repr(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +00001079{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001080 PyObject *nameobj, *res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001081
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001082 if (self->fd < 0)
1083 return PyUnicode_FromFormat("<_io.FileIO [closed]>");
Antoine Pitrou716c4442009-05-23 19:04:03 +00001084
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001085 if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) {
1086 return NULL;
1087 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001088 if (nameobj == NULL) {
Robert Collins933430a2014-10-18 13:32:43 +13001089 res = PyUnicode_FromFormat(
Serhiy Storchaka4954f9f2014-12-02 23:39:56 +02001090 "<_io.FileIO fd=%d mode='%s' closefd=%s>",
1091 self->fd, mode_string(self), self->closefd ? "True" : "False");
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001092 }
1093 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001094 int status = Py_ReprEnter((PyObject *)self);
1095 res = NULL;
1096 if (status == 0) {
1097 res = PyUnicode_FromFormat(
1098 "<_io.FileIO name=%R mode='%s' closefd=%s>",
1099 nameobj, mode_string(self), self->closefd ? "True" : "False");
1100 Py_ReprLeave((PyObject *)self);
1101 }
1102 else if (status > 0) {
1103 PyErr_Format(PyExc_RuntimeError,
1104 "reentrant call inside %s.__repr__",
1105 Py_TYPE(self)->tp_name);
1106 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001107 Py_DECREF(nameobj);
1108 }
1109 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001110}
1111
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001112/*[clinic input]
1113_io.FileIO.isatty
1114
1115True if the file is connected to a TTY device.
1116[clinic start generated code]*/
1117
Guido van Rossuma9e20242007-03-08 00:43:48 +00001118static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001119_io_FileIO_isatty_impl(fileio *self)
1120/*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +00001121{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001122 long res;
Guido van Rossum53807da2007-04-10 19:01:47 +00001123
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001124 if (self->fd < 0)
1125 return err_closed();
1126 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001127 _Py_BEGIN_SUPPRESS_IPH
Steve Dower940f33a2016-09-08 11:21:54 -07001128 res = isatty(self->fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001129 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001130 Py_END_ALLOW_THREADS
1131 return PyBool_FromLong(res);
Guido van Rossuma9e20242007-03-08 00:43:48 +00001132}
1133
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001134#include "clinic/fileio.c.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +00001135
1136static PyMethodDef fileio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001137 _IO_FILEIO_READ_METHODDEF
1138 _IO_FILEIO_READALL_METHODDEF
1139 _IO_FILEIO_READINTO_METHODDEF
1140 _IO_FILEIO_WRITE_METHODDEF
1141 _IO_FILEIO_SEEK_METHODDEF
1142 _IO_FILEIO_TELL_METHODDEF
1143 _IO_FILEIO_TRUNCATE_METHODDEF
1144 _IO_FILEIO_CLOSE_METHODDEF
1145 _IO_FILEIO_SEEKABLE_METHODDEF
1146 _IO_FILEIO_READABLE_METHODDEF
1147 _IO_FILEIO_WRITABLE_METHODDEF
1148 _IO_FILEIO_FILENO_METHODDEF
1149 _IO_FILEIO_ISATTY_METHODDEF
Antoine Pitroue033e062010-10-29 10:38:18 +00001150 {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001151 {NULL, NULL} /* sentinel */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001152};
1153
Guido van Rossum53807da2007-04-10 19:01:47 +00001154/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */
1155
Guido van Rossumb0428152007-04-08 17:44:42 +00001156static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001157get_closed(fileio *self, void *closure)
Guido van Rossumb0428152007-04-08 17:44:42 +00001158{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001159 return PyBool_FromLong((long)(self->fd < 0));
Guido van Rossum53807da2007-04-10 19:01:47 +00001160}
1161
1162static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001163get_closefd(fileio *self, void *closure)
Christian Heimesecc42a22008-11-05 19:30:32 +00001164{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001165 return PyBool_FromLong((long)(self->closefd));
Christian Heimesecc42a22008-11-05 19:30:32 +00001166}
1167
1168static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001169get_mode(fileio *self, void *closure)
Guido van Rossum53807da2007-04-10 19:01:47 +00001170{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001171 return PyUnicode_FromString(mode_string(self));
Guido van Rossumb0428152007-04-08 17:44:42 +00001172}
1173
1174static PyGetSetDef fileio_getsetlist[] = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001175 {"closed", (getter)get_closed, NULL, "True if the file is closed"},
1176 {"closefd", (getter)get_closefd, NULL,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +03001177 "True if the file descriptor will be closed by close()."},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001178 {"mode", (getter)get_mode, NULL, "String giving the file mode"},
1179 {NULL},
Guido van Rossumb0428152007-04-08 17:44:42 +00001180};
1181
Antoine Pitrou796564c2013-07-30 19:59:21 +02001182static PyMemberDef fileio_members[] = {
Antoine Pitroude687222014-06-29 20:07:28 -04001183 {"_blksize", T_UINT, offsetof(fileio, blksize), 0},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001184 {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
1185 {NULL}
1186};
1187
Guido van Rossuma9e20242007-03-08 00:43:48 +00001188PyTypeObject PyFileIO_Type = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001189 PyVarObject_HEAD_INIT(NULL, 0)
1190 "_io.FileIO",
1191 sizeof(fileio),
1192 0,
1193 (destructor)fileio_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001194 0, /* tp_vectorcall_offset */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001195 0, /* tp_getattr */
1196 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001197 0, /* tp_as_async */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001198 (reprfunc)fileio_repr, /* tp_repr */
1199 0, /* tp_as_number */
1200 0, /* tp_as_sequence */
1201 0, /* tp_as_mapping */
1202 0, /* tp_hash */
1203 0, /* tp_call */
1204 0, /* tp_str */
1205 PyObject_GenericGetAttr, /* tp_getattro */
1206 0, /* tp_setattro */
1207 0, /* tp_as_buffer */
1208 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02001209 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001210 _io_FileIO___init____doc__, /* tp_doc */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001211 (traverseproc)fileio_traverse, /* tp_traverse */
1212 (inquiry)fileio_clear, /* tp_clear */
1213 0, /* tp_richcompare */
Antoine Pitrouada319b2019-05-29 22:12:38 +02001214 offsetof(fileio, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001215 0, /* tp_iter */
1216 0, /* tp_iternext */
1217 fileio_methods, /* tp_methods */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001218 fileio_members, /* tp_members */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001219 fileio_getsetlist, /* tp_getset */
1220 0, /* tp_base */
1221 0, /* tp_dict */
1222 0, /* tp_descr_get */
1223 0, /* tp_descr_set */
Antoine Pitrouada319b2019-05-29 22:12:38 +02001224 offsetof(fileio, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001225 _io_FileIO___init__, /* tp_init */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001226 PyType_GenericAlloc, /* tp_alloc */
1227 fileio_new, /* tp_new */
1228 PyObject_GC_Del, /* tp_free */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001229 0, /* tp_is_gc */
1230 0, /* tp_bases */
1231 0, /* tp_mro */
1232 0, /* tp_cache */
1233 0, /* tp_subclasses */
1234 0, /* tp_weaklist */
1235 0, /* tp_del */
1236 0, /* tp_version_tag */
1237 0, /* tp_finalize */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001238};