Manual py3k backport: [svn r74158] Issue #6218: Make io.BytesIO and io.StringIO pickl...
[python.git] / Modules / _io / fileio.c
blobe98de9e69faff16663623fe2c60462652c8ef1d8
1 /* Author: Daniel Stutzbach */
3 #define PY_SSIZE_T_CLEAN
4 #include "Python.h"
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
8 #include <stddef.h> /* For offsetof */
9 #include "_iomodule.h"
12 * Known likely problems:
14 * - Files larger then 2**32-1
15 * - Files with unicode filenames
16 * - Passing numbers greater than 2**32-1 when an integer is expected
17 * - Making it work on Windows and other oddball platforms
19 * To Do:
21 * - autoconfify header file inclusion
24 #ifdef MS_WINDOWS
25 /* can simulate truncate with Win32 API functions; see file_truncate */
26 #define HAVE_FTRUNCATE
27 #define WIN32_LEAN_AND_MEAN
28 #include <windows.h>
29 #endif
31 #if BUFSIZ < (8*1024)
32 #define SMALLCHUNK (8*1024)
33 #elif (BUFSIZ >= (2 << 25))
34 #error "unreasonable BUFSIZ > 64MB defined"
35 #else
36 #define SMALLCHUNK BUFSIZ
37 #endif
39 #if SIZEOF_INT < 4
40 #define BIGCHUNK (512 * 32)
41 #else
42 #define BIGCHUNK (512 * 1024)
43 #endif
45 typedef struct {
46 PyObject_HEAD
47 int fd;
48 unsigned int readable : 1;
49 unsigned int writable : 1;
50 signed int seekable : 2; /* -1 means unknown */
51 unsigned int closefd : 1;
52 PyObject *weakreflist;
53 PyObject *dict;
54 } fileio;
56 PyTypeObject PyFileIO_Type;
58 #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
60 int
61 _PyFileIO_closed(PyObject *self)
63 return ((fileio *)self)->fd < 0;
66 static PyObject *
67 portable_lseek(int fd, PyObject *posobj, int whence);
69 static PyObject *portable_lseek(int fd, PyObject *posobj, int whence);
71 /* Returns 0 on success, -1 with exception set on failure. */
72 static int
73 internal_close(fileio *self)
75 int err = 0;
76 int save_errno = 0;
77 if (self->fd >= 0) {
78 int fd = self->fd;
79 self->fd = -1;
80 /* fd is accessible and someone else may have closed it */
81 if (_PyVerify_fd(fd)) {
82 Py_BEGIN_ALLOW_THREADS
83 err = close(fd);
84 if (err < 0)
85 save_errno = errno;
86 Py_END_ALLOW_THREADS
87 } else {
88 save_errno = errno;
89 err = -1;
92 if (err < 0) {
93 errno = save_errno;
94 PyErr_SetFromErrno(PyExc_IOError);
95 return -1;
97 return 0;
100 static PyObject *
101 fileio_close(fileio *self)
103 if (!self->closefd) {
104 self->fd = -1;
105 Py_RETURN_NONE;
107 errno = internal_close(self);
108 if (errno < 0)
109 return NULL;
111 return PyObject_CallMethod((PyObject*)&PyRawIOBase_Type,
112 "close", "O", self);
115 static PyObject *
116 fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
118 fileio *self;
120 assert(type != NULL && type->tp_alloc != NULL);
122 self = (fileio *) type->tp_alloc(type, 0);
123 if (self != NULL) {
124 self->fd = -1;
125 self->readable = 0;
126 self->writable = 0;
127 self->seekable = -1;
128 self->closefd = 1;
129 self->weakreflist = NULL;
132 return (PyObject *) self;
135 /* On Unix, open will succeed for directories.
136 In Python, there should be no file objects referring to
137 directories, so we need a check. */
139 static int
140 dircheck(fileio* self, const char *name)
142 #if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
143 struct stat buf;
144 if (self->fd < 0)
145 return 0;
146 if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
147 char *msg = strerror(EISDIR);
148 PyObject *exc;
149 if (internal_close(self))
150 return -1;
152 exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
153 EISDIR, msg, name);
154 PyErr_SetObject(PyExc_IOError, exc);
155 Py_XDECREF(exc);
156 return -1;
158 #endif
159 return 0;
162 static int
163 check_fd(int fd)
165 #if defined(HAVE_FSTAT)
166 struct stat buf;
167 if (!_PyVerify_fd(fd) || (fstat(fd, &buf) < 0 && errno == EBADF)) {
168 PyObject *exc;
169 char *msg = strerror(EBADF);
170 exc = PyObject_CallFunction(PyExc_OSError, "(is)",
171 EBADF, msg);
172 PyErr_SetObject(PyExc_OSError, exc);
173 Py_XDECREF(exc);
174 return -1;
176 #endif
177 return 0;
181 static int
182 fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
184 fileio *self = (fileio *) oself;
185 static char *kwlist[] = {"file", "mode", "closefd", NULL};
186 const char *name = NULL;
187 PyObject *nameobj, *stringobj = NULL;
188 char *mode = "r";
189 char *s;
190 #ifdef MS_WINDOWS
191 Py_UNICODE *widename = NULL;
192 #endif
193 int ret = 0;
194 int rwa = 0, plus = 0, append = 0;
195 int flags = 0;
196 int fd = -1;
197 int closefd = 1;
199 assert(PyFileIO_Check(oself));
200 if (self->fd >= 0) {
201 /* Have to close the existing file first. */
202 if (internal_close(self) < 0)
203 return -1;
206 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|si:fileio",
207 kwlist, &nameobj, &mode, &closefd))
208 return -1;
210 if (PyFloat_Check(nameobj)) {
211 PyErr_SetString(PyExc_TypeError,
212 "integer argument expected, got float");
213 return -1;
216 fd = PyLong_AsLong(nameobj);
217 if (fd < 0) {
218 if (!PyErr_Occurred()) {
219 PyErr_SetString(PyExc_ValueError,
220 "Negative filedescriptor");
221 return -1;
223 PyErr_Clear();
226 #ifdef MS_WINDOWS
227 if (PyUnicode_Check(nameobj))
228 widename = PyUnicode_AS_UNICODE(nameobj);
229 if (widename == NULL)
230 #endif
231 if (fd < 0)
233 if (PyBytes_Check(nameobj) || PyByteArray_Check(nameobj)) {
234 Py_ssize_t namelen;
235 if (PyObject_AsCharBuffer(nameobj, &name, &namelen) < 0)
236 return -1;
238 else {
239 PyObject *u = PyUnicode_FromObject(nameobj);
241 if (u == NULL)
242 return -1;
244 stringobj = PyUnicode_AsEncodedString(
245 u, Py_FileSystemDefaultEncoding, "surrogateescape");
246 Py_DECREF(u);
247 if (stringobj == NULL)
248 return -1;
249 if (!PyBytes_Check(stringobj)) {
250 PyErr_SetString(PyExc_TypeError,
251 "encoder failed to return bytes");
252 goto error;
254 name = PyBytes_AS_STRING(stringobj);
258 s = mode;
259 while (*s) {
260 switch (*s++) {
261 case 'r':
262 if (rwa) {
263 bad_mode:
264 PyErr_SetString(PyExc_ValueError,
265 "Must have exactly one of read/write/append mode");
266 goto error;
268 rwa = 1;
269 self->readable = 1;
270 break;
271 case 'w':
272 if (rwa)
273 goto bad_mode;
274 rwa = 1;
275 self->writable = 1;
276 flags |= O_CREAT | O_TRUNC;
277 break;
278 case 'a':
279 if (rwa)
280 goto bad_mode;
281 rwa = 1;
282 self->writable = 1;
283 flags |= O_CREAT;
284 append = 1;
285 break;
286 case 'b':
287 break;
288 case '+':
289 if (plus)
290 goto bad_mode;
291 self->readable = self->writable = 1;
292 plus = 1;
293 break;
294 default:
295 PyErr_Format(PyExc_ValueError,
296 "invalid mode: %.200s", mode);
297 goto error;
301 if (!rwa)
302 goto bad_mode;
304 if (self->readable && self->writable)
305 flags |= O_RDWR;
306 else if (self->readable)
307 flags |= O_RDONLY;
308 else
309 flags |= O_WRONLY;
311 #ifdef O_BINARY
312 flags |= O_BINARY;
313 #endif
315 #ifdef O_APPEND
316 if (append)
317 flags |= O_APPEND;
318 #endif
320 if (fd >= 0) {
321 if (check_fd(fd))
322 goto error;
323 self->fd = fd;
324 self->closefd = closefd;
326 else {
327 self->closefd = 1;
328 if (!closefd) {
329 PyErr_SetString(PyExc_ValueError,
330 "Cannot use closefd=False with file name");
331 goto error;
334 Py_BEGIN_ALLOW_THREADS
335 errno = 0;
336 #ifdef MS_WINDOWS
337 if (widename != NULL)
338 self->fd = _wopen(widename, flags, 0666);
339 else
340 #endif
341 self->fd = open(name, flags, 0666);
342 Py_END_ALLOW_THREADS
343 if (self->fd < 0) {
344 #ifdef MS_WINDOWS
345 if (widename != NULL)
346 PyErr_SetFromErrnoWithUnicodeFilename(PyExc_IOError, widename);
347 else
348 #endif
349 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
350 goto error;
352 if(dircheck(self, name) < 0)
353 goto error;
356 if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0)
357 goto error;
359 if (append) {
360 /* For consistent behaviour, we explicitly seek to the
361 end of file (otherwise, it might be done only on the
362 first write()). */
363 PyObject *pos = portable_lseek(self->fd, NULL, 2);
364 if (pos == NULL)
365 goto error;
366 Py_DECREF(pos);
369 goto done;
371 error:
372 ret = -1;
374 done:
375 Py_CLEAR(stringobj);
376 return ret;
379 static int
380 fileio_traverse(fileio *self, visitproc visit, void *arg)
382 Py_VISIT(self->dict);
383 return 0;
386 static int
387 fileio_clear(fileio *self)
389 Py_CLEAR(self->dict);
390 return 0;
393 static void
394 fileio_dealloc(fileio *self)
396 if (_PyIOBase_finalize((PyObject *) self) < 0)
397 return;
398 _PyObject_GC_UNTRACK(self);
399 if (self->weakreflist != NULL)
400 PyObject_ClearWeakRefs((PyObject *) self);
401 Py_CLEAR(self->dict);
402 Py_TYPE(self)->tp_free((PyObject *)self);
405 static PyObject *
406 err_closed(void)
408 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
409 return NULL;
412 static PyObject *
413 err_mode(char *action)
415 PyErr_Format(PyExc_ValueError, "File not open for %s", action);
416 return NULL;
419 static PyObject *
420 fileio_fileno(fileio *self)
422 if (self->fd < 0)
423 return err_closed();
424 return PyInt_FromLong((long) self->fd);
427 static PyObject *
428 fileio_readable(fileio *self)
430 if (self->fd < 0)
431 return err_closed();
432 return PyBool_FromLong((long) self->readable);
435 static PyObject *
436 fileio_writable(fileio *self)
438 if (self->fd < 0)
439 return err_closed();
440 return PyBool_FromLong((long) self->writable);
443 static PyObject *
444 fileio_seekable(fileio *self)
446 if (self->fd < 0)
447 return err_closed();
448 if (self->seekable < 0) {
449 PyObject *pos = portable_lseek(self->fd, NULL, SEEK_CUR);
450 if (pos == NULL) {
451 PyErr_Clear();
452 self->seekable = 0;
453 } else {
454 Py_DECREF(pos);
455 self->seekable = 1;
458 return PyBool_FromLong((long) self->seekable);
461 static PyObject *
462 fileio_readinto(fileio *self, PyObject *args)
464 Py_buffer pbuf;
465 Py_ssize_t n;
467 if (self->fd < 0)
468 return err_closed();
469 if (!self->readable)
470 return err_mode("reading");
472 if (!PyArg_ParseTuple(args, "w*", &pbuf))
473 return NULL;
475 if (_PyVerify_fd(self->fd)) {
476 Py_BEGIN_ALLOW_THREADS
477 errno = 0;
478 n = read(self->fd, pbuf.buf, pbuf.len);
479 Py_END_ALLOW_THREADS
480 } else
481 n = -1;
482 PyBuffer_Release(&pbuf);
483 if (n < 0) {
484 if (errno == EAGAIN)
485 Py_RETURN_NONE;
486 PyErr_SetFromErrno(PyExc_IOError);
487 return NULL;
490 return PyLong_FromSsize_t(n);
493 static size_t
494 new_buffersize(fileio *self, size_t currentsize)
496 #ifdef HAVE_FSTAT
497 off_t pos, end;
498 struct stat st;
499 if (fstat(self->fd, &st) == 0) {
500 end = st.st_size;
501 pos = lseek(self->fd, 0L, SEEK_CUR);
502 /* Files claiming a size smaller than SMALLCHUNK may
503 actually be streaming pseudo-files. In this case, we
504 apply the more aggressive algorithm below.
506 if (end >= SMALLCHUNK && end >= pos && pos >= 0) {
507 /* Add 1 so if the file were to grow we'd notice. */
508 return currentsize + end - pos + 1;
511 #endif
512 if (currentsize > SMALLCHUNK) {
513 /* Keep doubling until we reach BIGCHUNK;
514 then keep adding BIGCHUNK. */
515 if (currentsize <= BIGCHUNK)
516 return currentsize + currentsize;
517 else
518 return currentsize + BIGCHUNK;
520 return currentsize + SMALLCHUNK;
523 static PyObject *
524 fileio_readall(fileio *self)
526 PyObject *result;
527 Py_ssize_t total = 0;
528 int n;
530 if (!_PyVerify_fd(self->fd))
531 return PyErr_SetFromErrno(PyExc_IOError);
533 result = PyBytes_FromStringAndSize(NULL, SMALLCHUNK);
534 if (result == NULL)
535 return NULL;
537 while (1) {
538 size_t newsize = new_buffersize(self, total);
539 if (newsize > PY_SSIZE_T_MAX || newsize <= 0) {
540 PyErr_SetString(PyExc_OverflowError,
541 "unbounded read returned more bytes "
542 "than a Python string can hold ");
543 Py_DECREF(result);
544 return NULL;
547 if (PyBytes_GET_SIZE(result) < (Py_ssize_t)newsize) {
548 if (_PyBytes_Resize(&result, newsize) < 0) {
549 if (total == 0) {
550 Py_DECREF(result);
551 return NULL;
553 PyErr_Clear();
554 break;
557 Py_BEGIN_ALLOW_THREADS
558 errno = 0;
559 n = read(self->fd,
560 PyBytes_AS_STRING(result) + total,
561 newsize - total);
562 Py_END_ALLOW_THREADS
563 if (n == 0)
564 break;
565 if (n < 0) {
566 if (total > 0)
567 break;
568 if (errno == EAGAIN) {
569 Py_DECREF(result);
570 Py_RETURN_NONE;
572 Py_DECREF(result);
573 PyErr_SetFromErrno(PyExc_IOError);
574 return NULL;
576 total += n;
579 if (PyBytes_GET_SIZE(result) > total) {
580 if (_PyBytes_Resize(&result, total) < 0) {
581 /* This should never happen, but just in case */
582 Py_DECREF(result);
583 return NULL;
586 return result;
589 static PyObject *
590 fileio_read(fileio *self, PyObject *args)
592 char *ptr;
593 Py_ssize_t n;
594 Py_ssize_t size = -1;
595 PyObject *bytes;
597 if (self->fd < 0)
598 return err_closed();
599 if (!self->readable)
600 return err_mode("reading");
602 if (!PyArg_ParseTuple(args, "|n", &size))
603 return NULL;
605 if (size < 0) {
606 return fileio_readall(self);
609 bytes = PyBytes_FromStringAndSize(NULL, size);
610 if (bytes == NULL)
611 return NULL;
612 ptr = PyBytes_AS_STRING(bytes);
614 if (_PyVerify_fd(self->fd)) {
615 Py_BEGIN_ALLOW_THREADS
616 errno = 0;
617 n = read(self->fd, ptr, size);
618 Py_END_ALLOW_THREADS
619 } else
620 n = -1;
622 if (n < 0) {
623 Py_DECREF(bytes);
624 if (errno == EAGAIN)
625 Py_RETURN_NONE;
626 PyErr_SetFromErrno(PyExc_IOError);
627 return NULL;
630 if (n != size) {
631 if (_PyBytes_Resize(&bytes, n) < 0) {
632 Py_DECREF(bytes);
633 return NULL;
637 return (PyObject *) bytes;
640 static PyObject *
641 fileio_write(fileio *self, PyObject *args)
643 Py_buffer pbuf;
644 Py_ssize_t n;
646 if (self->fd < 0)
647 return err_closed();
648 if (!self->writable)
649 return err_mode("writing");
651 if (!PyArg_ParseTuple(args, "s*", &pbuf))
652 return NULL;
654 if (_PyVerify_fd(self->fd)) {
655 Py_BEGIN_ALLOW_THREADS
656 errno = 0;
657 n = write(self->fd, pbuf.buf, pbuf.len);
658 Py_END_ALLOW_THREADS
659 } else
660 n = -1;
662 PyBuffer_Release(&pbuf);
664 if (n < 0) {
665 if (errno == EAGAIN)
666 Py_RETURN_NONE;
667 PyErr_SetFromErrno(PyExc_IOError);
668 return NULL;
671 return PyLong_FromSsize_t(n);
674 /* XXX Windows support below is likely incomplete */
676 /* Cribbed from posix_lseek() */
677 static PyObject *
678 portable_lseek(int fd, PyObject *posobj, int whence)
680 Py_off_t pos, res;
682 #ifdef SEEK_SET
683 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
684 switch (whence) {
685 #if SEEK_SET != 0
686 case 0: whence = SEEK_SET; break;
687 #endif
688 #if SEEK_CUR != 1
689 case 1: whence = SEEK_CUR; break;
690 #endif
691 #if SEEK_END != 2
692 case 2: whence = SEEK_END; break;
693 #endif
695 #endif /* SEEK_SET */
697 if (posobj == NULL)
698 pos = 0;
699 else {
700 if(PyFloat_Check(posobj)) {
701 PyErr_SetString(PyExc_TypeError, "an integer is required");
702 return NULL;
704 #if defined(HAVE_LARGEFILE_SUPPORT)
705 pos = PyLong_AsLongLong(posobj);
706 #else
707 pos = PyLong_AsLong(posobj);
708 #endif
709 if (PyErr_Occurred())
710 return NULL;
713 if (_PyVerify_fd(fd)) {
714 Py_BEGIN_ALLOW_THREADS
715 #if defined(MS_WIN64) || defined(MS_WINDOWS)
716 res = _lseeki64(fd, pos, whence);
717 #else
718 res = lseek(fd, pos, whence);
719 #endif
720 Py_END_ALLOW_THREADS
721 } else
722 res = -1;
723 if (res < 0)
724 return PyErr_SetFromErrno(PyExc_IOError);
726 #if defined(HAVE_LARGEFILE_SUPPORT)
727 return PyLong_FromLongLong(res);
728 #else
729 return PyLong_FromLong(res);
730 #endif
733 static PyObject *
734 fileio_seek(fileio *self, PyObject *args)
736 PyObject *posobj;
737 int whence = 0;
739 if (self->fd < 0)
740 return err_closed();
742 if (!PyArg_ParseTuple(args, "O|i", &posobj, &whence))
743 return NULL;
745 return portable_lseek(self->fd, posobj, whence);
748 static PyObject *
749 fileio_tell(fileio *self, PyObject *args)
751 if (self->fd < 0)
752 return err_closed();
754 return portable_lseek(self->fd, NULL, 1);
757 #ifdef HAVE_FTRUNCATE
758 static PyObject *
759 fileio_truncate(fileio *self, PyObject *args)
761 PyObject *posobj = NULL;
762 Py_off_t pos;
763 int ret;
764 int fd;
766 fd = self->fd;
767 if (fd < 0)
768 return err_closed();
769 if (!self->writable)
770 return err_mode("writing");
772 if (!PyArg_ParseTuple(args, "|O", &posobj))
773 return NULL;
775 if (posobj == Py_None || posobj == NULL) {
776 /* Get the current position. */
777 posobj = portable_lseek(fd, NULL, 1);
778 if (posobj == NULL)
779 return NULL;
781 else {
782 /* Move to the position to be truncated. */
783 posobj = portable_lseek(fd, posobj, 0);
785 if (posobj == NULL)
786 return NULL;
788 #if defined(HAVE_LARGEFILE_SUPPORT)
789 pos = PyLong_AsLongLong(posobj);
790 #else
791 pos = PyLong_AsLong(posobj);
792 #endif
793 if (pos == -1 && PyErr_Occurred())
794 return NULL;
796 #ifdef MS_WINDOWS
797 /* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
798 so don't even try using it. */
800 HANDLE hFile;
802 /* Truncate. Note that this may grow the file! */
803 Py_BEGIN_ALLOW_THREADS
804 errno = 0;
805 hFile = (HANDLE)_get_osfhandle(fd);
806 ret = hFile == (HANDLE)-1;
807 if (ret == 0) {
808 ret = SetEndOfFile(hFile) == 0;
809 if (ret)
810 errno = EACCES;
812 Py_END_ALLOW_THREADS
814 #else
815 Py_BEGIN_ALLOW_THREADS
816 errno = 0;
817 ret = ftruncate(fd, pos);
818 Py_END_ALLOW_THREADS
819 #endif /* !MS_WINDOWS */
821 if (ret != 0) {
822 PyErr_SetFromErrno(PyExc_IOError);
823 return NULL;
826 return posobj;
828 #endif
830 static char *
831 mode_string(fileio *self)
833 if (self->readable) {
834 if (self->writable)
835 return "rb+";
836 else
837 return "rb";
839 else
840 return "wb";
843 static PyObject *
844 fileio_repr(fileio *self)
846 PyObject *nameobj, *res;
848 if (self->fd < 0)
849 return PyString_FromFormat("<_io.FileIO [closed]>");
851 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
852 if (nameobj == NULL) {
853 if (PyErr_ExceptionMatches(PyExc_AttributeError))
854 PyErr_Clear();
855 else
856 return NULL;
857 res = PyString_FromFormat("<_io.FileIO fd=%d mode='%s'>",
858 self->fd, mode_string(self));
860 else {
861 PyObject *repr = PyObject_Repr(nameobj);
862 Py_DECREF(nameobj);
863 if (repr == NULL)
864 return NULL;
865 res = PyString_FromFormat("<_io.FileIO name=%s mode='%s'>",
866 PyString_AS_STRING(repr),
867 mode_string(self));
868 Py_DECREF(repr);
870 return res;
873 static PyObject *
874 fileio_isatty(fileio *self)
876 long res;
878 if (self->fd < 0)
879 return err_closed();
880 Py_BEGIN_ALLOW_THREADS
881 res = isatty(self->fd);
882 Py_END_ALLOW_THREADS
883 return PyBool_FromLong(res);
887 PyDoc_STRVAR(fileio_doc,
888 "file(name: str[, mode: str]) -> file IO object\n"
889 "\n"
890 "Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n"
891 "writing or appending. The file will be created if it doesn't exist\n"
892 "when opened for writing or appending; it will be truncated when\n"
893 "opened for writing. Add a '+' to the mode to allow simultaneous\n"
894 "reading and writing.");
896 PyDoc_STRVAR(read_doc,
897 "read(size: int) -> bytes. read at most size bytes, returned as bytes.\n"
898 "\n"
899 "Only makes one system call, so less data may be returned than requested\n"
900 "In non-blocking mode, returns None if no data is available.\n"
901 "On end-of-file, returns ''.");
903 PyDoc_STRVAR(readall_doc,
904 "readall() -> bytes. read all data from the file, returned as bytes.\n"
905 "\n"
906 "In non-blocking mode, returns as much as is immediately available,\n"
907 "or None if no data is available. On end-of-file, returns ''.");
909 PyDoc_STRVAR(write_doc,
910 "write(b: bytes) -> int. Write bytes b to file, return number written.\n"
911 "\n"
912 "Only makes one system call, so not all of the data may be written.\n"
913 "The number of bytes actually written is returned.");
915 PyDoc_STRVAR(fileno_doc,
916 "fileno() -> int. \"file descriptor\".\n"
917 "\n"
918 "This is needed for lower-level file interfaces, such the fcntl module.");
920 PyDoc_STRVAR(seek_doc,
921 "seek(offset: int[, whence: int]) -> None. Move to new file position.\n"
922 "\n"
923 "Argument offset is a byte count. Optional argument whence defaults to\n"
924 "0 (offset from start of file, offset should be >= 0); other values are 1\n"
925 "(move relative to current position, positive or negative), and 2 (move\n"
926 "relative to end of file, usually negative, although many platforms allow\n"
927 "seeking beyond the end of a file)."
928 "\n"
929 "Note that not all file objects are seekable.");
931 #ifdef HAVE_FTRUNCATE
932 PyDoc_STRVAR(truncate_doc,
933 "truncate([size: int]) -> None. Truncate the file to at most size bytes.\n"
934 "\n"
935 "Size defaults to the current file position, as returned by tell()."
936 "The current file position is changed to the value of size.");
937 #endif
939 PyDoc_STRVAR(tell_doc,
940 "tell() -> int. Current file position");
942 PyDoc_STRVAR(readinto_doc,
943 "readinto() -> Same as RawIOBase.readinto().");
945 PyDoc_STRVAR(close_doc,
946 "close() -> None. Close the file.\n"
947 "\n"
948 "A closed file cannot be used for further I/O operations. close() may be\n"
949 "called more than once without error. Changes the fileno to -1.");
951 PyDoc_STRVAR(isatty_doc,
952 "isatty() -> bool. True if the file is connected to a tty device.");
954 PyDoc_STRVAR(seekable_doc,
955 "seekable() -> bool. True if file supports random-access.");
957 PyDoc_STRVAR(readable_doc,
958 "readable() -> bool. True if file was opened in a read mode.");
960 PyDoc_STRVAR(writable_doc,
961 "writable() -> bool. True if file was opened in a write mode.");
963 static PyMethodDef fileio_methods[] = {
964 {"read", (PyCFunction)fileio_read, METH_VARARGS, read_doc},
965 {"readall", (PyCFunction)fileio_readall, METH_NOARGS, readall_doc},
966 {"readinto", (PyCFunction)fileio_readinto, METH_VARARGS, readinto_doc},
967 {"write", (PyCFunction)fileio_write, METH_VARARGS, write_doc},
968 {"seek", (PyCFunction)fileio_seek, METH_VARARGS, seek_doc},
969 {"tell", (PyCFunction)fileio_tell, METH_VARARGS, tell_doc},
970 #ifdef HAVE_FTRUNCATE
971 {"truncate", (PyCFunction)fileio_truncate, METH_VARARGS, truncate_doc},
972 #endif
973 {"close", (PyCFunction)fileio_close, METH_NOARGS, close_doc},
974 {"seekable", (PyCFunction)fileio_seekable, METH_NOARGS, seekable_doc},
975 {"readable", (PyCFunction)fileio_readable, METH_NOARGS, readable_doc},
976 {"writable", (PyCFunction)fileio_writable, METH_NOARGS, writable_doc},
977 {"fileno", (PyCFunction)fileio_fileno, METH_NOARGS, fileno_doc},
978 {"isatty", (PyCFunction)fileio_isatty, METH_NOARGS, isatty_doc},
979 {NULL, NULL} /* sentinel */
982 /* 'closed' and 'mode' are attributes for backwards compatibility reasons. */
984 static PyObject *
985 get_closed(fileio *self, void *closure)
987 return PyBool_FromLong((long)(self->fd < 0));
990 static PyObject *
991 get_closefd(fileio *self, void *closure)
993 return PyBool_FromLong((long)(self->closefd));
996 static PyObject *
997 get_mode(fileio *self, void *closure)
999 return PyUnicode_FromString(mode_string(self));
1002 static PyGetSetDef fileio_getsetlist[] = {
1003 {"closed", (getter)get_closed, NULL, "True if the file is closed"},
1004 {"closefd", (getter)get_closefd, NULL,
1005 "True if the file descriptor will be closed"},
1006 {"mode", (getter)get_mode, NULL, "String giving the file mode"},
1007 {NULL},
1010 PyTypeObject PyFileIO_Type = {
1011 PyVarObject_HEAD_INIT(NULL, 0)
1012 "_io.FileIO",
1013 sizeof(fileio),
1015 (destructor)fileio_dealloc, /* tp_dealloc */
1016 0, /* tp_print */
1017 0, /* tp_getattr */
1018 0, /* tp_setattr */
1019 0, /* tp_reserved */
1020 (reprfunc)fileio_repr, /* tp_repr */
1021 0, /* tp_as_number */
1022 0, /* tp_as_sequence */
1023 0, /* tp_as_mapping */
1024 0, /* tp_hash */
1025 0, /* tp_call */
1026 0, /* tp_str */
1027 PyObject_GenericGetAttr, /* tp_getattro */
1028 0, /* tp_setattro */
1029 0, /* tp_as_buffer */
1030 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1031 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1032 fileio_doc, /* tp_doc */
1033 (traverseproc)fileio_traverse, /* tp_traverse */
1034 (inquiry)fileio_clear, /* tp_clear */
1035 0, /* tp_richcompare */
1036 offsetof(fileio, weakreflist), /* tp_weaklistoffset */
1037 0, /* tp_iter */
1038 0, /* tp_iternext */
1039 fileio_methods, /* tp_methods */
1040 0, /* tp_members */
1041 fileio_getsetlist, /* tp_getset */
1042 0, /* tp_base */
1043 0, /* tp_dict */
1044 0, /* tp_descr_get */
1045 0, /* tp_descr_set */
1046 offsetof(fileio, dict), /* tp_dictoffset */
1047 fileio_init, /* tp_init */
1048 PyType_GenericAlloc, /* tp_alloc */
1049 fileio_new, /* tp_new */
1050 PyObject_GC_Del, /* tp_free */