blob: 0894ca45c891bbbadb5d1cc4007aad6549933817 [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"
Antoine Pitroue033e062010-10-29 10:38:18 +00005#include "structmember.h"
Benjamin Peterson2614cda2010-03-21 22:36:19 +00006#ifdef HAVE_SYS_TYPES_H
Guido van Rossuma9e20242007-03-08 00:43:48 +00007#include <sys/types.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +00008#endif
9#ifdef HAVE_SYS_STAT_H
Guido van Rossuma9e20242007-03-08 00:43:48 +000010#include <sys/stat.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +000011#endif
12#ifdef HAVE_FCNTL_H
Guido van Rossuma9e20242007-03-08 00:43:48 +000013#include <fcntl.h>
Benjamin Peterson2614cda2010-03-21 22:36:19 +000014#endif
Guido van Rossuma9e20242007-03-08 00:43:48 +000015#include <stddef.h> /* For offsetof */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000016#include "_iomodule.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +000017
18/*
19 * Known likely problems:
20 *
21 * - Files larger then 2**32-1
22 * - Files with unicode filenames
23 * - Passing numbers greater than 2**32-1 when an integer is expected
24 * - Making it work on Windows and other oddball platforms
25 *
26 * To Do:
27 *
28 * - autoconfify header file inclusion
Guido van Rossuma9e20242007-03-08 00:43:48 +000029 */
30
31#ifdef MS_WINDOWS
32/* can simulate truncate with Win32 API functions; see file_truncate */
Thomas Hellerfdeee3a2007-07-12 11:21:36 +000033#define HAVE_FTRUNCATE
Guido van Rossuma9e20242007-03-08 00:43:48 +000034#define WIN32_LEAN_AND_MEAN
35#include <windows.h>
36#endif
37
Christian Heimesa872de52008-12-05 08:26:55 +000038#if BUFSIZ < (8*1024)
39#define SMALLCHUNK (8*1024)
40#elif (BUFSIZ >= (2 << 25))
41#error "unreasonable BUFSIZ > 64MB defined"
42#else
43#define SMALLCHUNK BUFSIZ
44#endif
45
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030046/*[clinic input]
47module _io
48class _io.FileIO "fileio *" "&PyFileIO_Type"
49[clinic start generated code]*/
50/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/
51
52/*[python input]
53class io_ssize_t_converter(CConverter):
54 type = 'Py_ssize_t'
55 converter = '_PyIO_ConvertSsize_t'
56[python start generated code]*/
57/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/
58
Guido van Rossuma9e20242007-03-08 00:43:48 +000059typedef struct {
Antoine Pitrouae4b4722010-05-05 16:31:07 +000060 PyObject_HEAD
61 int fd;
Charles-François Natalidc3044c2012-01-09 22:40:02 +010062 unsigned int created : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000063 unsigned int readable : 1;
64 unsigned int writable : 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +020065 unsigned int appending : 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000066 signed int seekable : 2; /* -1 means unknown */
67 unsigned int closefd : 1;
Antoine Pitrou796564c2013-07-30 19:59:21 +020068 char finalizing;
Antoine Pitroude687222014-06-29 20:07:28 -040069 unsigned int blksize;
Antoine Pitrouae4b4722010-05-05 16:31:07 +000070 PyObject *weakreflist;
71 PyObject *dict;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000072} fileio;
Guido van Rossuma9e20242007-03-08 00:43:48 +000073
Collin Winteraf334382007-03-08 21:46:15 +000074PyTypeObject PyFileIO_Type;
75
Victor Stinnerd9d04192013-11-06 23:50:10 +010076_Py_IDENTIFIER(name);
77
Guido van Rossuma9e20242007-03-08 00:43:48 +000078#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
79
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000080int
81_PyFileIO_closed(PyObject *self)
82{
Antoine Pitrouae4b4722010-05-05 16:31:07 +000083 return ((fileio *)self)->fd < 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000084}
Antoine Pitrou08838b62009-01-21 00:55:13 +000085
Antoine Pitroue033e062010-10-29 10:38:18 +000086/* Because this can call arbitrary code, it shouldn't be called when
87 the refcount is 0 (that is, not directly from tp_dealloc unless
88 the refcount has been temporarily re-incremented). */
89static PyObject *
90fileio_dealloc_warn(fileio *self, PyObject *source)
91{
92 if (self->fd >= 0 && self->closefd) {
93 PyObject *exc, *val, *tb;
94 PyErr_Fetch(&exc, &val, &tb);
95 if (PyErr_WarnFormat(PyExc_ResourceWarning, 1,
96 "unclosed file %R", source)) {
97 /* 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
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000106static PyObject *
107portable_lseek(int fd, PyObject *posobj, int whence);
108
Antoine Pitroua28fcfd2009-03-13 23:42:55 +0000109static PyObject *portable_lseek(int fd, PyObject *posobj, int whence);
110
Kristján Valur Jónsson19288c22008-12-18 17:15:54 +0000111/* Returns 0 on success, -1 with exception set on failure. */
Neal Norwitz88b44da2007-08-12 17:23:54 +0000112static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000113internal_close(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000114{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000115 int err = 0;
116 int save_errno = 0;
117 if (self->fd >= 0) {
118 int fd = self->fd;
119 self->fd = -1;
120 /* fd is accessible and someone else may have closed it */
121 if (_PyVerify_fd(fd)) {
122 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400123 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000124 err = close(fd);
125 if (err < 0)
126 save_errno = errno;
Steve Dower8fc89802015-04-12 00:26:27 -0400127 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000128 Py_END_ALLOW_THREADS
129 } else {
130 save_errno = errno;
131 err = -1;
132 }
133 }
134 if (err < 0) {
135 errno = save_errno;
136 PyErr_SetFromErrno(PyExc_IOError);
137 return -1;
138 }
139 return 0;
Neal Norwitz88b44da2007-08-12 17:23:54 +0000140}
141
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300142/*[clinic input]
143_io.FileIO.close
144
145Close the file.
146
147A closed file cannot be used for further I/O operations. close() may be
148called more than once without error.
149[clinic start generated code]*/
150
Neal Norwitz88b44da2007-08-12 17:23:54 +0000151static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300152_io_FileIO_close_impl(fileio *self)
153/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/
Neal Norwitz88b44da2007-08-12 17:23:54 +0000154{
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200155 PyObject *res;
156 PyObject *exc, *val, *tb;
157 int rc;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200158 _Py_IDENTIFIER(close);
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200159 res = _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type,
160 &PyId_close, "O", self);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000161 if (!self->closefd) {
162 self->fd = -1;
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200163 return res;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000164 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200165 if (res == NULL)
166 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou796564c2013-07-30 19:59:21 +0200167 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000168 PyObject *r = fileio_dealloc_warn(self, (PyObject *) self);
169 if (r)
170 Py_DECREF(r);
171 else
172 PyErr_Clear();
173 }
Serhiy Storchakaa3712a92015-02-21 00:35:09 +0200174 rc = internal_close(self);
175 if (res == NULL)
176 _PyErr_ChainExceptions(exc, val, tb);
177 if (rc < 0)
178 Py_CLEAR(res);
179 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000180}
181
182static PyObject *
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000183fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000184{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000185 fileio *self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000186
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000187 assert(type != NULL && type->tp_alloc != NULL);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000188
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000189 self = (fileio *) type->tp_alloc(type, 0);
190 if (self != NULL) {
191 self->fd = -1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100192 self->created = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000193 self->readable = 0;
194 self->writable = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200195 self->appending = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000196 self->seekable = -1;
Antoine Pitroude687222014-06-29 20:07:28 -0400197 self->blksize = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000198 self->closefd = 1;
199 self->weakreflist = NULL;
200 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000201
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000202 return (PyObject *) self;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000203}
204
Victor Stinnerdaf45552013-08-28 00:53:59 +0200205#ifdef O_CLOEXEC
206extern int _Py_open_cloexec_works;
207#endif
Guido van Rossuma9e20242007-03-08 00:43:48 +0000208
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300209/*[clinic input]
210_io.FileIO.__init__
211 file as nameobj: object
212 mode: str = "r"
213 closefd: int(c_default="1") = True
214 opener: object = None
215
216Open a file.
217
218The mode can be 'r' (default), 'w', 'x' or 'a' for reading,
219writing, exclusive creation or appending. The file will be created if it
220doesn't exist when opened for writing or appending; it will be truncated
221when opened for writing. A FileExistsError will be raised if it already
222exists when opened for creating. Opening a file for creating implies
223writing so this mode behaves in a similar way to 'w'.Add a '+' to the mode
224to allow simultaneous reading and writing. A custom opener can be used by
225passing a callable as *opener*. The underlying file descriptor for the file
226object is then obtained by calling opener with (*name*, *flags*).
227*opener* must return an open file descriptor (passing os.open as *opener*
228results in functionality similar to passing None).
229[clinic start generated code]*/
230
Guido van Rossuma9e20242007-03-08 00:43:48 +0000231static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300232_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
233 int closefd, PyObject *opener)
234/*[clinic end generated code: output=23413f68e6484bbd input=193164e293d6c097]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000235{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000236 const char *name = NULL;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300237 PyObject *stringobj = NULL;
238 const char *s;
Thomas Helleraf2be262007-07-12 11:03:13 +0000239#ifdef MS_WINDOWS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000240 Py_UNICODE *widename = NULL;
Thomas Helleraf2be262007-07-12 11:03:13 +0000241#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000242 int ret = 0;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200243 int rwa = 0, plus = 0;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000244 int flags = 0;
245 int fd = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200246 int fd_is_own = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200247#ifdef O_CLOEXEC
248 int *atomic_flag_works = &_Py_open_cloexec_works;
249#elif !defined(MS_WINDOWS)
250 int *atomic_flag_works = NULL;
251#endif
Steve Dowerf2f373f2015-02-21 08:44:05 -0800252 struct _Py_stat_struct fdfstat;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000253 int async_err = 0;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000254
Christian Heimes82adeff2015-04-16 17:21:54 +0200255 assert(PyFileIO_Check(self));
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000256 if (self->fd >= 0) {
Hynek Schlawack2cc71562012-05-25 10:05:53 +0200257 if (self->closefd) {
258 /* Have to close the existing file first. */
259 if (internal_close(self) < 0)
260 return -1;
261 }
262 else
263 self->fd = -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000264 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000265
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000266 if (PyFloat_Check(nameobj)) {
267 PyErr_SetString(PyExc_TypeError,
268 "integer argument expected, got float");
269 return -1;
270 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000271
Serhiy Storchaka78980432013-01-15 01:12:17 +0200272 fd = _PyLong_AsInt(nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000273 if (fd < 0) {
274 if (!PyErr_Occurred()) {
275 PyErr_SetString(PyExc_ValueError,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +0300276 "negative file descriptor");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000277 return -1;
278 }
279 PyErr_Clear();
280 }
Guido van Rossumb0428152007-04-08 17:44:42 +0000281
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000282#ifdef MS_WINDOWS
Victor Stinnerfe9a8612011-09-29 23:19:04 +0200283 if (PyUnicode_Check(nameobj)) {
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300284 Py_ssize_t length;
285 widename = PyUnicode_AsUnicodeAndSize(nameobj, &length);
Victor Stinnerfe9a8612011-09-29 23:19:04 +0200286 if (widename == NULL)
287 return -1;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300288 if (wcslen(widename) != length) {
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +0300289 PyErr_SetString(PyExc_ValueError, "embedded null character");
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300290 return -1;
291 }
Victor Stinnerfe9a8612011-09-29 23:19:04 +0200292 } else
Guido van Rossuma9e20242007-03-08 00:43:48 +0000293#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000294 if (fd < 0)
295 {
Antoine Pitrou13348842012-01-29 18:36:34 +0100296 if (!PyUnicode_FSConverter(nameobj, &stringobj)) {
297 return -1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000298 }
Antoine Pitrou13348842012-01-29 18:36:34 +0100299 name = PyBytes_AS_STRING(stringobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000300 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000301
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000302 s = mode;
303 while (*s) {
304 switch (*s++) {
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100305 case 'x':
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000306 if (rwa) {
307 bad_mode:
308 PyErr_SetString(PyExc_ValueError,
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100309 "Must have exactly one of create/read/write/append "
Georg Brandl28928ae2010-10-21 13:45:52 +0000310 "mode and at most one plus");
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000311 goto error;
312 }
313 rwa = 1;
Charles-François Natalidc3044c2012-01-09 22:40:02 +0100314 self->created = 1;
315 self->writable = 1;
316 flags |= O_EXCL | O_CREAT;
317 break;
318 case 'r':
319 if (rwa)
320 goto bad_mode;
321 rwa = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000322 self->readable = 1;
323 break;
324 case 'w':
325 if (rwa)
326 goto bad_mode;
327 rwa = 1;
328 self->writable = 1;
329 flags |= O_CREAT | O_TRUNC;
330 break;
331 case 'a':
332 if (rwa)
333 goto bad_mode;
334 rwa = 1;
335 self->writable = 1;
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200336 self->appending = 1;
337 flags |= O_APPEND | O_CREAT;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000338 break;
339 case 'b':
340 break;
341 case '+':
342 if (plus)
343 goto bad_mode;
344 self->readable = self->writable = 1;
345 plus = 1;
346 break;
347 default:
348 PyErr_Format(PyExc_ValueError,
349 "invalid mode: %.200s", mode);
350 goto error;
351 }
352 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000353
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000354 if (!rwa)
355 goto bad_mode;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000356
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000357 if (self->readable && self->writable)
358 flags |= O_RDWR;
359 else if (self->readable)
360 flags |= O_RDONLY;
361 else
362 flags |= O_WRONLY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000363
364#ifdef O_BINARY
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000365 flags |= O_BINARY;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000366#endif
367
Victor Stinnerdaf45552013-08-28 00:53:59 +0200368#ifdef MS_WINDOWS
369 flags |= O_NOINHERIT;
370#elif defined(O_CLOEXEC)
371 flags |= O_CLOEXEC;
372#endif
Walter Dörwald0e411482007-06-06 16:55:38 +0000373
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000374 if (fd >= 0) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000375 self->fd = fd;
376 self->closefd = closefd;
377 }
378 else {
379 self->closefd = 1;
380 if (!closefd) {
381 PyErr_SetString(PyExc_ValueError,
382 "Cannot use closefd=False with file name");
383 goto error;
384 }
Guido van Rossum2dced8b2007-10-30 17:27:30 +0000385
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000386 errno = 0;
Ross Lagerwall59142db2011-10-31 20:34:46 +0200387 if (opener == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000388 do {
389 Py_BEGIN_ALLOW_THREADS
Thomas Helleraf2be262007-07-12 11:03:13 +0000390#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000391 if (widename != NULL)
392 self->fd = _wopen(widename, flags, 0666);
393 else
Thomas Helleraf2be262007-07-12 11:03:13 +0000394#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000395 self->fd = open(name, flags, 0666);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +0000396 Py_END_ALLOW_THREADS
397 } while (self->fd < 0 && errno == EINTR &&
398 !(async_err = PyErr_CheckSignals()));
Victor Stinner9672da72015-03-04 18:40:10 +0100399
400 if (async_err)
401 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200402 }
403 else {
404 PyObject *fdobj;
405
406#ifndef MS_WINDOWS
407 /* the opener may clear the atomic flag */
408 atomic_flag_works = NULL;
409#endif
410
411 fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200412 if (fdobj == NULL)
413 goto error;
414 if (!PyLong_Check(fdobj)) {
415 Py_DECREF(fdobj);
416 PyErr_SetString(PyExc_TypeError,
417 "expected integer from opener");
418 goto error;
419 }
420
Serhiy Storchaka78980432013-01-15 01:12:17 +0200421 self->fd = _PyLong_AsInt(fdobj);
Ross Lagerwall59142db2011-10-31 20:34:46 +0200422 Py_DECREF(fdobj);
423 if (self->fd == -1) {
424 goto error;
425 }
426 }
427
Hynek Schlawack7f59fd72012-06-22 09:32:22 +0200428 fd_is_own = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000429 if (self->fd < 0) {
Victor Stinner9672da72015-03-04 18:40:10 +0100430 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000431 goto error;
432 }
Victor Stinnerdaf45552013-08-28 00:53:59 +0200433
434#ifndef MS_WINDOWS
435 if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0)
436 goto error;
437#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000438 }
Antoine Pitroude687222014-06-29 20:07:28 -0400439
440 self->blksize = DEFAULT_BUFFER_SIZE;
Victor Stinnere134a7f2015-03-30 10:09:31 +0200441 if (_Py_fstat(self->fd, &fdfstat) < 0)
Antoine Pitrou9235b252012-07-06 18:48:24 +0200442 goto error;
Antoine Pitroude687222014-06-29 20:07:28 -0400443#if defined(S_ISDIR) && defined(EISDIR)
444 /* On Unix, open will succeed for directories.
445 In Python, there should be no file objects referring to
446 directories, so we need a check. */
447 if (S_ISDIR(fdfstat.st_mode)) {
448 errno = EISDIR;
449 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
450 goto error;
451 }
452#endif /* defined(S_ISDIR) */
453#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
454 if (fdfstat.st_blksize > 1)
455 self->blksize = fdfstat.st_blksize;
456#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
Guido van Rossuma9e20242007-03-08 00:43:48 +0000457
Victor Stinner89e34362011-01-07 18:47:22 +0000458#if defined(MS_WINDOWS) || defined(__CYGWIN__)
459 /* don't translate newlines (\r\n <=> \n) */
460 _setmode(self->fd, O_BINARY);
461#endif
462
Victor Stinnerd9d04192013-11-06 23:50:10 +0100463 if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000464 goto error;
Antoine Pitrou08838b62009-01-21 00:55:13 +0000465
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200466 if (self->appending) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000467 /* For consistent behaviour, we explicitly seek to the
468 end of file (otherwise, it might be done only on the
469 first write()). */
470 PyObject *pos = portable_lseek(self->fd, NULL, 2);
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200471 if (pos == NULL)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000472 goto error;
473 Py_DECREF(pos);
474 }
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000475
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000476 goto done;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000477
478 error:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000479 ret = -1;
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200480 if (!fd_is_own)
481 self->fd = -1;
Benjamin Petersonbbb04122010-10-30 23:16:28 +0000482 if (self->fd >= 0)
483 internal_close(self);
Guido van Rossum53807da2007-04-10 19:01:47 +0000484
Guido van Rossuma9e20242007-03-08 00:43:48 +0000485 done:
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000486 Py_CLEAR(stringobj);
487 return ret;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000488}
489
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000490static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000491fileio_traverse(fileio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000492{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000493 Py_VISIT(self->dict);
494 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000495}
496
497static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000498fileio_clear(fileio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000499{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000500 Py_CLEAR(self->dict);
501 return 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000502}
503
Guido van Rossuma9e20242007-03-08 00:43:48 +0000504static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000505fileio_dealloc(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000506{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200507 self->finalizing = 1;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000508 if (_PyIOBase_finalize((PyObject *) self) < 0)
509 return;
510 _PyObject_GC_UNTRACK(self);
511 if (self->weakreflist != NULL)
512 PyObject_ClearWeakRefs((PyObject *) self);
513 Py_CLEAR(self->dict);
514 Py_TYPE(self)->tp_free((PyObject *)self);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000515}
516
517static PyObject *
518err_closed(void)
519{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000520 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
521 return NULL;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000522}
523
524static PyObject *
Guido van Rossum53807da2007-04-10 19:01:47 +0000525err_mode(char *action)
526{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100527 _PyIO_State *state = IO_STATE();
528 if (state != NULL)
529 PyErr_Format(state->unsupported_operation,
530 "File not open for %s", action);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000531 return NULL;
Guido van Rossum53807da2007-04-10 19:01:47 +0000532}
533
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300534/*[clinic input]
535_io.FileIO.fileno
536
537Return the underlying file descriptor (an integer).
538[clinic start generated code]*/
539
Guido van Rossum53807da2007-04-10 19:01:47 +0000540static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300541_io_FileIO_fileno_impl(fileio *self)
542/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000543{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000544 if (self->fd < 0)
545 return err_closed();
546 return PyLong_FromLong((long) self->fd);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000547}
548
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300549/*[clinic input]
550_io.FileIO.readable
551
552True if file was opened in a read mode.
553[clinic start generated code]*/
554
Guido van Rossuma9e20242007-03-08 00:43:48 +0000555static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300556_io_FileIO_readable_impl(fileio *self)
557/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000558{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000559 if (self->fd < 0)
560 return err_closed();
561 return PyBool_FromLong((long) self->readable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000562}
563
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300564/*[clinic input]
565_io.FileIO.writable
566
567True if file was opened in a write mode.
568[clinic start generated code]*/
569
Guido van Rossuma9e20242007-03-08 00:43:48 +0000570static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300571_io_FileIO_writable_impl(fileio *self)
572/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000573{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000574 if (self->fd < 0)
575 return err_closed();
576 return PyBool_FromLong((long) self->writable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000577}
578
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300579/*[clinic input]
580_io.FileIO.seekable
581
582True if file supports random-access.
583[clinic start generated code]*/
584
Guido van Rossuma9e20242007-03-08 00:43:48 +0000585static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300586_io_FileIO_seekable_impl(fileio *self)
587/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000588{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000589 if (self->fd < 0)
590 return err_closed();
591 if (self->seekable < 0) {
592 PyObject *pos = portable_lseek(self->fd, NULL, SEEK_CUR);
593 if (pos == NULL) {
594 PyErr_Clear();
595 self->seekable = 0;
596 } else {
597 Py_DECREF(pos);
598 self->seekable = 1;
599 }
600 }
601 return PyBool_FromLong((long) self->seekable);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000602}
603
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300604/*[clinic input]
605_io.FileIO.readinto
606 buffer: Py_buffer(types={'rwbuffer'})
607 /
608
609Same as RawIOBase.readinto().
610[clinic start generated code]*/
611
Guido van Rossuma9e20242007-03-08 00:43:48 +0000612static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300613_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer)
614/*[clinic end generated code: output=b01a5a22c8415cb4 input=5edd8327498d468c]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000615{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100616 Py_ssize_t n;
617 int err;
Guido van Rossum53807da2007-04-10 19:01:47 +0000618
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000619 if (self->fd < 0)
620 return err_closed();
621 if (!self->readable)
622 return err_mode("reading");
Guido van Rossum53807da2007-04-10 19:01:47 +0000623
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300624 n = _Py_read(self->fd, buffer->buf, buffer->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100625 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100626 err = errno;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100627
628 if (n == -1) {
629 if (err == EAGAIN) {
630 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000631 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100632 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000633 return NULL;
634 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000635
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000636 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000637}
638
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000639static size_t
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100640new_buffersize(fileio *self, size_t currentsize)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641{
Antoine Pitroua3f44572012-04-17 13:50:58 +0200642 size_t addend;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100643
Nadeem Vawdad41a98b2011-10-13 13:34:16 +0200644 /* Expand the buffer by an amount proportional to the current size,
Antoine Pitroua3f44572012-04-17 13:50:58 +0200645 giving us amortized linear-time behavior. For bigger sizes, use a
646 less-than-double growth factor to avoid excessive allocation. */
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100647 assert(currentsize <= PY_SSIZE_T_MAX);
Antoine Pitroua3f44572012-04-17 13:50:58 +0200648 if (currentsize > 65536)
649 addend = currentsize >> 3;
650 else
651 addend = 256 + currentsize;
652 if (addend < SMALLCHUNK)
653 /* Avoid tiny read() calls. */
654 addend = SMALLCHUNK;
655 return addend + currentsize;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656}
657
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300658/*[clinic input]
659_io.FileIO.readall
660
661Read all data from the file, returned as bytes.
662
663In non-blocking mode, returns as much as is immediately available,
664or None if no data is available. Return an empty bytes object at EOF.
665[clinic start generated code]*/
666
Guido van Rossum7165cb12007-07-10 06:54:34 +0000667static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300668_io_FileIO_readall_impl(fileio *self)
669/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/
Guido van Rossum7165cb12007-07-10 06:54:34 +0000670{
Victor Stinnere134a7f2015-03-30 10:09:31 +0200671 struct _Py_stat_struct status;
Victor Stinnera2a64772011-10-11 22:45:02 +0200672 Py_off_t pos, end;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000673 PyObject *result;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100674 Py_ssize_t bytes_read = 0;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100675 Py_ssize_t n;
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100676 size_t bufsize;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000677
Victor Stinnerb79f28c2011-05-25 22:09:03 +0200678 if (self->fd < 0)
679 return err_closed();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000680 if (!_PyVerify_fd(self->fd))
681 return PyErr_SetFromErrno(PyExc_IOError);
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000682
Steve Dower8fc89802015-04-12 00:26:27 -0400683 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200684#ifdef MS_WINDOWS
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200685 pos = _lseeki64(self->fd, 0L, SEEK_CUR);
686#else
687 pos = lseek(self->fd, 0L, SEEK_CUR);
688#endif
Steve Dower8fc89802015-04-12 00:26:27 -0400689 _Py_END_SUPPRESS_IPH
690
Victor Stinnere134a7f2015-03-30 10:09:31 +0200691 if (_Py_fstat_noraise(self->fd, &status) == 0)
692 end = status.st_size;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200693 else
Victor Stinnera2a64772011-10-11 22:45:02 +0200694 end = (Py_off_t)-1;
Christian Heimesa872de52008-12-05 08:26:55 +0000695
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100696 if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) {
697 /* This is probably a real file, so we try to allocate a
698 buffer one byte larger than the rest of the file. If the
699 calculation is right then we should get EOF without having
700 to enlarge the buffer. */
701 bufsize = (size_t)(end - pos + 1);
702 } else {
703 bufsize = SMALLCHUNK;
704 }
705
706 result = PyBytes_FromStringAndSize(NULL, bufsize);
707 if (result == NULL)
708 return NULL;
709
710 while (1) {
711 if (bytes_read >= (Py_ssize_t)bufsize) {
712 bufsize = new_buffersize(self, bytes_read);
713 if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) {
714 PyErr_SetString(PyExc_OverflowError,
715 "unbounded read returned more bytes "
Serhiy Storchakab817b772015-04-10 02:18:44 +0300716 "than a Python bytes object can hold");
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100717 Py_DECREF(result);
718 return NULL;
719 }
720
721 if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) {
722 if (_PyBytes_Resize(&result, bufsize) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000723 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000724 }
725 }
Victor Stinner9672da72015-03-04 18:40:10 +0100726
Victor Stinner66aab0c2015-03-19 22:53:20 +0100727 n = _Py_read(self->fd,
728 PyBytes_AS_STRING(result) + bytes_read,
729 bufsize - bytes_read);
Victor Stinner9672da72015-03-04 18:40:10 +0100730
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000731 if (n == 0)
732 break;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100733 if (n == -1) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000734 if (errno == EAGAIN) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100735 PyErr_Clear();
Victor Stinnere10920f2014-07-02 22:59:31 +0200736 if (bytes_read > 0)
737 break;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000738 Py_DECREF(result);
739 Py_RETURN_NONE;
740 }
741 Py_DECREF(result);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000742 return NULL;
743 }
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100744 bytes_read += n;
Victor Stinnere9d44ccb2011-05-26 00:16:44 +0200745 pos += n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000746 }
Guido van Rossum7165cb12007-07-10 06:54:34 +0000747
Richard Oudkerkaf7260e2013-05-17 23:34:42 +0100748 if (PyBytes_GET_SIZE(result) > bytes_read) {
749 if (_PyBytes_Resize(&result, bytes_read) < 0)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000750 return NULL;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000751 }
752 return result;
Guido van Rossum7165cb12007-07-10 06:54:34 +0000753}
754
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300755/*[clinic input]
756_io.FileIO.read
757 size: io_ssize_t = -1
758 /
759
760Read at most size bytes, returned as bytes.
761
762Only makes one system call, so less data may be returned than requested.
763In non-blocking mode, returns None if no data is available.
764Return an empty bytes object at EOF.
765[clinic start generated code]*/
766
Guido van Rossuma9e20242007-03-08 00:43:48 +0000767static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300768_io_FileIO_read_impl(fileio *self, Py_ssize_t size)
769/*[clinic end generated code: output=42528d39dd0ca641 input=5c6caa5490c13a9b]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000770{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000771 char *ptr;
772 Py_ssize_t n;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000773 PyObject *bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000774
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000775 if (self->fd < 0)
776 return err_closed();
777 if (!self->readable)
778 return err_mode("reading");
Guido van Rossuma9e20242007-03-08 00:43:48 +0000779
Victor Stinner66aab0c2015-03-19 22:53:20 +0100780 if (size < 0)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300781 return _io_FileIO_readall_impl(self);
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000782
Victor Stinner14b9b112013-06-25 00:37:25 +0200783#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +0100784 /* On Windows, the count parameter of read() is an int */
Victor Stinnerc655a722011-07-05 11:31:49 +0200785 if (size > INT_MAX)
786 size = INT_MAX;
787#endif
Victor Stinner66aab0c2015-03-19 22:53:20 +0100788
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000789 bytes = PyBytes_FromStringAndSize(NULL, size);
790 if (bytes == NULL)
791 return NULL;
792 ptr = PyBytes_AS_STRING(bytes);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000793
Victor Stinner66aab0c2015-03-19 22:53:20 +0100794 n = _Py_read(self->fd, ptr, size);
795 if (n == -1) {
796 /* copy errno because Py_DECREF() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100797 int err = errno;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000798 Py_DECREF(bytes);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100799 if (err == EAGAIN) {
800 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000801 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100802 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000803 return NULL;
804 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000805
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000806 if (n != size) {
807 if (_PyBytes_Resize(&bytes, n) < 0) {
Victor Stinner85c761d2013-07-16 21:36:02 +0200808 Py_CLEAR(bytes);
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000809 return NULL;
810 }
811 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000812
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000813 return (PyObject *) bytes;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000814}
815
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300816/*[clinic input]
817_io.FileIO.write
818 b: Py_buffer
819 /
820
821Write bytes b to file, return number written.
822
823Only makes one system call, so not all of the data may be written.
824The number of bytes actually written is returned. In non-blocking mode,
825returns None if the write would block.
826[clinic start generated code]*/
827
Guido van Rossuma9e20242007-03-08 00:43:48 +0000828static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300829_io_FileIO_write_impl(fileio *self, Py_buffer *b)
830/*[clinic end generated code: output=b4059db3d363a2f7 input=ffbd8834f447ac31]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000831{
Victor Stinner66aab0c2015-03-19 22:53:20 +0100832 Py_ssize_t n;
833 int err;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000834
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000835 if (self->fd < 0)
836 return err_closed();
837 if (!self->writable)
838 return err_mode("writing");
Guido van Rossum53807da2007-04-10 19:01:47 +0000839
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300840 n = _Py_write(self->fd, b->buf, b->len);
Victor Stinner66aab0c2015-03-19 22:53:20 +0100841 /* copy errno because PyBuffer_Release() can indirectly modify it */
Antoine Pitrouc345ce12011-12-16 12:28:32 +0100842 err = errno;
Martin v. Löwis423be952008-08-13 15:53:07 +0000843
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000844 if (n < 0) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100845 if (err == EAGAIN) {
846 PyErr_Clear();
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000847 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100848 }
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000849 return NULL;
850 }
Guido van Rossuma9e20242007-03-08 00:43:48 +0000851
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000852 return PyLong_FromSsize_t(n);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000853}
854
Guido van Rossum53807da2007-04-10 19:01:47 +0000855/* XXX Windows support below is likely incomplete */
856
Guido van Rossum53807da2007-04-10 19:01:47 +0000857/* Cribbed from posix_lseek() */
858static PyObject *
859portable_lseek(int fd, PyObject *posobj, int whence)
860{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000861 Py_off_t pos, res;
Guido van Rossum53807da2007-04-10 19:01:47 +0000862
863#ifdef SEEK_SET
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000864 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
865 switch (whence) {
Guido van Rossum53807da2007-04-10 19:01:47 +0000866#if SEEK_SET != 0
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000867 case 0: whence = SEEK_SET; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000868#endif
869#if SEEK_CUR != 1
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000870 case 1: whence = SEEK_CUR; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000871#endif
Antoine Pitrou4f7945f2009-01-20 11:42:11 +0000872#if SEEK_END != 2
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000873 case 2: whence = SEEK_END; break;
Guido van Rossum53807da2007-04-10 19:01:47 +0000874#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000875 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000876#endif /* SEEK_SET */
877
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000878 if (posobj == NULL)
879 pos = 0;
880 else {
881 if(PyFloat_Check(posobj)) {
882 PyErr_SetString(PyExc_TypeError, "an integer is required");
883 return NULL;
884 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000885#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000886 pos = PyLong_AsLongLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000887#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000888 pos = PyLong_AsLong(posobj);
Guido van Rossum53807da2007-04-10 19:01:47 +0000889#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000890 if (PyErr_Occurred())
891 return NULL;
892 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000893
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000894 if (_PyVerify_fd(fd)) {
895 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -0400896 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +0200897#ifdef MS_WINDOWS
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000898 res = _lseeki64(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000899#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000900 res = lseek(fd, pos, whence);
Guido van Rossum53807da2007-04-10 19:01:47 +0000901#endif
Steve Dower8fc89802015-04-12 00:26:27 -0400902 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000903 Py_END_ALLOW_THREADS
904 } else
905 res = -1;
906 if (res < 0)
907 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum53807da2007-04-10 19:01:47 +0000908
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000909#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000910 return PyLong_FromLongLong(res);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000911#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000912 return PyLong_FromLong(res);
Guido van Rossum53807da2007-04-10 19:01:47 +0000913#endif
914}
915
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300916/*[clinic input]
917_io.FileIO.seek
918 pos: object
919 whence: int = 0
920 /
Guido van Rossuma9e20242007-03-08 00:43:48 +0000921
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300922Move to new file position and return the file position.
923
924Argument offset is a byte count. Optional argument whence defaults to
925SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
926are SEEK_CUR or 1 (move relative to current position, positive or negative),
927and SEEK_END or 2 (move relative to end of file, usually negative, although
928many platforms allow seeking beyond the end of a file).
929
930Note that not all file objects are seekable.
931[clinic start generated code]*/
932
933static PyObject *
934_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
935/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/
936{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000937 if (self->fd < 0)
938 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000939
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300940 return portable_lseek(self->fd, pos, whence);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000941}
942
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300943/*[clinic input]
944_io.FileIO.tell
945
946Current file position.
947
948Can raise OSError for non seekable files.
949[clinic start generated code]*/
950
Guido van Rossuma9e20242007-03-08 00:43:48 +0000951static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300952_io_FileIO_tell_impl(fileio *self)
953/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000954{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000955 if (self->fd < 0)
956 return err_closed();
Guido van Rossuma9e20242007-03-08 00:43:48 +0000957
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000958 return portable_lseek(self->fd, NULL, 1);
Guido van Rossuma9e20242007-03-08 00:43:48 +0000959}
960
Thomas Hellerc6a55ee2007-07-11 12:45:46 +0000961#ifdef HAVE_FTRUNCATE
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300962/*[clinic input]
963_io.FileIO.truncate
964 size as posobj: object = NULL
965 /
966
967Truncate the file to at most size bytes and return the truncated size.
968
969Size defaults to the current file position, as returned by tell().
970The current file position is changed to the value of size.
971[clinic start generated code]*/
972
Guido van Rossuma9e20242007-03-08 00:43:48 +0000973static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300974_io_FileIO_truncate_impl(fileio *self, PyObject *posobj)
975/*[clinic end generated code: output=e49ca7a916c176fa input=9026af44686b7318]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +0000976{
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000977 Py_off_t pos;
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000978 int ret;
979 int fd;
Guido van Rossuma9e20242007-03-08 00:43:48 +0000980
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000981 fd = self->fd;
982 if (fd < 0)
983 return err_closed();
984 if (!self->writable)
985 return err_mode("writing");
Guido van Rossuma9e20242007-03-08 00:43:48 +0000986
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000987 if (posobj == Py_None || posobj == NULL) {
988 /* Get the current position. */
989 posobj = portable_lseek(fd, NULL, 1);
990 if (posobj == NULL)
991 return NULL;
992 }
993 else {
994 Py_INCREF(posobj);
995 }
Guido van Rossum53807da2007-04-10 19:01:47 +0000996
Antoine Pitrou905a2ff2010-01-31 22:47:27 +0000997#if defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouae4b4722010-05-05 16:31:07 +0000998 pos = PyLong_AsLongLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +0000999#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001000 pos = PyLong_AsLong(posobj);
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001001#endif
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001002 if (PyErr_Occurred()){
1003 Py_DECREF(posobj);
1004 return NULL;
1005 }
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001006
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001007 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04001008 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001009 errno = 0;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001010#ifdef MS_WINDOWS
1011 ret = _chsize_s(fd, pos);
1012#else
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001013 ret = ftruncate(fd, pos);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07001014#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04001015 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001016 Py_END_ALLOW_THREADS
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001017
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001018 if (ret != 0) {
1019 Py_DECREF(posobj);
1020 PyErr_SetFromErrno(PyExc_IOError);
1021 return NULL;
1022 }
Guido van Rossuma9e20242007-03-08 00:43:48 +00001023
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001024 return posobj;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001025}
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00001026#endif /* HAVE_FTRUNCATE */
Guido van Rossum53807da2007-04-10 19:01:47 +00001027
1028static char *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001029mode_string(fileio *self)
Guido van Rossum53807da2007-04-10 19:01:47 +00001030{
Charles-François Natalidc3044c2012-01-09 22:40:02 +01001031 if (self->created) {
1032 if (self->readable)
1033 return "xb+";
1034 else
1035 return "xb";
1036 }
Antoine Pitroue93b63b2013-09-04 20:46:33 +02001037 if (self->appending) {
1038 if (self->readable)
1039 return "ab+";
1040 else
1041 return "ab";
1042 }
1043 else if (self->readable) {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001044 if (self->writable)
1045 return "rb+";
1046 else
1047 return "rb";
1048 }
1049 else
1050 return "wb";
Guido van Rossum53807da2007-04-10 19:01:47 +00001051}
Guido van Rossuma9e20242007-03-08 00:43:48 +00001052
1053static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001054fileio_repr(fileio *self)
Guido van Rossuma9e20242007-03-08 00:43:48 +00001055{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001056 PyObject *nameobj, *res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001057
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001058 if (self->fd < 0)
1059 return PyUnicode_FromFormat("<_io.FileIO [closed]>");
Antoine Pitrou716c4442009-05-23 19:04:03 +00001060
Martin v. Löwis767046a2011-10-14 15:35:36 +02001061 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001062 if (nameobj == NULL) {
1063 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1064 PyErr_Clear();
1065 else
1066 return NULL;
Robert Collins933430a2014-10-18 13:32:43 +13001067 res = PyUnicode_FromFormat(
Serhiy Storchaka4954f9f2014-12-02 23:39:56 +02001068 "<_io.FileIO fd=%d mode='%s' closefd=%s>",
1069 self->fd, mode_string(self), self->closefd ? "True" : "False");
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001070 }
1071 else {
Robert Collins933430a2014-10-18 13:32:43 +13001072 res = PyUnicode_FromFormat(
Serhiy Storchaka4954f9f2014-12-02 23:39:56 +02001073 "<_io.FileIO name=%R mode='%s' closefd=%s>",
1074 nameobj, mode_string(self), self->closefd ? "True" : "False");
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001075 Py_DECREF(nameobj);
1076 }
1077 return res;
Guido van Rossuma9e20242007-03-08 00:43:48 +00001078}
1079
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001080/*[clinic input]
1081_io.FileIO.isatty
1082
1083True if the file is connected to a TTY device.
1084[clinic start generated code]*/
1085
Guido van Rossuma9e20242007-03-08 00:43:48 +00001086static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001087_io_FileIO_isatty_impl(fileio *self)
1088/*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/
Guido van Rossuma9e20242007-03-08 00:43:48 +00001089{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001090 long res;
Guido van Rossum53807da2007-04-10 19:01:47 +00001091
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001092 if (self->fd < 0)
1093 return err_closed();
1094 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001095 _Py_BEGIN_SUPPRESS_IPH
1096 if (_PyVerify_fd(self->fd))
1097 res = isatty(self->fd);
1098 else
1099 res = 0;
1100 _Py_END_SUPPRESS_IPH
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001101 Py_END_ALLOW_THREADS
1102 return PyBool_FromLong(res);
Guido van Rossuma9e20242007-03-08 00:43:48 +00001103}
1104
Antoine Pitrou243757e2010-11-05 21:15:39 +00001105static PyObject *
1106fileio_getstate(fileio *self)
1107{
1108 PyErr_Format(PyExc_TypeError,
1109 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
1110 return NULL;
1111}
1112
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001113#include "clinic/fileio.c.h"
Guido van Rossuma9e20242007-03-08 00:43:48 +00001114
1115static PyMethodDef fileio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001116 _IO_FILEIO_READ_METHODDEF
1117 _IO_FILEIO_READALL_METHODDEF
1118 _IO_FILEIO_READINTO_METHODDEF
1119 _IO_FILEIO_WRITE_METHODDEF
1120 _IO_FILEIO_SEEK_METHODDEF
1121 _IO_FILEIO_TELL_METHODDEF
1122 _IO_FILEIO_TRUNCATE_METHODDEF
1123 _IO_FILEIO_CLOSE_METHODDEF
1124 _IO_FILEIO_SEEKABLE_METHODDEF
1125 _IO_FILEIO_READABLE_METHODDEF
1126 _IO_FILEIO_WRITABLE_METHODDEF
1127 _IO_FILEIO_FILENO_METHODDEF
1128 _IO_FILEIO_ISATTY_METHODDEF
Antoine Pitroue033e062010-10-29 10:38:18 +00001129 {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001130 {"__getstate__", (PyCFunction)fileio_getstate, METH_NOARGS, NULL},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001131 {NULL, NULL} /* sentinel */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001132};
1133
Guido van Rossum53807da2007-04-10 19:01:47 +00001134/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */
1135
Guido van Rossumb0428152007-04-08 17:44:42 +00001136static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001137get_closed(fileio *self, void *closure)
Guido van Rossumb0428152007-04-08 17:44:42 +00001138{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001139 return PyBool_FromLong((long)(self->fd < 0));
Guido van Rossum53807da2007-04-10 19:01:47 +00001140}
1141
1142static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001143get_closefd(fileio *self, void *closure)
Christian Heimesecc42a22008-11-05 19:30:32 +00001144{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001145 return PyBool_FromLong((long)(self->closefd));
Christian Heimesecc42a22008-11-05 19:30:32 +00001146}
1147
1148static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001149get_mode(fileio *self, void *closure)
Guido van Rossum53807da2007-04-10 19:01:47 +00001150{
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001151 return PyUnicode_FromString(mode_string(self));
Guido van Rossumb0428152007-04-08 17:44:42 +00001152}
1153
1154static PyGetSetDef fileio_getsetlist[] = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001155 {"closed", (getter)get_closed, NULL, "True if the file is closed"},
1156 {"closefd", (getter)get_closefd, NULL,
Serhiy Storchaka3d2279f2015-04-10 16:08:43 +03001157 "True if the file descriptor will be closed by close()."},
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001158 {"mode", (getter)get_mode, NULL, "String giving the file mode"},
1159 {NULL},
Guido van Rossumb0428152007-04-08 17:44:42 +00001160};
1161
Antoine Pitrou796564c2013-07-30 19:59:21 +02001162static PyMemberDef fileio_members[] = {
Antoine Pitroude687222014-06-29 20:07:28 -04001163 {"_blksize", T_UINT, offsetof(fileio, blksize), 0},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001164 {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
1165 {NULL}
1166};
1167
Guido van Rossuma9e20242007-03-08 00:43:48 +00001168PyTypeObject PyFileIO_Type = {
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001169 PyVarObject_HEAD_INIT(NULL, 0)
1170 "_io.FileIO",
1171 sizeof(fileio),
1172 0,
1173 (destructor)fileio_dealloc, /* tp_dealloc */
1174 0, /* tp_print */
1175 0, /* tp_getattr */
1176 0, /* tp_setattr */
1177 0, /* tp_reserved */
1178 (reprfunc)fileio_repr, /* tp_repr */
1179 0, /* tp_as_number */
1180 0, /* tp_as_sequence */
1181 0, /* tp_as_mapping */
1182 0, /* tp_hash */
1183 0, /* tp_call */
1184 0, /* tp_str */
1185 PyObject_GenericGetAttr, /* tp_getattro */
1186 0, /* tp_setattro */
1187 0, /* tp_as_buffer */
1188 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001189 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001190 _io_FileIO___init____doc__, /* tp_doc */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001191 (traverseproc)fileio_traverse, /* tp_traverse */
1192 (inquiry)fileio_clear, /* tp_clear */
1193 0, /* tp_richcompare */
1194 offsetof(fileio, weakreflist), /* tp_weaklistoffset */
1195 0, /* tp_iter */
1196 0, /* tp_iternext */
1197 fileio_methods, /* tp_methods */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001198 fileio_members, /* tp_members */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001199 fileio_getsetlist, /* tp_getset */
1200 0, /* tp_base */
1201 0, /* tp_dict */
1202 0, /* tp_descr_get */
1203 0, /* tp_descr_set */
1204 offsetof(fileio, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001205 _io_FileIO___init__, /* tp_init */
Antoine Pitrouae4b4722010-05-05 16:31:07 +00001206 PyType_GenericAlloc, /* tp_alloc */
1207 fileio_new, /* tp_new */
1208 PyObject_GC_Del, /* tp_free */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001209 0, /* tp_is_gc */
1210 0, /* tp_bases */
1211 0, /* tp_mro */
1212 0, /* tp_cache */
1213 0, /* tp_subclasses */
1214 0, /* tp_weaklist */
1215 0, /* tp_del */
1216 0, /* tp_version_tag */
1217 0, /* tp_finalize */
Guido van Rossuma9e20242007-03-08 00:43:48 +00001218};