1 /*
2     An implementation of the I/O abstract base classes hierarchy
3     as defined by PEP 3116 - "New I/O"
4 
5     Classes defined here: IOBase, RawIOBase.
6 
7     Written by Amaury Forgeot d'Arc and Antoine Pitrou
8 */
9 
10 
11 #define PY_SSIZE_T_CLEAN
12 #include "Python.h"
13 #include "structmember.h"
14 #include "_iomodule.h"
15 
16 /*
17  * IOBase class, an abstract class
18  */
19 
20 typedef struct {
21     PyObject_HEAD
22 
23     PyObject *dict;
24     PyObject *weakreflist;
25 } iobase;
26 
27 PyDoc_STRVAR(iobase_doc,
28     "The abstract base class for all I/O classes, acting on streams of\n"
29     "bytes. There is no public constructor.\n"
30     "\n"
31     "This class provides dummy implementations for many methods that\n"
32     "derived classes can override selectively; the default implementations\n"
33     "represent a file that cannot be read, written or seeked.\n"
34     "\n"
35     "Even though IOBase does not declare read, readinto, or write because\n"
36     "their signatures will vary, implementations and clients should\n"
37     "consider those methods part of the interface. Also, implementations\n"
38     "may raise an IOError when operations they do not support are called.\n"
39     "\n"
40     "The basic type used for binary data read from or written to a file is\n"
41     "the bytes type. Method arguments may also be bytearray or memoryview\n"
42     "of arrays of bytes. In some cases, such as readinto, a writable\n"
43     "object such as bytearray is required. Text I/O classes work with\n"
44     "unicode data.\n"
45     "\n"
46     "Note that calling any method (except additional calls to close(),\n"
47     "which are ignored) on a closed stream should raise a ValueError.\n"
48     "\n"
49     "IOBase (and its subclasses) support the iterator protocol, meaning\n"
50     "that an IOBase object can be iterated over yielding the lines in a\n"
51     "stream.\n"
52     "\n"
53     "IOBase also supports the :keyword:`with` statement. In this example,\n"
54     "fp is closed after the suite of the with statement is complete:\n"
55     "\n"
56     "with open('spam.txt', 'r') as fp:\n"
57     "    fp.write('Spam and eggs!')\n");
58 
59 /* Use this macro whenever you want to check the internal `closed` status
60    of the IOBase object rather than the virtual `closed` attribute as returned
61    by whatever subclass. */
62 
63 #define IS_CLOSED(self) \
64     PyObject_HasAttrString(self, "__IOBase_closed")
65 
66 /* Internal methods */
67 static PyObject *
iobase_unsupported(const char * message)68 iobase_unsupported(const char *message)
69 {
70     PyErr_SetString(_PyIO_unsupported_operation, message);
71     return NULL;
72 }
73 
74 /* Positioning */
75 
76 PyDoc_STRVAR(iobase_seek_doc,
77     "Change stream position.\n"
78     "\n"
79     "Change the stream position to the given byte offset. The offset is\n"
80     "interpreted relative to the position indicated by whence.  Values\n"
81     "for whence are:\n"
82     "\n"
83     "* 0 -- start of stream (the default); offset should be zero or positive\n"
84     "* 1 -- current stream position; offset may be negative\n"
85     "* 2 -- end of stream; offset is usually negative\n"
86     "\n"
87     "Return the new absolute position.");
88 
89 static PyObject *
iobase_seek(PyObject * self,PyObject * args)90 iobase_seek(PyObject *self, PyObject *args)
91 {
92     return iobase_unsupported("seek");
93 }
94 
95 PyDoc_STRVAR(iobase_tell_doc,
96              "Return current stream position.");
97 
98 static PyObject *
iobase_tell(PyObject * self,PyObject * args)99 iobase_tell(PyObject *self, PyObject *args)
100 {
101     return PyObject_CallMethod(self, "seek", "ii", 0, 1);
102 }
103 
104 PyDoc_STRVAR(iobase_truncate_doc,
105     "Truncate file to size bytes.\n"
106     "\n"
107     "File pointer is left unchanged.  Size defaults to the current IO\n"
108     "position as reported by tell().  Returns the new size.");
109 
110 static PyObject *
iobase_truncate(PyObject * self,PyObject * args)111 iobase_truncate(PyObject *self, PyObject *args)
112 {
113     return iobase_unsupported("truncate");
114 }
115 
116 /* Flush and close methods */
117 
118 PyDoc_STRVAR(iobase_flush_doc,
119     "Flush write buffers, if applicable.\n"
120     "\n"
121     "This is not implemented for read-only and non-blocking streams.\n");
122 
123 static PyObject *
iobase_flush(PyObject * self,PyObject * args)124 iobase_flush(PyObject *self, PyObject *args)
125 {
126     /* XXX Should this return the number of bytes written??? */
127     if (IS_CLOSED(self)) {
128         PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
129         return NULL;
130     }
131     Py_RETURN_NONE;
132 }
133 
134 PyDoc_STRVAR(iobase_close_doc,
135     "Flush and close the IO object.\n"
136     "\n"
137     "This method has no effect if the file is already closed.\n");
138 
139 static int
iobase_closed(PyObject * self)140 iobase_closed(PyObject *self)
141 {
142     PyObject *res;
143     int closed;
144     /* This gets the derived attribute, which is *not* __IOBase_closed
145        in most cases! */
146     res = PyObject_GetAttr(self, _PyIO_str_closed);
147     if (res == NULL)
148         return 0;
149     closed = PyObject_IsTrue(res);
150     Py_DECREF(res);
151     return closed;
152 }
153 
154 static PyObject *
iobase_closed_get(PyObject * self,void * context)155 iobase_closed_get(PyObject *self, void *context)
156 {
157     return PyBool_FromLong(IS_CLOSED(self));
158 }
159 
160 PyObject *
_PyIOBase_check_closed(PyObject * self,PyObject * args)161 _PyIOBase_check_closed(PyObject *self, PyObject *args)
162 {
163     if (iobase_closed(self)) {
164         PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
165         return NULL;
166     }
167     if (args == Py_True)
168         return Py_None;
169     else
170         Py_RETURN_NONE;
171 }
172 
173 /* XXX: IOBase thinks it has to maintain its own internal state in
174    `__IOBase_closed` and call flush() by itself, but it is redundant with
175    whatever behaviour a non-trivial derived class will implement. */
176 
177 static PyObject *
iobase_close(PyObject * self,PyObject * args)178 iobase_close(PyObject *self, PyObject *args)
179 {
180     PyObject *res, *exc, *val, *tb;
181     int rc;
182 
183     if (IS_CLOSED(self))
184         Py_RETURN_NONE;
185 
186     res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL);
187 
188     PyErr_Fetch(&exc, &val, &tb);
189     rc = PyObject_SetAttrString(self, "__IOBase_closed", Py_True);
190     _PyErr_ReplaceException(exc, val, tb);
191     if (rc < 0) {
192         Py_CLEAR(res);
193     }
194 
195     if (res == NULL) {
196         return NULL;
197     }
198     Py_DECREF(res);
199     Py_RETURN_NONE;
200 }
201 
202 /* Finalization and garbage collection support */
203 
204 int
_PyIOBase_finalize(PyObject * self)205 _PyIOBase_finalize(PyObject *self)
206 {
207     PyObject *res;
208     PyObject *tp, *v, *tb;
209     int closed = 1;
210     int is_zombie;
211 
212     /* If _PyIOBase_finalize() is called from a destructor, we need to
213        resurrect the object as calling close() can invoke arbitrary code. */
214     is_zombie = (Py_REFCNT(self) == 0);
215     if (is_zombie) {
216         ++Py_REFCNT(self);
217     }
218     PyErr_Fetch(&tp, &v, &tb);
219     /* If `closed` doesn't exist or can't be evaluated as bool, then the
220        object is probably in an unusable state, so ignore. */
221     res = PyObject_GetAttr(self, _PyIO_str_closed);
222     if (res == NULL)
223         PyErr_Clear();
224     else {
225         closed = PyObject_IsTrue(res);
226         Py_DECREF(res);
227         if (closed == -1)
228             PyErr_Clear();
229     }
230     if (closed == 0) {
231         res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close,
232                                           NULL);
233         /* Silencing I/O errors is bad, but printing spurious tracebacks is
234            equally as bad, and potentially more frequent (because of
235            shutdown issues). */
236         if (res == NULL)
237             PyErr_Clear();
238         else
239             Py_DECREF(res);
240     }
241     PyErr_Restore(tp, v, tb);
242     if (is_zombie) {
243         if (--Py_REFCNT(self) != 0) {
244             /* The object lives again. The following code is taken from
245                slot_tp_del in typeobject.c. */
246             Py_ssize_t refcnt = Py_REFCNT(self);
247             _Py_NewReference(self);
248             Py_REFCNT(self) = refcnt;
249             /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
250              * we need to undo that. */
251             _Py_DEC_REFTOTAL;
252             /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
253              * chain, so no more to do there.
254              * If COUNT_ALLOCS, the original decref bumped tp_frees, and
255              * _Py_NewReference bumped tp_allocs:  both of those need to be
256              * undone.
257              */
258 #ifdef COUNT_ALLOCS
259             --Py_TYPE(self)->tp_frees;
260             --Py_TYPE(self)->tp_allocs;
261 #endif
262             return -1;
263         }
264     }
265     return 0;
266 }
267 
268 static int
iobase_traverse(iobase * self,visitproc visit,void * arg)269 iobase_traverse(iobase *self, visitproc visit, void *arg)
270 {
271     Py_VISIT(self->dict);
272     return 0;
273 }
274 
275 static int
iobase_clear(iobase * self)276 iobase_clear(iobase *self)
277 {
278     if (_PyIOBase_finalize((PyObject *) self) < 0)
279         return -1;
280     Py_CLEAR(self->dict);
281     return 0;
282 }
283 
284 /* Destructor */
285 
286 static void
iobase_dealloc(iobase * self)287 iobase_dealloc(iobase *self)
288 {
289     /* NOTE: since IOBaseObject has its own dict, Python-defined attributes
290        are still available here for close() to use.
291        However, if the derived class declares a __slots__, those slots are
292        already gone.
293     */
294     if (_PyIOBase_finalize((PyObject *) self) < 0) {
295         /* When called from a heap type's dealloc, the type will be
296            decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */
297         if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE))
298             Py_INCREF(Py_TYPE(self));
299         return;
300     }
301     _PyObject_GC_UNTRACK(self);
302     if (self->weakreflist != NULL)
303         PyObject_ClearWeakRefs((PyObject *) self);
304     Py_CLEAR(self->dict);
305     Py_TYPE(self)->tp_free((PyObject *) self);
306 }
307 
308 /* Inquiry methods */
309 
310 PyDoc_STRVAR(iobase_seekable_doc,
311     "Return whether object supports random access.\n"
312     "\n"
313     "If False, seek(), tell() and truncate() will raise IOError.\n"
314     "This method may need to do a test seek().");
315 
316 static PyObject *
iobase_seekable(PyObject * self,PyObject * args)317 iobase_seekable(PyObject *self, PyObject *args)
318 {
319     Py_RETURN_FALSE;
320 }
321 
322 PyObject *
_PyIOBase_check_seekable(PyObject * self,PyObject * args)323 _PyIOBase_check_seekable(PyObject *self, PyObject *args)
324 {
325     PyObject *res  = PyObject_CallMethodObjArgs(self, _PyIO_str_seekable, NULL);
326     if (res == NULL)
327         return NULL;
328     if (res != Py_True) {
329         Py_CLEAR(res);
330         PyErr_SetString(PyExc_IOError, "File or stream is not seekable.");
331         return NULL;
332     }
333     if (args == Py_True) {
334         Py_DECREF(res);
335     }
336     return res;
337 }
338 
339 PyDoc_STRVAR(iobase_readable_doc,
340     "Return whether object was opened for reading.\n"
341     "\n"
342     "If False, read() will raise IOError.");
343 
344 static PyObject *
iobase_readable(PyObject * self,PyObject * args)345 iobase_readable(PyObject *self, PyObject *args)
346 {
347     Py_RETURN_FALSE;
348 }
349 
350 /* May be called with any object */
351 PyObject *
_PyIOBase_check_readable(PyObject * self,PyObject * args)352 _PyIOBase_check_readable(PyObject *self, PyObject *args)
353 {
354     PyObject *res  = PyObject_CallMethodObjArgs(self, _PyIO_str_readable, NULL);
355     if (res == NULL)
356         return NULL;
357     if (res != Py_True) {
358         Py_CLEAR(res);
359         PyErr_SetString(PyExc_IOError, "File or stream is not readable.");
360         return NULL;
361     }
362     if (args == Py_True) {
363         Py_DECREF(res);
364     }
365     return res;
366 }
367 
368 PyDoc_STRVAR(iobase_writable_doc,
369     "Return whether object was opened for writing.\n"
370     "\n"
371     "If False, read() will raise IOError.");
372 
373 static PyObject *
iobase_writable(PyObject * self,PyObject * args)374 iobase_writable(PyObject *self, PyObject *args)
375 {
376     Py_RETURN_FALSE;
377 }
378 
379 /* May be called with any object */
380 PyObject *
_PyIOBase_check_writable(PyObject * self,PyObject * args)381 _PyIOBase_check_writable(PyObject *self, PyObject *args)
382 {
383     PyObject *res  = PyObject_CallMethodObjArgs(self, _PyIO_str_writable, NULL);
384     if (res == NULL)
385         return NULL;
386     if (res != Py_True) {
387         Py_CLEAR(res);
388         PyErr_SetString(PyExc_IOError, "File or stream is not writable.");
389         return NULL;
390     }
391     if (args == Py_True) {
392         Py_DECREF(res);
393     }
394     return res;
395 }
396 
397 /* Context manager */
398 
399 static PyObject *
iobase_enter(PyObject * self,PyObject * args)400 iobase_enter(PyObject *self, PyObject *args)
401 {
402     if (_PyIOBase_check_closed(self, Py_True) == NULL)
403         return NULL;
404 
405     Py_INCREF(self);
406     return self;
407 }
408 
409 static PyObject *
iobase_exit(PyObject * self,PyObject * args)410 iobase_exit(PyObject *self, PyObject *args)
411 {
412     return PyObject_CallMethodObjArgs(self, _PyIO_str_close, NULL);
413 }
414 
415 /* Lower-level APIs */
416 
417 /* XXX Should these be present even if unimplemented? */
418 
419 PyDoc_STRVAR(iobase_fileno_doc,
420     "Returns underlying file descriptor if one exists.\n"
421     "\n"
422     "An IOError is raised if the IO object does not use a file descriptor.\n");
423 
424 static PyObject *
iobase_fileno(PyObject * self,PyObject * args)425 iobase_fileno(PyObject *self, PyObject *args)
426 {
427     return iobase_unsupported("fileno");
428 }
429 
430 PyDoc_STRVAR(iobase_isatty_doc,
431     "Return whether this is an 'interactive' stream.\n"
432     "\n"
433     "Return False if it can't be determined.\n");
434 
435 static PyObject *
iobase_isatty(PyObject * self,PyObject * args)436 iobase_isatty(PyObject *self, PyObject *args)
437 {
438     if (_PyIOBase_check_closed(self, Py_True) == NULL)
439         return NULL;
440     Py_RETURN_FALSE;
441 }
442 
443 /* Readline(s) and writelines */
444 
445 PyDoc_STRVAR(iobase_readline_doc,
446     "Read and return a line from the stream.\n"
447     "\n"
448     "If limit is specified, at most limit bytes will be read.\n"
449     "\n"
450     "The line terminator is always b'\\n' for binary files; for text\n"
451     "files, the newlines argument to open can be used to select the line\n"
452     "terminator(s) recognized.\n");
453 
454 static PyObject *
iobase_readline(PyObject * self,PyObject * args)455 iobase_readline(PyObject *self, PyObject *args)
456 {
457     /* For backwards compatibility, a (slowish) readline(). */
458 
459     Py_ssize_t limit = -1;
460     int has_peek = 0;
461     PyObject *buffer, *result;
462     Py_ssize_t old_size = -1;
463 
464     if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) {
465         return NULL;
466     }
467 
468     if (PyObject_HasAttrString(self, "peek"))
469         has_peek = 1;
470 
471     buffer = PyByteArray_FromStringAndSize(NULL, 0);
472     if (buffer == NULL)
473         return NULL;
474 
475     while (limit < 0 || Py_SIZE(buffer) < limit) {
476         Py_ssize_t nreadahead = 1;
477         PyObject *b;
478 
479         if (has_peek) {
480             PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1);
481             if (readahead == NULL) {
482                 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
483                    when EINTR occurs so we needn't do it ourselves. */
484                 if (_PyIO_trap_eintr()) {
485                     continue;
486                 }
487                 goto fail;
488             }
489             if (!PyBytes_Check(readahead)) {
490                 PyErr_Format(PyExc_IOError,
491                              "peek() should have returned a bytes object, "
492                              "not '%.200s'", Py_TYPE(readahead)->tp_name);
493                 Py_DECREF(readahead);
494                 goto fail;
495             }
496             if (PyBytes_GET_SIZE(readahead) > 0) {
497                 Py_ssize_t n = 0;
498                 const char *buf = PyBytes_AS_STRING(readahead);
499                 if (limit >= 0) {
500                     do {
501                         if (n >= PyBytes_GET_SIZE(readahead) || n >= limit)
502                             break;
503                         if (buf[n++] == '\n')
504                             break;
505                     } while (1);
506                 }
507                 else {
508                     do {
509                         if (n >= PyBytes_GET_SIZE(readahead))
510                             break;
511                         if (buf[n++] == '\n')
512                             break;
513                     } while (1);
514                 }
515                 nreadahead = n;
516             }
517             Py_DECREF(readahead);
518         }
519 
520         b = PyObject_CallMethod(self, "read", "n", nreadahead);
521         if (b == NULL) {
522             /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
523                when EINTR occurs so we needn't do it ourselves. */
524             if (_PyIO_trap_eintr()) {
525                 continue;
526             }
527             goto fail;
528         }
529         if (!PyBytes_Check(b)) {
530             PyErr_Format(PyExc_IOError,
531                          "read() should have returned a bytes object, "
532                          "not '%.200s'", Py_TYPE(b)->tp_name);
533             Py_DECREF(b);
534             goto fail;
535         }
536         if (PyBytes_GET_SIZE(b) == 0) {
537             Py_DECREF(b);
538             break;
539         }
540 
541         old_size = PyByteArray_GET_SIZE(buffer);
542         if (PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)) < 0) {
543             Py_DECREF(b);
544             goto fail;
545         }
546         memcpy(PyByteArray_AS_STRING(buffer) + old_size,
547                PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b));
548 
549         Py_DECREF(b);
550 
551         if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n')
552             break;
553     }
554 
555     result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer),
556                                        PyByteArray_GET_SIZE(buffer));
557     Py_DECREF(buffer);
558     return result;
559   fail:
560     Py_DECREF(buffer);
561     return NULL;
562 }
563 
564 static PyObject *
iobase_iter(PyObject * self)565 iobase_iter(PyObject *self)
566 {
567     if (_PyIOBase_check_closed(self, Py_True) == NULL)
568         return NULL;
569 
570     Py_INCREF(self);
571     return self;
572 }
573 
574 static PyObject *
iobase_iternext(PyObject * self)575 iobase_iternext(PyObject *self)
576 {
577     PyObject *line = PyObject_CallMethodObjArgs(self, _PyIO_str_readline, NULL);
578 
579     if (line == NULL)
580         return NULL;
581 
582     if (PyObject_Size(line) <= 0) {
583         /* Error or empty */
584         Py_DECREF(line);
585         return NULL;
586     }
587 
588     return line;
589 }
590 
591 PyDoc_STRVAR(iobase_readlines_doc,
592     "Return a list of lines from the stream.\n"
593     "\n"
594     "hint can be specified to control the number of lines read: no more\n"
595     "lines will be read if the total size (in bytes/characters) of all\n"
596     "lines so far exceeds hint.");
597 
598 static PyObject *
iobase_readlines(PyObject * self,PyObject * args)599 iobase_readlines(PyObject *self, PyObject *args)
600 {
601     Py_ssize_t hint = -1, length = 0;
602     PyObject *result, *it = NULL;
603 
604     if (!PyArg_ParseTuple(args, "|O&:readlines", &_PyIO_ConvertSsize_t, &hint)) {
605         return NULL;
606     }
607 
608     result = PyList_New(0);
609     if (result == NULL)
610         return NULL;
611 
612     if (hint <= 0) {
613         /* XXX special-casing this made sense in the Python version in order
614            to remove the bytecode interpretation overhead, but it could
615            probably be removed here. */
616         PyObject *ret = PyObject_CallMethod(result, "extend", "O", self);
617         if (ret == NULL) {
618             goto error;
619         }
620         Py_DECREF(ret);
621         return result;
622     }
623 
624     it = PyObject_GetIter(self);
625     if (it == NULL) {
626         goto error;
627     }
628 
629     while (1) {
630         Py_ssize_t line_length;
631         PyObject *line = PyIter_Next(it);
632         if (line == NULL) {
633             if (PyErr_Occurred()) {
634                 goto error;
635             }
636             else
637                 break; /* StopIteration raised */
638         }
639 
640         if (PyList_Append(result, line) < 0) {
641             Py_DECREF(line);
642             goto error;
643         }
644         line_length = PyObject_Size(line);
645         Py_DECREF(line);
646         if (line_length < 0) {
647             goto error;
648         }
649         if (line_length > hint - length)
650             break;
651         length += line_length;
652     }
653 
654     Py_DECREF(it);
655     return result;
656 
657  error:
658     Py_XDECREF(it);
659     Py_DECREF(result);
660     return NULL;
661 }
662 
663 static PyObject *
iobase_writelines(PyObject * self,PyObject * args)664 iobase_writelines(PyObject *self, PyObject *args)
665 {
666     PyObject *lines, *iter, *res;
667 
668     if (!PyArg_ParseTuple(args, "O:writelines", &lines)) {
669         return NULL;
670     }
671 
672     if (_PyIOBase_check_closed(self, Py_True) == NULL)
673         return NULL;
674 
675     iter = PyObject_GetIter(lines);
676     if (iter == NULL)
677         return NULL;
678 
679     while (1) {
680         PyObject *line = PyIter_Next(iter);
681         if (line == NULL) {
682             if (PyErr_Occurred()) {
683                 Py_DECREF(iter);
684                 return NULL;
685             }
686             else
687                 break; /* Stop Iteration */
688         }
689 
690         res = NULL;
691         do {
692             res = PyObject_CallMethodObjArgs(self, _PyIO_str_write, line, NULL);
693         } while (res == NULL && _PyIO_trap_eintr());
694         Py_DECREF(line);
695         if (res == NULL) {
696             Py_DECREF(iter);
697             return NULL;
698         }
699         Py_DECREF(res);
700     }
701     Py_DECREF(iter);
702     Py_RETURN_NONE;
703 }
704 
705 static PyMethodDef iobase_methods[] = {
706     {"seek", iobase_seek, METH_VARARGS, iobase_seek_doc},
707     {"tell", iobase_tell, METH_NOARGS, iobase_tell_doc},
708     {"truncate", iobase_truncate, METH_VARARGS, iobase_truncate_doc},
709     {"flush", iobase_flush, METH_NOARGS, iobase_flush_doc},
710     {"close", iobase_close, METH_NOARGS, iobase_close_doc},
711 
712     {"seekable", iobase_seekable, METH_NOARGS, iobase_seekable_doc},
713     {"readable", iobase_readable, METH_NOARGS, iobase_readable_doc},
714     {"writable", iobase_writable, METH_NOARGS, iobase_writable_doc},
715 
716     {"_checkClosed",   _PyIOBase_check_closed, METH_NOARGS},
717     {"_checkSeekable", _PyIOBase_check_seekable, METH_NOARGS},
718     {"_checkReadable", _PyIOBase_check_readable, METH_NOARGS},
719     {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS},
720 
721     {"fileno", iobase_fileno, METH_NOARGS, iobase_fileno_doc},
722     {"isatty", iobase_isatty, METH_NOARGS, iobase_isatty_doc},
723 
724     {"__enter__", iobase_enter, METH_NOARGS},
725     {"__exit__", iobase_exit, METH_VARARGS},
726 
727     {"readline", iobase_readline, METH_VARARGS, iobase_readline_doc},
728     {"readlines", iobase_readlines, METH_VARARGS, iobase_readlines_doc},
729     {"writelines", iobase_writelines, METH_VARARGS},
730 
731     {NULL, NULL}
732 };
733 
734 static PyGetSetDef iobase_getset[] = {
735     {"closed", (getter)iobase_closed_get, NULL, NULL},
736     {NULL}
737 };
738 
739 
740 PyTypeObject PyIOBase_Type = {
741     PyVarObject_HEAD_INIT(NULL, 0)
742     "_io._IOBase",              /*tp_name*/
743     sizeof(iobase),             /*tp_basicsize*/
744     0,                          /*tp_itemsize*/
745     (destructor)iobase_dealloc, /*tp_dealloc*/
746     0,                          /*tp_print*/
747     0,                          /*tp_getattr*/
748     0,                          /*tp_setattr*/
749     0,                          /*tp_compare */
750     0,                          /*tp_repr*/
751     0,                          /*tp_as_number*/
752     0,                          /*tp_as_sequence*/
753     0,                          /*tp_as_mapping*/
754     0,                          /*tp_hash */
755     0,                          /*tp_call*/
756     0,                          /*tp_str*/
757     0,                          /*tp_getattro*/
758     0,                          /*tp_setattro*/
759     0,                          /*tp_as_buffer*/
760     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
761         | Py_TPFLAGS_HAVE_GC,   /*tp_flags*/
762     iobase_doc,                 /* tp_doc */
763     (traverseproc)iobase_traverse, /* tp_traverse */
764     (inquiry)iobase_clear,      /* tp_clear */
765     0,                          /* tp_richcompare */
766     offsetof(iobase, weakreflist), /* tp_weaklistoffset */
767     iobase_iter,                /* tp_iter */
768     iobase_iternext,            /* tp_iternext */
769     iobase_methods,             /* tp_methods */
770     0,                          /* tp_members */
771     iobase_getset,              /* tp_getset */
772     0,                          /* tp_base */
773     0,                          /* tp_dict */
774     0,                          /* tp_descr_get */
775     0,                          /* tp_descr_set */
776     offsetof(iobase, dict),     /* tp_dictoffset */
777     0,                          /* tp_init */
778     0,                          /* tp_alloc */
779     PyType_GenericNew,          /* tp_new */
780 };
781 
782 
783 /*
784  * RawIOBase class, Inherits from IOBase.
785  */
786 PyDoc_STRVAR(rawiobase_doc,
787              "Base class for raw binary I/O.");
788 
789 /*
790  * The read() method is implemented by calling readinto(); derived classes
791  * that want to support read() only need to implement readinto() as a
792  * primitive operation.  In general, readinto() can be more efficient than
793  * read().
794  *
795  * (It would be tempting to also provide an implementation of readinto() in
796  * terms of read(), in case the latter is a more suitable primitive operation,
797  * but that would lead to nasty recursion in case a subclass doesn't implement
798  * either.)
799 */
800 
801 static PyObject *
rawiobase_read(PyObject * self,PyObject * args)802 rawiobase_read(PyObject *self, PyObject *args)
803 {
804     Py_ssize_t n = -1;
805     PyObject *b, *res;
806 
807     if (!PyArg_ParseTuple(args, "|n:read", &n)) {
808         return NULL;
809     }
810 
811     if (n < 0)
812         return PyObject_CallMethod(self, "readall", NULL);
813 
814     /* TODO: allocate a bytes object directly instead and manually construct
815        a writable memoryview pointing to it. */
816     b = PyByteArray_FromStringAndSize(NULL, n);
817     if (b == NULL)
818         return NULL;
819 
820     res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL);
821     if (res == NULL || res == Py_None) {
822         Py_DECREF(b);
823         return res;
824     }
825 
826     n = PyNumber_AsSsize_t(res, PyExc_ValueError);
827     Py_DECREF(res);
828     if (n == -1 && PyErr_Occurred()) {
829         Py_DECREF(b);
830         return NULL;
831     }
832 
833     res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n);
834     Py_DECREF(b);
835     return res;
836 }
837 
838 
839 PyDoc_STRVAR(rawiobase_readall_doc,
840              "Read until EOF, using multiple read() call.");
841 
842 static PyObject *
rawiobase_readall(PyObject * self,PyObject * args)843 rawiobase_readall(PyObject *self, PyObject *args)
844 {
845     int r;
846     PyObject *chunks = PyList_New(0);
847     PyObject *result;
848 
849     if (chunks == NULL)
850         return NULL;
851 
852     while (1) {
853         PyObject *data = PyObject_CallMethod(self, "read",
854                                              "i", DEFAULT_BUFFER_SIZE);
855         if (!data) {
856             /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
857                when EINTR occurs so we needn't do it ourselves. */
858             if (_PyIO_trap_eintr()) {
859                 continue;
860             }
861             Py_DECREF(chunks);
862             return NULL;
863         }
864         if (data == Py_None) {
865             if (PyList_GET_SIZE(chunks) == 0) {
866                 Py_DECREF(chunks);
867                 return data;
868             }
869             Py_DECREF(data);
870             break;
871         }
872         if (!PyBytes_Check(data)) {
873             Py_DECREF(chunks);
874             Py_DECREF(data);
875             PyErr_SetString(PyExc_TypeError, "read() should return bytes");
876             return NULL;
877         }
878         if (PyBytes_GET_SIZE(data) == 0) {
879             /* EOF */
880             Py_DECREF(data);
881             break;
882         }
883         r = PyList_Append(chunks, data);
884         Py_DECREF(data);
885         if (r < 0) {
886             Py_DECREF(chunks);
887             return NULL;
888         }
889     }
890     result = _PyBytes_Join(_PyIO_empty_bytes, chunks);
891     Py_DECREF(chunks);
892     return result;
893 }
894 
895 static PyMethodDef rawiobase_methods[] = {
896     {"read", rawiobase_read, METH_VARARGS},
897     {"readall", rawiobase_readall, METH_NOARGS, rawiobase_readall_doc},
898     {NULL, NULL}
899 };
900 
901 PyTypeObject PyRawIOBase_Type = {
902     PyVarObject_HEAD_INIT(NULL, 0)
903     "_io._RawIOBase",                /*tp_name*/
904     0,                          /*tp_basicsize*/
905     0,                          /*tp_itemsize*/
906     0,                          /*tp_dealloc*/
907     0,                          /*tp_print*/
908     0,                          /*tp_getattr*/
909     0,                          /*tp_setattr*/
910     0,                          /*tp_compare */
911     0,                          /*tp_repr*/
912     0,                          /*tp_as_number*/
913     0,                          /*tp_as_sequence*/
914     0,                          /*tp_as_mapping*/
915     0,                          /*tp_hash */
916     0,                          /*tp_call*/
917     0,                          /*tp_str*/
918     0,                          /*tp_getattro*/
919     0,                          /*tp_setattro*/
920     0,                          /*tp_as_buffer*/
921     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
922     rawiobase_doc,              /* tp_doc */
923     0,                          /* tp_traverse */
924     0,                          /* tp_clear */
925     0,                          /* tp_richcompare */
926     0,                          /* tp_weaklistoffset */
927     0,                          /* tp_iter */
928     0,                          /* tp_iternext */
929     rawiobase_methods,          /* tp_methods */
930     0,                          /* tp_members */
931     0,                          /* tp_getset */
932     &PyIOBase_Type,             /* tp_base */
933     0,                          /* tp_dict */
934     0,                          /* tp_descr_get */
935     0,                          /* tp_descr_set */
936     0,                          /* tp_dictoffset */
937     0,                          /* tp_init */
938     0,                          /* tp_alloc */
939     0,                          /* tp_new */
940 };
941