Home | History | Annotate | Download | only in _io
      1 /*
      2     An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
      3 
      4     Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
      5     BufferedRandom.
      6 
      7     Written by Amaury Forgeot d'Arc and Antoine Pitrou
      8 */
      9 
     10 #define PY_SSIZE_T_CLEAN
     11 #include "Python.h"
     12 #include "structmember.h"
     13 #include "pythread.h"
     14 #include "_iomodule.h"
     15 
     16 /*
     17  * BufferedIOBase class, inherits from IOBase.
     18  */
     19 PyDoc_STRVAR(bufferediobase_doc,
     20     "Base class for buffered IO objects.\n"
     21     "\n"
     22     "The main difference with RawIOBase is that the read() method\n"
     23     "supports omitting the size argument, and does not have a default\n"
     24     "implementation that defers to readinto().\n"
     25     "\n"
     26     "In addition, read(), readinto() and write() may raise\n"
     27     "BlockingIOError if the underlying raw stream is in non-blocking\n"
     28     "mode and not ready; unlike their raw counterparts, they will never\n"
     29     "return None.\n"
     30     "\n"
     31     "A typical implementation should not inherit from a RawIOBase\n"
     32     "implementation, but wrap one.\n"
     33     );
     34 
     35 static PyObject *
     36 bufferediobase_readinto(PyObject *self, PyObject *args)
     37 {
     38     Py_buffer buf;
     39     Py_ssize_t len;
     40     PyObject *data;
     41 
     42     if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
     43         return NULL;
     44     }
     45 
     46     data = PyObject_CallMethod(self, "read", "n", buf.len);
     47     if (data == NULL)
     48         goto error;
     49 
     50     if (!PyBytes_Check(data)) {
     51         Py_DECREF(data);
     52         PyErr_SetString(PyExc_TypeError, "read() should return bytes");
     53         goto error;
     54     }
     55 
     56     len = Py_SIZE(data);
     57     memcpy(buf.buf, PyBytes_AS_STRING(data), len);
     58 
     59     PyBuffer_Release(&buf);
     60     Py_DECREF(data);
     61 
     62     return PyLong_FromSsize_t(len);
     63 
     64   error:
     65     PyBuffer_Release(&buf);
     66     return NULL;
     67 }
     68 
     69 static PyObject *
     70 bufferediobase_unsupported(const char *message)
     71 {
     72     PyErr_SetString(_PyIO_unsupported_operation, message);
     73     return NULL;
     74 }
     75 
     76 PyDoc_STRVAR(bufferediobase_detach_doc,
     77     "Disconnect this buffer from its underlying raw stream and return it.\n"
     78     "\n"
     79     "After the raw stream has been detached, the buffer is in an unusable\n"
     80     "state.\n");
     81 
     82 static PyObject *
     83 bufferediobase_detach(PyObject *self)
     84 {
     85     return bufferediobase_unsupported("detach");
     86 }
     87 
     88 PyDoc_STRVAR(bufferediobase_read_doc,
     89     "Read and return up to n bytes.\n"
     90     "\n"
     91     "If the argument is omitted, None, or negative, reads and\n"
     92     "returns all data until EOF.\n"
     93     "\n"
     94     "If the argument is positive, and the underlying raw stream is\n"
     95     "not 'interactive', multiple raw reads may be issued to satisfy\n"
     96     "the byte count (unless EOF is reached first).  But for\n"
     97     "interactive raw streams (as well as sockets and pipes), at most\n"
     98     "one raw read will be issued, and a short result does not imply\n"
     99     "that EOF is imminent.\n"
    100     "\n"
    101     "Returns an empty bytes object on EOF.\n"
    102     "\n"
    103     "Returns None if the underlying raw stream was open in non-blocking\n"
    104     "mode and no data is available at the moment.\n");
    105 
    106 static PyObject *
    107 bufferediobase_read(PyObject *self, PyObject *args)
    108 {
    109     return bufferediobase_unsupported("read");
    110 }
    111 
    112 PyDoc_STRVAR(bufferediobase_read1_doc,
    113     "Read and return up to n bytes, with at most one read() call\n"
    114     "to the underlying raw stream. A short result does not imply\n"
    115     "that EOF is imminent.\n"
    116     "\n"
    117     "Returns an empty bytes object on EOF.\n");
    118 
    119 static PyObject *
    120 bufferediobase_read1(PyObject *self, PyObject *args)
    121 {
    122     return bufferediobase_unsupported("read1");
    123 }
    124 
    125 PyDoc_STRVAR(bufferediobase_write_doc,
    126     "Write the given buffer to the IO stream.\n"
    127     "\n"
    128     "Returns the number of bytes written, which is never less than\n"
    129     "len(b).\n"
    130     "\n"
    131     "Raises BlockingIOError if the buffer is full and the\n"
    132     "underlying raw stream cannot accept more data at the moment.\n");
    133 
    134 static PyObject *
    135 bufferediobase_write(PyObject *self, PyObject *args)
    136 {
    137     return bufferediobase_unsupported("write");
    138 }
    139 
    140 
    141 static PyMethodDef bufferediobase_methods[] = {
    142     {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
    143     {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
    144     {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
    145     {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
    146     {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
    147     {NULL, NULL}
    148 };
    149 
    150 PyTypeObject PyBufferedIOBase_Type = {
    151     PyVarObject_HEAD_INIT(NULL, 0)
    152     "_io._BufferedIOBase",      /*tp_name*/
    153     0,                          /*tp_basicsize*/
    154     0,                          /*tp_itemsize*/
    155     0,                          /*tp_dealloc*/
    156     0,                          /*tp_print*/
    157     0,                          /*tp_getattr*/
    158     0,                          /*tp_setattr*/
    159     0,                          /*tp_compare */
    160     0,                          /*tp_repr*/
    161     0,                          /*tp_as_number*/
    162     0,                          /*tp_as_sequence*/
    163     0,                          /*tp_as_mapping*/
    164     0,                          /*tp_hash */
    165     0,                          /*tp_call*/
    166     0,                          /*tp_str*/
    167     0,                          /*tp_getattro*/
    168     0,                          /*tp_setattro*/
    169     0,                          /*tp_as_buffer*/
    170     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
    171     bufferediobase_doc,         /* tp_doc */
    172     0,                          /* tp_traverse */
    173     0,                          /* tp_clear */
    174     0,                          /* tp_richcompare */
    175     0,                          /* tp_weaklistoffset */
    176     0,                          /* tp_iter */
    177     0,                          /* tp_iternext */
    178     bufferediobase_methods,     /* tp_methods */
    179     0,                          /* tp_members */
    180     0,                          /* tp_getset */
    181     &PyIOBase_Type,             /* tp_base */
    182     0,                          /* tp_dict */
    183     0,                          /* tp_descr_get */
    184     0,                          /* tp_descr_set */
    185     0,                          /* tp_dictoffset */
    186     0,                          /* tp_init */
    187     0,                          /* tp_alloc */
    188     0,                          /* tp_new */
    189 };
    190 
    191 
    192 typedef struct {
    193     PyObject_HEAD
    194 
    195     PyObject *raw;
    196     int ok;    /* Initialized? */
    197     int detached;
    198     int readable;
    199     int writable;
    200 
    201     /* True if this is a vanilla Buffered object (rather than a user derived
    202        class) *and* the raw stream is a vanilla FileIO object. */
    203     int fast_closed_checks;
    204 
    205     /* Absolute position inside the raw stream (-1 if unknown). */
    206     Py_off_t abs_pos;
    207 
    208     /* A static buffer of size `buffer_size` */
    209     char *buffer;
    210     /* Current logical position in the buffer. */
    211     Py_off_t pos;
    212     /* Position of the raw stream in the buffer. */
    213     Py_off_t raw_pos;
    214 
    215     /* Just after the last buffered byte in the buffer, or -1 if the buffer
    216        isn't ready for reading. */
    217     Py_off_t read_end;
    218 
    219     /* Just after the last byte actually written */
    220     Py_off_t write_pos;
    221     /* Just after the last byte waiting to be written, or -1 if the buffer
    222        isn't ready for writing. */
    223     Py_off_t write_end;
    224 
    225 #ifdef WITH_THREAD
    226     PyThread_type_lock lock;
    227     volatile long owner;
    228 #endif
    229 
    230     Py_ssize_t buffer_size;
    231     Py_ssize_t buffer_mask;
    232 
    233     PyObject *dict;
    234     PyObject *weakreflist;
    235 } buffered;
    236 
    237 /*
    238     Implementation notes:
    239 
    240     * BufferedReader, BufferedWriter and BufferedRandom try to share most
    241       methods (this is helped by the members `readable` and `writable`, which
    242       are initialized in the respective constructors)
    243     * They also share a single buffer for reading and writing. This enables
    244       interleaved reads and writes without flushing. It also makes the logic
    245       a bit trickier to get right.
    246     * The absolute position of the raw stream is cached, if possible, in the
    247       `abs_pos` member. It must be updated every time an operation is done
    248       on the raw stream. If not sure, it can be reinitialized by calling
    249       _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
    250       also does it). To read it, use RAW_TELL().
    251     * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
    252       _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
    253 
    254     NOTE: we should try to maintain block alignment of reads and writes to the
    255     raw stream (according to the buffer size), but for now it is only done
    256     in read() and friends.
    257 
    258 */
    259 
    260 /* These macros protect the buffered object against concurrent operations. */
    261 
    262 #ifdef WITH_THREAD
    263 
    264 static int
    265 _enter_buffered_busy(buffered *self)
    266 {
    267     if (self->owner == PyThread_get_thread_ident()) {
    268         PyObject *r = PyObject_Repr((PyObject *) self);
    269         if (r != NULL) {
    270             PyErr_Format(PyExc_RuntimeError,
    271                          "reentrant call inside %s",
    272                          PyString_AS_STRING(r));
    273             Py_DECREF(r);
    274         }
    275         return 0;
    276     }
    277     Py_BEGIN_ALLOW_THREADS
    278     PyThread_acquire_lock(self->lock, 1);
    279     Py_END_ALLOW_THREADS
    280     return 1;
    281 }
    282 
    283 #define ENTER_BUFFERED(self) \
    284     ( (PyThread_acquire_lock(self->lock, 0) ? \
    285        1 : _enter_buffered_busy(self)) \
    286      && (self->owner = PyThread_get_thread_ident(), 1) )
    287 
    288 #define LEAVE_BUFFERED(self) \
    289     do { \
    290         self->owner = 0; \
    291         PyThread_release_lock(self->lock); \
    292     } while(0);
    293 
    294 #else
    295 #define ENTER_BUFFERED(self) 1
    296 #define LEAVE_BUFFERED(self)
    297 #endif
    298 
    299 #define CHECK_INITIALIZED(self) \
    300     if (self->ok <= 0) { \
    301         if (self->detached) { \
    302             PyErr_SetString(PyExc_ValueError, \
    303                  "raw stream has been detached"); \
    304         } else { \
    305             PyErr_SetString(PyExc_ValueError, \
    306                 "I/O operation on uninitialized object"); \
    307         } \
    308         return NULL; \
    309     }
    310 
    311 #define CHECK_INITIALIZED_INT(self) \
    312     if (self->ok <= 0) { \
    313         if (self->detached) { \
    314             PyErr_SetString(PyExc_ValueError, \
    315                  "raw stream has been detached"); \
    316         } else { \
    317             PyErr_SetString(PyExc_ValueError, \
    318                 "I/O operation on uninitialized object"); \
    319         } \
    320         return -1; \
    321     }
    322 
    323 #define IS_CLOSED(self) \
    324     (self->fast_closed_checks \
    325      ? _PyFileIO_closed(self->raw) \
    326      : buffered_closed(self))
    327 
    328 #define CHECK_CLOSED(self, error_msg) \
    329     if (IS_CLOSED(self)) { \
    330         PyErr_SetString(PyExc_ValueError, error_msg); \
    331         return NULL; \
    332     }
    333 
    334 
    335 #define VALID_READ_BUFFER(self) \
    336     (self->readable && self->read_end != -1)
    337 
    338 #define VALID_WRITE_BUFFER(self) \
    339     (self->writable && self->write_end != -1)
    340 
    341 #define ADJUST_POSITION(self, _new_pos) \
    342     do { \
    343         self->pos = _new_pos; \
    344         if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
    345             self->read_end = self->pos; \
    346     } while(0)
    347 
    348 #define READAHEAD(self) \
    349     ((self->readable && VALID_READ_BUFFER(self)) \
    350         ? (self->read_end - self->pos) : 0)
    351 
    352 #define RAW_OFFSET(self) \
    353     (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
    354         && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
    355 
    356 #define RAW_TELL(self) \
    357     (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
    358 
    359 #define MINUS_LAST_BLOCK(self, size) \
    360     (self->buffer_mask ? \
    361         (size & ~self->buffer_mask) : \
    362         (self->buffer_size * (size / self->buffer_size)))
    363 
    364 
    365 static void
    366 buffered_dealloc(buffered *self)
    367 {
    368     if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
    369         return;
    370     _PyObject_GC_UNTRACK(self);
    371     self->ok = 0;
    372     if (self->weakreflist != NULL)
    373         PyObject_ClearWeakRefs((PyObject *)self);
    374     Py_CLEAR(self->raw);
    375     if (self->buffer) {
    376         PyMem_Free(self->buffer);
    377         self->buffer = NULL;
    378     }
    379 #ifdef WITH_THREAD
    380     if (self->lock) {
    381         PyThread_free_lock(self->lock);
    382         self->lock = NULL;
    383     }
    384 #endif
    385     Py_CLEAR(self->dict);
    386     Py_TYPE(self)->tp_free((PyObject *)self);
    387 }
    388 
    389 static PyObject *
    390 buffered_sizeof(buffered *self, void *unused)
    391 {
    392     Py_ssize_t res;
    393 
    394     res = sizeof(buffered);
    395     if (self->buffer)
    396         res += self->buffer_size;
    397     return PyLong_FromSsize_t(res);
    398 }
    399 
    400 static int
    401 buffered_traverse(buffered *self, visitproc visit, void *arg)
    402 {
    403     Py_VISIT(self->raw);
    404     Py_VISIT(self->dict);
    405     return 0;
    406 }
    407 
    408 static int
    409 buffered_clear(buffered *self)
    410 {
    411     if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
    412         return -1;
    413     self->ok = 0;
    414     Py_CLEAR(self->raw);
    415     Py_CLEAR(self->dict);
    416     return 0;
    417 }
    418 
    419 /*
    420  * _BufferedIOMixin methods
    421  * This is not a class, just a collection of methods that will be reused
    422  * by BufferedReader and BufferedWriter
    423  */
    424 
    425 /* Flush and close */
    426 
    427 static PyObject *
    428 buffered_simple_flush(buffered *self, PyObject *args)
    429 {
    430     CHECK_INITIALIZED(self)
    431     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
    432 }
    433 
    434 static int
    435 buffered_closed(buffered *self)
    436 {
    437     int closed;
    438     PyObject *res;
    439     CHECK_INITIALIZED_INT(self)
    440     res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
    441     if (res == NULL)
    442         return -1;
    443     closed = PyObject_IsTrue(res);
    444     Py_DECREF(res);
    445     return closed;
    446 }
    447 
    448 static PyObject *
    449 buffered_closed_get(buffered *self, void *context)
    450 {
    451     CHECK_INITIALIZED(self)
    452     return PyObject_GetAttr(self->raw, _PyIO_str_closed);
    453 }
    454 
    455 static PyObject *
    456 buffered_close(buffered *self, PyObject *args)
    457 {
    458     PyObject *res = NULL, *exc = NULL, *val, *tb;
    459     int r;
    460 
    461     CHECK_INITIALIZED(self)
    462     if (!ENTER_BUFFERED(self))
    463         return NULL;
    464 
    465     r = buffered_closed(self);
    466     if (r < 0)
    467         goto end;
    468     if (r > 0) {
    469         res = Py_None;
    470         Py_INCREF(res);
    471         goto end;
    472     }
    473     /* flush() will most probably re-take the lock, so drop it first */
    474     LEAVE_BUFFERED(self)
    475     res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
    476     if (!ENTER_BUFFERED(self))
    477         return NULL;
    478     if (res == NULL)
    479         PyErr_Fetch(&exc, &val, &tb);
    480     else
    481         Py_DECREF(res);
    482 
    483     res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
    484 
    485     if (exc != NULL) {
    486         _PyErr_ReplaceException(exc, val, tb);
    487         Py_CLEAR(res);
    488     }
    489 
    490 end:
    491     LEAVE_BUFFERED(self)
    492     return res;
    493 }
    494 
    495 /* detach */
    496 
    497 static PyObject *
    498 buffered_detach(buffered *self, PyObject *args)
    499 {
    500     PyObject *raw, *res;
    501     CHECK_INITIALIZED(self)
    502     res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
    503     if (res == NULL)
    504         return NULL;
    505     Py_DECREF(res);
    506     raw = self->raw;
    507     self->raw = NULL;
    508     self->detached = 1;
    509     self->ok = 0;
    510     return raw;
    511 }
    512 
    513 /* Inquiries */
    514 
    515 static PyObject *
    516 buffered_seekable(buffered *self, PyObject *args)
    517 {
    518     CHECK_INITIALIZED(self)
    519     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
    520 }
    521 
    522 static PyObject *
    523 buffered_readable(buffered *self, PyObject *args)
    524 {
    525     CHECK_INITIALIZED(self)
    526     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
    527 }
    528 
    529 static PyObject *
    530 buffered_writable(buffered *self, PyObject *args)
    531 {
    532     CHECK_INITIALIZED(self)
    533     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
    534 }
    535 
    536 static PyObject *
    537 buffered_name_get(buffered *self, void *context)
    538 {
    539     CHECK_INITIALIZED(self)
    540     return PyObject_GetAttrString(self->raw, "name");
    541 }
    542 
    543 static PyObject *
    544 buffered_mode_get(buffered *self, void *context)
    545 {
    546     CHECK_INITIALIZED(self)
    547     return PyObject_GetAttrString(self->raw, "mode");
    548 }
    549 
    550 /* Lower-level APIs */
    551 
    552 static PyObject *
    553 buffered_fileno(buffered *self, PyObject *args)
    554 {
    555     CHECK_INITIALIZED(self)
    556     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
    557 }
    558 
    559 static PyObject *
    560 buffered_isatty(buffered *self, PyObject *args)
    561 {
    562     CHECK_INITIALIZED(self)
    563     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
    564 }
    565 
    566 
    567 /* Forward decls */
    568 static PyObject *
    569 _bufferedwriter_flush_unlocked(buffered *);
    570 static Py_ssize_t
    571 _bufferedreader_fill_buffer(buffered *self);
    572 static void
    573 _bufferedreader_reset_buf(buffered *self);
    574 static void
    575 _bufferedwriter_reset_buf(buffered *self);
    576 static PyObject *
    577 _bufferedreader_peek_unlocked(buffered *self, Py_ssize_t);
    578 static PyObject *
    579 _bufferedreader_read_all(buffered *self);
    580 static PyObject *
    581 _bufferedreader_read_fast(buffered *self, Py_ssize_t);
    582 static PyObject *
    583 _bufferedreader_read_generic(buffered *self, Py_ssize_t);
    584 
    585 
    586 /*
    587  * Helpers
    588  */
    589 
    590 /* Sets the current error to BlockingIOError */
    591 static void
    592 _set_BlockingIOError(char *msg, Py_ssize_t written)
    593 {
    594     PyObject *err;
    595     err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
    596                                 errno, msg, written);
    597     if (err)
    598         PyErr_SetObject(PyExc_BlockingIOError, err);
    599     Py_XDECREF(err);
    600 }
    601 
    602 /* Returns the address of the `written` member if a BlockingIOError was
    603    raised, NULL otherwise. The error is always re-raised. */
    604 static Py_ssize_t *
    605 _buffered_check_blocking_error(void)
    606 {
    607     PyObject *t, *v, *tb;
    608     PyBlockingIOErrorObject *err;
    609 
    610     PyErr_Fetch(&t, &v, &tb);
    611     if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
    612         PyErr_Restore(t, v, tb);
    613         return NULL;
    614     }
    615     err = (PyBlockingIOErrorObject *) v;
    616     /* TODO: sanity check (err->written >= 0) */
    617     PyErr_Restore(t, v, tb);
    618     return &err->written;
    619 }
    620 
    621 static Py_off_t
    622 _buffered_raw_tell(buffered *self)
    623 {
    624     Py_off_t n;
    625     PyObject *res;
    626     res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
    627     if (res == NULL)
    628         return -1;
    629     n = PyNumber_AsOff_t(res, PyExc_ValueError);
    630     Py_DECREF(res);
    631     if (n < 0) {
    632         if (!PyErr_Occurred())
    633             PyErr_Format(PyExc_IOError,
    634                          "Raw stream returned invalid position %" PY_PRIdOFF,
    635 			 (PY_OFF_T_COMPAT)n);
    636         return -1;
    637     }
    638     self->abs_pos = n;
    639     return n;
    640 }
    641 
    642 static Py_off_t
    643 _buffered_raw_seek(buffered *self, Py_off_t target, int whence)
    644 {
    645     PyObject *res, *posobj, *whenceobj;
    646     Py_off_t n;
    647 
    648     posobj = PyLong_FromOff_t(target);
    649     if (posobj == NULL)
    650         return -1;
    651     whenceobj = PyLong_FromLong(whence);
    652     if (whenceobj == NULL) {
    653         Py_DECREF(posobj);
    654         return -1;
    655     }
    656     res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
    657                                      posobj, whenceobj, NULL);
    658     Py_DECREF(posobj);
    659     Py_DECREF(whenceobj);
    660     if (res == NULL)
    661         return -1;
    662     n = PyNumber_AsOff_t(res, PyExc_ValueError);
    663     Py_DECREF(res);
    664     if (n < 0) {
    665         if (!PyErr_Occurred())
    666             PyErr_Format(PyExc_IOError,
    667                          "Raw stream returned invalid position %" PY_PRIdOFF,
    668 			 (PY_OFF_T_COMPAT)n);
    669         return -1;
    670     }
    671     self->abs_pos = n;
    672     return n;
    673 }
    674 
    675 static int
    676 _buffered_init(buffered *self)
    677 {
    678     Py_ssize_t n;
    679     if (self->buffer_size <= 0) {
    680         PyErr_SetString(PyExc_ValueError,
    681             "buffer size must be strictly positive");
    682         return -1;
    683     }
    684     if (self->buffer)
    685         PyMem_Free(self->buffer);
    686     self->buffer = PyMem_Malloc(self->buffer_size);
    687     if (self->buffer == NULL) {
    688         PyErr_NoMemory();
    689         return -1;
    690     }
    691 #ifdef WITH_THREAD
    692     if (self->lock)
    693         PyThread_free_lock(self->lock);
    694     self->lock = PyThread_allocate_lock();
    695     if (self->lock == NULL) {
    696         PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
    697         return -1;
    698     }
    699     self->owner = 0;
    700 #endif
    701     /* Find out whether buffer_size is a power of 2 */
    702     /* XXX is this optimization useful? */
    703     for (n = self->buffer_size - 1; n & 1; n >>= 1)
    704         ;
    705     if (n == 0)
    706         self->buffer_mask = self->buffer_size - 1;
    707     else
    708         self->buffer_mask = 0;
    709     if (_buffered_raw_tell(self) == -1)
    710         PyErr_Clear();
    711     return 0;
    712 }
    713 
    714 /* Return 1 if an EnvironmentError with errno == EINTR is set (and then
    715    clears the error indicator), 0 otherwise.
    716    Should only be called when PyErr_Occurred() is true.
    717 */
    718 int
    719 _PyIO_trap_eintr(void)
    720 {
    721     static PyObject *eintr_int = NULL;
    722     PyObject *typ, *val, *tb;
    723     PyEnvironmentErrorObject *env_err;
    724 
    725     if (eintr_int == NULL) {
    726         eintr_int = PyLong_FromLong(EINTR);
    727         assert(eintr_int != NULL);
    728     }
    729     if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
    730         return 0;
    731     PyErr_Fetch(&typ, &val, &tb);
    732     PyErr_NormalizeException(&typ, &val, &tb);
    733     env_err = (PyEnvironmentErrorObject *) val;
    734     assert(env_err != NULL);
    735     if (env_err->myerrno != NULL &&
    736         PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
    737         Py_DECREF(typ);
    738         Py_DECREF(val);
    739         Py_XDECREF(tb);
    740         return 1;
    741     }
    742     /* This silences any error set by PyObject_RichCompareBool() */
    743     PyErr_Restore(typ, val, tb);
    744     return 0;
    745 }
    746 
    747 /*
    748  * Shared methods and wrappers
    749  */
    750 
    751 static PyObject *
    752 buffered_flush_and_rewind_unlocked(buffered *self)
    753 {
    754     PyObject *res;
    755 
    756     res = _bufferedwriter_flush_unlocked(self);
    757     if (res == NULL)
    758         return NULL;
    759     Py_DECREF(res);
    760 
    761     if (self->readable) {
    762         /* Rewind the raw stream so that its position corresponds to
    763            the current logical position. */
    764         Py_off_t n;
    765         n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
    766         _bufferedreader_reset_buf(self);
    767         if (n == -1)
    768             return NULL;
    769     }
    770     Py_RETURN_NONE;
    771 }
    772 
    773 static PyObject *
    774 buffered_flush(buffered *self, PyObject *args)
    775 {
    776     PyObject *res;
    777 
    778     CHECK_INITIALIZED(self)
    779     CHECK_CLOSED(self, "flush of closed file")
    780 
    781     if (!ENTER_BUFFERED(self))
    782         return NULL;
    783     res = buffered_flush_and_rewind_unlocked(self);
    784     LEAVE_BUFFERED(self)
    785 
    786     return res;
    787 }
    788 
    789 static PyObject *
    790 buffered_peek(buffered *self, PyObject *args)
    791 {
    792     Py_ssize_t n = 0;
    793     PyObject *res = NULL;
    794 
    795     CHECK_INITIALIZED(self)
    796     if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
    797         return NULL;
    798     }
    799 
    800     if (!ENTER_BUFFERED(self))
    801         return NULL;
    802 
    803     if (self->writable) {
    804         res = buffered_flush_and_rewind_unlocked(self);
    805         if (res == NULL)
    806             goto end;
    807         Py_CLEAR(res);
    808     }
    809     res = _bufferedreader_peek_unlocked(self, n);
    810 
    811 end:
    812     LEAVE_BUFFERED(self)
    813     return res;
    814 }
    815 
    816 static PyObject *
    817 buffered_read(buffered *self, PyObject *args)
    818 {
    819     Py_ssize_t n = -1;
    820     PyObject *res;
    821 
    822     CHECK_INITIALIZED(self)
    823     if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
    824         return NULL;
    825     }
    826     if (n < -1) {
    827         PyErr_SetString(PyExc_ValueError,
    828                         "read length must be positive or -1");
    829         return NULL;
    830     }
    831 
    832     CHECK_CLOSED(self, "read of closed file")
    833 
    834     if (n == -1) {
    835         /* The number of bytes is unspecified, read until the end of stream */
    836         if (!ENTER_BUFFERED(self))
    837             return NULL;
    838         res = _bufferedreader_read_all(self);
    839     }
    840     else {
    841         res = _bufferedreader_read_fast(self, n);
    842         if (res != Py_None)
    843             return res;
    844         Py_DECREF(res);
    845         if (!ENTER_BUFFERED(self))
    846             return NULL;
    847         res = _bufferedreader_read_generic(self, n);
    848     }
    849 
    850     LEAVE_BUFFERED(self)
    851     return res;
    852 }
    853 
    854 static PyObject *
    855 buffered_read1(buffered *self, PyObject *args)
    856 {
    857     Py_ssize_t n, have, r;
    858     PyObject *res = NULL;
    859 
    860     CHECK_INITIALIZED(self)
    861     if (!PyArg_ParseTuple(args, "n:read1", &n)) {
    862         return NULL;
    863     }
    864 
    865     if (n < 0) {
    866         PyErr_SetString(PyExc_ValueError,
    867                         "read length must be positive");
    868         return NULL;
    869     }
    870     if (n == 0)
    871         return PyBytes_FromStringAndSize(NULL, 0);
    872 
    873     if (!ENTER_BUFFERED(self))
    874         return NULL;
    875 
    876     /* Return up to n bytes.  If at least one byte is buffered, we
    877        only return buffered bytes.  Otherwise, we do one raw read. */
    878 
    879     /* XXX: this mimicks the io.py implementation but is probably wrong.
    880        If we need to read from the raw stream, then we could actually read
    881        all `n` bytes asked by the caller (and possibly more, so as to fill
    882        our buffer for the next reads). */
    883 
    884     have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
    885     if (have > 0) {
    886         if (n > have)
    887             n = have;
    888         res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
    889         if (res == NULL)
    890             goto end;
    891         self->pos += n;
    892         goto end;
    893     }
    894 
    895     if (self->writable) {
    896         res = buffered_flush_and_rewind_unlocked(self);
    897         if (res == NULL)
    898             goto end;
    899         Py_DECREF(res);
    900     }
    901 
    902     /* Fill the buffer from the raw stream, and copy it to the result. */
    903     _bufferedreader_reset_buf(self);
    904     r = _bufferedreader_fill_buffer(self);
    905     if (r == -1)
    906         goto end;
    907     if (r == -2)
    908         r = 0;
    909     if (n > r)
    910         n = r;
    911     res = PyBytes_FromStringAndSize(self->buffer, n);
    912     if (res == NULL)
    913         goto end;
    914     self->pos = n;
    915 
    916 end:
    917     LEAVE_BUFFERED(self)
    918     return res;
    919 }
    920 
    921 static PyObject *
    922 buffered_readinto(buffered *self, PyObject *args)
    923 {
    924     CHECK_INITIALIZED(self)
    925 
    926     /* TODO: use raw.readinto() (or a direct copy from our buffer) instead! */
    927     return bufferediobase_readinto((PyObject *)self, args);
    928 }
    929 
    930 static PyObject *
    931 _buffered_readline(buffered *self, Py_ssize_t limit)
    932 {
    933     PyObject *res = NULL;
    934     PyObject *chunks = NULL;
    935     Py_ssize_t n, written = 0;
    936     const char *start, *s, *end;
    937 
    938     CHECK_CLOSED(self, "readline of closed file")
    939 
    940     /* First, try to find a line in the buffer. This can run unlocked because
    941        the calls to the C API are simple enough that they can't trigger
    942        any thread switch. */
    943     n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
    944     if (limit >= 0 && n > limit)
    945         n = limit;
    946     start = self->buffer + self->pos;
    947     s = memchr(start, '\n', n);
    948     if (s != NULL) {
    949         res = PyBytes_FromStringAndSize(start, s - start + 1);
    950         if (res != NULL)
    951             self->pos += s - start + 1;
    952         goto end_unlocked;
    953     }
    954     if (n == limit) {
    955         res = PyBytes_FromStringAndSize(start, n);
    956         if (res != NULL)
    957             self->pos += n;
    958         goto end_unlocked;
    959     }
    960 
    961     if (!ENTER_BUFFERED(self))
    962         goto end_unlocked;
    963 
    964     /* Now we try to get some more from the raw stream */
    965     chunks = PyList_New(0);
    966     if (chunks == NULL)
    967         goto end;
    968     if (n > 0) {
    969         res = PyBytes_FromStringAndSize(start, n);
    970         if (res == NULL)
    971             goto end;
    972         if (PyList_Append(chunks, res) < 0) {
    973             Py_CLEAR(res);
    974             goto end;
    975         }
    976         Py_CLEAR(res);
    977         written += n;
    978         self->pos += n;
    979         if (limit >= 0)
    980             limit -= n;
    981     }
    982     if (self->writable) {
    983         PyObject *r = buffered_flush_and_rewind_unlocked(self);
    984         if (r == NULL)
    985             goto end;
    986         Py_DECREF(r);
    987     }
    988 
    989     for (;;) {
    990         _bufferedreader_reset_buf(self);
    991         n = _bufferedreader_fill_buffer(self);
    992         if (n == -1)
    993             goto end;
    994         if (n <= 0)
    995             break;
    996         if (limit >= 0 && n > limit)
    997             n = limit;
    998         start = self->buffer;
    999         end = start + n;
   1000         s = start;
   1001         while (s < end) {
   1002             if (*s++ == '\n') {
   1003                 res = PyBytes_FromStringAndSize(start, s - start);
   1004                 if (res == NULL)
   1005                     goto end;
   1006                 self->pos = s - start;
   1007                 goto found;
   1008             }
   1009         }
   1010         res = PyBytes_FromStringAndSize(start, n);
   1011         if (res == NULL)
   1012             goto end;
   1013         if (n == limit) {
   1014             self->pos = n;
   1015             break;
   1016         }
   1017         if (PyList_Append(chunks, res) < 0) {
   1018             Py_CLEAR(res);
   1019             goto end;
   1020         }
   1021         Py_CLEAR(res);
   1022         written += n;
   1023         if (limit >= 0)
   1024             limit -= n;
   1025     }
   1026 found:
   1027     if (res != NULL && PyList_Append(chunks, res) < 0) {
   1028         Py_CLEAR(res);
   1029         goto end;
   1030     }
   1031     Py_CLEAR(res);
   1032     res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
   1033 
   1034 end:
   1035     LEAVE_BUFFERED(self)
   1036 end_unlocked:
   1037     Py_XDECREF(chunks);
   1038     return res;
   1039 }
   1040 
   1041 static PyObject *
   1042 buffered_readline(buffered *self, PyObject *args)
   1043 {
   1044     Py_ssize_t limit = -1;
   1045 
   1046     CHECK_INITIALIZED(self)
   1047     if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
   1048         return NULL;
   1049     return _buffered_readline(self, limit);
   1050 }
   1051 
   1052 
   1053 static PyObject *
   1054 buffered_tell(buffered *self, PyObject *args)
   1055 {
   1056     Py_off_t pos;
   1057 
   1058     CHECK_INITIALIZED(self)
   1059     pos = _buffered_raw_tell(self);
   1060     if (pos == -1)
   1061         return NULL;
   1062     pos -= RAW_OFFSET(self);
   1063     /* TODO: sanity check (pos >= 0) */
   1064     return PyLong_FromOff_t(pos);
   1065 }
   1066 
   1067 static PyObject *
   1068 buffered_seek(buffered *self, PyObject *args)
   1069 {
   1070     Py_off_t target, n;
   1071     int whence = 0;
   1072     PyObject *targetobj, *res = NULL;
   1073 
   1074     CHECK_INITIALIZED(self)
   1075     if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
   1076         return NULL;
   1077     }
   1078     if (whence < 0 || whence > 2) {
   1079         PyErr_Format(PyExc_ValueError,
   1080                      "whence must be between 0 and 2, not %d", whence);
   1081         return NULL;
   1082     }
   1083 
   1084     CHECK_CLOSED(self, "seek of closed file")
   1085 
   1086     target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
   1087     if (target == -1 && PyErr_Occurred())
   1088         return NULL;
   1089 
   1090     if (whence != 2 && self->readable) {
   1091         Py_off_t current, avail;
   1092         /* Check if seeking leaves us inside the current buffer,
   1093            so as to return quickly if possible. Also, we needn't take the
   1094            lock in this fast path.
   1095            Don't know how to do that when whence == 2, though. */
   1096         /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
   1097            state at this point. */
   1098         current = RAW_TELL(self);
   1099         avail = READAHEAD(self);
   1100         if (avail > 0) {
   1101             Py_off_t offset;
   1102             if (whence == 0)
   1103                 offset = target - (current - RAW_OFFSET(self));
   1104             else
   1105                 offset = target;
   1106             if (offset >= -self->pos && offset <= avail) {
   1107                 self->pos += offset;
   1108                 return PyLong_FromOff_t(current - avail + offset);
   1109             }
   1110         }
   1111     }
   1112 
   1113     if (!ENTER_BUFFERED(self))
   1114         return NULL;
   1115 
   1116     /* Fallback: invoke raw seek() method and clear buffer */
   1117     if (self->writable) {
   1118         res = _bufferedwriter_flush_unlocked(self);
   1119         if (res == NULL)
   1120             goto end;
   1121         Py_CLEAR(res);
   1122         _bufferedwriter_reset_buf(self);
   1123     }
   1124 
   1125     /* TODO: align on block boundary and read buffer if needed? */
   1126     if (whence == 1)
   1127         target -= RAW_OFFSET(self);
   1128     n = _buffered_raw_seek(self, target, whence);
   1129     if (n == -1)
   1130         goto end;
   1131     self->raw_pos = -1;
   1132     res = PyLong_FromOff_t(n);
   1133     if (res != NULL && self->readable)
   1134         _bufferedreader_reset_buf(self);
   1135 
   1136 end:
   1137     LEAVE_BUFFERED(self)
   1138     return res;
   1139 }
   1140 
   1141 static PyObject *
   1142 buffered_truncate(buffered *self, PyObject *args)
   1143 {
   1144     PyObject *pos = Py_None;
   1145     PyObject *res = NULL;
   1146 
   1147     CHECK_INITIALIZED(self)
   1148     if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
   1149         return NULL;
   1150     }
   1151 
   1152     if (!ENTER_BUFFERED(self))
   1153         return NULL;
   1154 
   1155     if (self->writable) {
   1156         res = buffered_flush_and_rewind_unlocked(self);
   1157         if (res == NULL)
   1158             goto end;
   1159         Py_CLEAR(res);
   1160     }
   1161     res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
   1162     if (res == NULL)
   1163         goto end;
   1164     /* Reset cached position */
   1165     if (_buffered_raw_tell(self) == -1)
   1166         PyErr_Clear();
   1167 
   1168 end:
   1169     LEAVE_BUFFERED(self)
   1170     return res;
   1171 }
   1172 
   1173 static PyObject *
   1174 buffered_iternext(buffered *self)
   1175 {
   1176     PyObject *line;
   1177     PyTypeObject *tp;
   1178 
   1179     CHECK_INITIALIZED(self);
   1180 
   1181     tp = Py_TYPE(self);
   1182     if (tp == &PyBufferedReader_Type ||
   1183         tp == &PyBufferedRandom_Type) {
   1184         /* Skip method call overhead for speed */
   1185         line = _buffered_readline(self, -1);
   1186     }
   1187     else {
   1188         line = PyObject_CallMethodObjArgs((PyObject *)self,
   1189                                            _PyIO_str_readline, NULL);
   1190         if (line && !PyBytes_Check(line)) {
   1191             PyErr_Format(PyExc_IOError,
   1192                          "readline() should have returned a bytes object, "
   1193                          "not '%.200s'", Py_TYPE(line)->tp_name);
   1194             Py_DECREF(line);
   1195             return NULL;
   1196         }
   1197     }
   1198 
   1199     if (line == NULL)
   1200         return NULL;
   1201 
   1202     if (PyBytes_GET_SIZE(line) == 0) {
   1203         /* Reached EOF or would have blocked */
   1204         Py_DECREF(line);
   1205         return NULL;
   1206     }
   1207 
   1208     return line;
   1209 }
   1210 
   1211 static PyObject *
   1212 buffered_repr(buffered *self)
   1213 {
   1214     PyObject *nameobj, *res;
   1215 
   1216     nameobj = PyObject_GetAttrString((PyObject *) self, "name");
   1217     if (nameobj == NULL) {
   1218         if (PyErr_ExceptionMatches(PyExc_Exception))
   1219             PyErr_Clear();
   1220         else
   1221             return NULL;
   1222         res = PyString_FromFormat("<%s>", Py_TYPE(self)->tp_name);
   1223     }
   1224     else {
   1225         PyObject *repr = PyObject_Repr(nameobj);
   1226         Py_DECREF(nameobj);
   1227         if (repr == NULL)
   1228             return NULL;
   1229         res = PyString_FromFormat("<%s name=%s>",
   1230                                    Py_TYPE(self)->tp_name,
   1231                                    PyString_AS_STRING(repr));
   1232         Py_DECREF(repr);
   1233     }
   1234     return res;
   1235 }
   1236 
   1237 /*
   1238  * class BufferedReader
   1239  */
   1240 
   1241 PyDoc_STRVAR(bufferedreader_doc,
   1242              "Create a new buffered reader using the given readable raw IO object.");
   1243 
   1244 static void _bufferedreader_reset_buf(buffered *self)
   1245 {
   1246     self->read_end = -1;
   1247 }
   1248 
   1249 static int
   1250 bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
   1251 {
   1252     char *kwlist[] = {"raw", "buffer_size", NULL};
   1253     Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
   1254     PyObject *raw;
   1255 
   1256     self->ok = 0;
   1257     self->detached = 0;
   1258 
   1259     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
   1260                                      &raw, &buffer_size)) {
   1261         return -1;
   1262     }
   1263 
   1264     if (_PyIOBase_check_readable(raw, Py_True) == NULL)
   1265         return -1;
   1266 
   1267     Py_CLEAR(self->raw);
   1268     Py_INCREF(raw);
   1269     self->raw = raw;
   1270     self->buffer_size = buffer_size;
   1271     self->readable = 1;
   1272     self->writable = 0;
   1273 
   1274     if (_buffered_init(self) < 0)
   1275         return -1;
   1276     _bufferedreader_reset_buf(self);
   1277 
   1278     self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
   1279                                 Py_TYPE(raw) == &PyFileIO_Type);
   1280 
   1281     self->ok = 1;
   1282     return 0;
   1283 }
   1284 
   1285 static Py_ssize_t
   1286 _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
   1287 {
   1288     Py_buffer buf;
   1289     PyObject *memobj, *res;
   1290     Py_ssize_t n;
   1291     /* NOTE: the buffer needn't be released as its object is NULL. */
   1292     if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
   1293         return -1;
   1294     memobj = PyMemoryView_FromBuffer(&buf);
   1295     if (memobj == NULL)
   1296         return -1;
   1297     /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
   1298        occurs so we needn't do it ourselves.
   1299        We then retry reading, ignoring the signal if no handler has
   1300        raised (see issue #10956).
   1301     */
   1302     do {
   1303         res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
   1304     } while (res == NULL && _PyIO_trap_eintr());
   1305     Py_DECREF(memobj);
   1306     if (res == NULL)
   1307         return -1;
   1308     if (res == Py_None) {
   1309         /* Non-blocking stream would have blocked. Special return code! */
   1310         Py_DECREF(res);
   1311         return -2;
   1312     }
   1313     n = PyNumber_AsSsize_t(res, PyExc_ValueError);
   1314     Py_DECREF(res);
   1315     if (n < 0 || n > len) {
   1316         PyErr_Format(PyExc_IOError,
   1317                      "raw readinto() returned invalid length %zd "
   1318                      "(should have been between 0 and %zd)", n, len);
   1319         return -1;
   1320     }
   1321     if (n > 0 && self->abs_pos != -1)
   1322         self->abs_pos += n;
   1323     return n;
   1324 }
   1325 
   1326 static Py_ssize_t
   1327 _bufferedreader_fill_buffer(buffered *self)
   1328 {
   1329     Py_ssize_t start, len, n;
   1330     if (VALID_READ_BUFFER(self))
   1331         start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
   1332     else
   1333         start = 0;
   1334     len = self->buffer_size - start;
   1335     n = _bufferedreader_raw_read(self, self->buffer + start, len);
   1336     if (n <= 0)
   1337         return n;
   1338     self->read_end = start + n;
   1339     self->raw_pos = start + n;
   1340     return n;
   1341 }
   1342 
   1343 static PyObject *
   1344 _bufferedreader_read_all(buffered *self)
   1345 {
   1346     Py_ssize_t current_size;
   1347     PyObject *res, *data = NULL;
   1348     PyObject *chunks = PyList_New(0);
   1349 
   1350     if (chunks == NULL)
   1351         return NULL;
   1352 
   1353     /* First copy what we have in the current buffer. */
   1354     current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
   1355     if (current_size) {
   1356         data = PyBytes_FromStringAndSize(
   1357             self->buffer + self->pos, current_size);
   1358         if (data == NULL) {
   1359             Py_DECREF(chunks);
   1360             return NULL;
   1361         }
   1362         self->pos += current_size;
   1363     }
   1364     /* We're going past the buffer's bounds, flush it */
   1365     if (self->writable) {
   1366         res = buffered_flush_and_rewind_unlocked(self);
   1367         if (res == NULL) {
   1368             Py_DECREF(chunks);
   1369             return NULL;
   1370         }
   1371         Py_CLEAR(res);
   1372     }
   1373     _bufferedreader_reset_buf(self);
   1374     while (1) {
   1375         if (data) {
   1376             if (PyList_Append(chunks, data) < 0) {
   1377                 Py_DECREF(data);
   1378                 Py_DECREF(chunks);
   1379                 return NULL;
   1380             }
   1381             Py_DECREF(data);
   1382         }
   1383 
   1384         /* Read until EOF or until read() would block. */
   1385         data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
   1386         if (data == NULL) {
   1387             Py_DECREF(chunks);
   1388             return NULL;
   1389         }
   1390         if (data != Py_None && !PyBytes_Check(data)) {
   1391             Py_DECREF(data);
   1392             Py_DECREF(chunks);
   1393             PyErr_SetString(PyExc_TypeError, "read() should return bytes");
   1394             return NULL;
   1395         }
   1396         if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
   1397             if (current_size == 0) {
   1398                 Py_DECREF(chunks);
   1399                 return data;
   1400             }
   1401             else {
   1402                 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
   1403                 Py_DECREF(data);
   1404                 Py_DECREF(chunks);
   1405                 return res;
   1406             }
   1407         }
   1408         current_size += PyBytes_GET_SIZE(data);
   1409         if (self->abs_pos != -1)
   1410             self->abs_pos += PyBytes_GET_SIZE(data);
   1411     }
   1412 }
   1413 
   1414 /* Read n bytes from the buffer if it can, otherwise return None.
   1415    This function is simple enough that it can run unlocked. */
   1416 static PyObject *
   1417 _bufferedreader_read_fast(buffered *self, Py_ssize_t n)
   1418 {
   1419     Py_ssize_t current_size;
   1420 
   1421     current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
   1422     if (n <= current_size) {
   1423         /* Fast path: the data to read is fully buffered. */
   1424         PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
   1425         if (res != NULL)
   1426             self->pos += n;
   1427         return res;
   1428     }
   1429     Py_RETURN_NONE;
   1430 }
   1431 
   1432 /* Generic read function: read from the stream until enough bytes are read,
   1433  * or until an EOF occurs or until read() would block.
   1434  */
   1435 static PyObject *
   1436 _bufferedreader_read_generic(buffered *self, Py_ssize_t n)
   1437 {
   1438     PyObject *res = NULL;
   1439     Py_ssize_t current_size, remaining, written;
   1440     char *out;
   1441 
   1442     current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
   1443     if (n <= current_size)
   1444         return _bufferedreader_read_fast(self, n);
   1445 
   1446     res = PyBytes_FromStringAndSize(NULL, n);
   1447     if (res == NULL)
   1448         goto error;
   1449     out = PyBytes_AS_STRING(res);
   1450     remaining = n;
   1451     written = 0;
   1452     if (current_size > 0) {
   1453         memcpy(out, self->buffer + self->pos, current_size);
   1454         remaining -= current_size;
   1455         written += current_size;
   1456         self->pos += current_size;
   1457     }
   1458     /* Flush the write buffer if necessary */
   1459     if (self->writable) {
   1460         PyObject *r = buffered_flush_and_rewind_unlocked(self);
   1461         if (r == NULL)
   1462             goto error;
   1463         Py_DECREF(r);
   1464     }
   1465     _bufferedreader_reset_buf(self);
   1466     while (remaining > 0) {
   1467         /* We want to read a whole block at the end into buffer.
   1468            If we had readv() we could do this in one pass. */
   1469         Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
   1470         if (r == 0)
   1471             break;
   1472         r = _bufferedreader_raw_read(self, out + written, r);
   1473         if (r == -1)
   1474             goto error;
   1475         if (r == 0 || r == -2) {
   1476             /* EOF occurred or read() would block. */
   1477             if (r == 0 || written > 0) {
   1478                 if (_PyBytes_Resize(&res, written))
   1479                     goto error;
   1480                 return res;
   1481             }
   1482             Py_DECREF(res);
   1483             Py_INCREF(Py_None);
   1484             return Py_None;
   1485         }
   1486         remaining -= r;
   1487         written += r;
   1488     }
   1489     assert(remaining <= self->buffer_size);
   1490     self->pos = 0;
   1491     self->raw_pos = 0;
   1492     self->read_end = 0;
   1493     /* NOTE: when the read is satisfied, we avoid issuing any additional
   1494        reads, which could block indefinitely (e.g. on a socket).
   1495        See issue #9550. */
   1496     while (remaining > 0 && self->read_end < self->buffer_size) {
   1497         Py_ssize_t r = _bufferedreader_fill_buffer(self);
   1498         if (r == -1)
   1499             goto error;
   1500         if (r == 0 || r == -2) {
   1501             /* EOF occurred or read() would block. */
   1502             if (r == 0 || written > 0) {
   1503                 if (_PyBytes_Resize(&res, written))
   1504                     goto error;
   1505                 return res;
   1506             }
   1507             Py_DECREF(res);
   1508             Py_INCREF(Py_None);
   1509             return Py_None;
   1510         }
   1511         if (remaining > r) {
   1512             memcpy(out + written, self->buffer + self->pos, r);
   1513             written += r;
   1514             self->pos += r;
   1515             remaining -= r;
   1516         }
   1517         else if (remaining > 0) {
   1518             memcpy(out + written, self->buffer + self->pos, remaining);
   1519             written += remaining;
   1520             self->pos += remaining;
   1521             remaining = 0;
   1522         }
   1523         if (remaining == 0)
   1524             break;
   1525     }
   1526 
   1527     return res;
   1528 
   1529 error:
   1530     Py_XDECREF(res);
   1531     return NULL;
   1532 }
   1533 
   1534 static PyObject *
   1535 _bufferedreader_peek_unlocked(buffered *self, Py_ssize_t n)
   1536 {
   1537     Py_ssize_t have, r;
   1538 
   1539     have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
   1540     /* Constraints:
   1541        1. we don't want to advance the file position.
   1542        2. we don't want to lose block alignment, so we can't shift the buffer
   1543           to make some place.
   1544        Therefore, we either return `have` bytes (if > 0), or a full buffer.
   1545     */
   1546     if (have > 0) {
   1547         return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
   1548     }
   1549 
   1550     /* Fill the buffer from the raw stream, and copy it to the result. */
   1551     _bufferedreader_reset_buf(self);
   1552     r = _bufferedreader_fill_buffer(self);
   1553     if (r == -1)
   1554         return NULL;
   1555     if (r == -2)
   1556         r = 0;
   1557     self->pos = 0;
   1558     return PyBytes_FromStringAndSize(self->buffer, r);
   1559 }
   1560 
   1561 static PyMethodDef bufferedreader_methods[] = {
   1562     /* BufferedIOMixin methods */
   1563     {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
   1564     {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
   1565     {"close", (PyCFunction)buffered_close, METH_NOARGS},
   1566     {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
   1567     {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
   1568     {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
   1569     {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
   1570     {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
   1571 
   1572     {"read", (PyCFunction)buffered_read, METH_VARARGS},
   1573     {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
   1574     {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
   1575     {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
   1576     {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
   1577     {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
   1578     {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
   1579     {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
   1580     {NULL, NULL}
   1581 };
   1582 
   1583 static PyMemberDef bufferedreader_members[] = {
   1584     {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
   1585     {NULL}
   1586 };
   1587 
   1588 static PyGetSetDef bufferedreader_getset[] = {
   1589     {"closed", (getter)buffered_closed_get, NULL, NULL},
   1590     {"name", (getter)buffered_name_get, NULL, NULL},
   1591     {"mode", (getter)buffered_mode_get, NULL, NULL},
   1592     {NULL}
   1593 };
   1594 
   1595 
   1596 PyTypeObject PyBufferedReader_Type = {
   1597     PyVarObject_HEAD_INIT(NULL, 0)
   1598     "_io.BufferedReader",       /*tp_name*/
   1599     sizeof(buffered),           /*tp_basicsize*/
   1600     0,                          /*tp_itemsize*/
   1601     (destructor)buffered_dealloc,     /*tp_dealloc*/
   1602     0,                          /*tp_print*/
   1603     0,                          /*tp_getattr*/
   1604     0,                          /*tp_setattr*/
   1605     0,                          /*tp_compare */
   1606     (reprfunc)buffered_repr,    /*tp_repr*/
   1607     0,                          /*tp_as_number*/
   1608     0,                          /*tp_as_sequence*/
   1609     0,                          /*tp_as_mapping*/
   1610     0,                          /*tp_hash */
   1611     0,                          /*tp_call*/
   1612     0,                          /*tp_str*/
   1613     0,                          /*tp_getattro*/
   1614     0,                          /*tp_setattro*/
   1615     0,                          /*tp_as_buffer*/
   1616     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
   1617             | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   1618     bufferedreader_doc,         /* tp_doc */
   1619     (traverseproc)buffered_traverse, /* tp_traverse */
   1620     (inquiry)buffered_clear,    /* tp_clear */
   1621     0,                          /* tp_richcompare */
   1622     offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
   1623     0,                          /* tp_iter */
   1624     (iternextfunc)buffered_iternext, /* tp_iternext */
   1625     bufferedreader_methods,     /* tp_methods */
   1626     bufferedreader_members,     /* tp_members */
   1627     bufferedreader_getset,      /* tp_getset */
   1628     0,                          /* tp_base */
   1629     0,                          /* tp_dict */
   1630     0,                          /* tp_descr_get */
   1631     0,                          /* tp_descr_set */
   1632     offsetof(buffered, dict), /* tp_dictoffset */
   1633     (initproc)bufferedreader_init, /* tp_init */
   1634     0,                          /* tp_alloc */
   1635     PyType_GenericNew,          /* tp_new */
   1636 };
   1637 
   1638 
   1640 
   1641 static int
   1642 complain_about_max_buffer_size(void)
   1643 {
   1644     if (PyErr_WarnEx(PyExc_DeprecationWarning,
   1645                      "max_buffer_size is deprecated", 1) < 0)
   1646         return 0;
   1647     return 1;
   1648 }
   1649 
   1650 /*
   1651  * class BufferedWriter
   1652  */
   1653 PyDoc_STRVAR(bufferedwriter_doc,
   1654     "A buffer for a writeable sequential RawIO object.\n"
   1655     "\n"
   1656     "The constructor creates a BufferedWriter for the given writeable raw\n"
   1657     "stream. If the buffer_size is not given, it defaults to\n"
   1658     "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
   1659     );
   1660 
   1661 static void
   1662 _bufferedwriter_reset_buf(buffered *self)
   1663 {
   1664     self->write_pos = 0;
   1665     self->write_end = -1;
   1666 }
   1667 
   1668 static int
   1669 bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
   1670 {
   1671     /* TODO: properly deprecate max_buffer_size */
   1672     char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
   1673     Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
   1674     Py_ssize_t max_buffer_size = -234;
   1675     PyObject *raw;
   1676 
   1677     self->ok = 0;
   1678     self->detached = 0;
   1679 
   1680     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedWriter", kwlist,
   1681                                      &raw, &buffer_size, &max_buffer_size)) {
   1682         return -1;
   1683     }
   1684 
   1685     if (max_buffer_size != -234 && !complain_about_max_buffer_size())
   1686         return -1;
   1687 
   1688     if (_PyIOBase_check_writable(raw, Py_True) == NULL)
   1689         return -1;
   1690 
   1691     Py_CLEAR(self->raw);
   1692     Py_INCREF(raw);
   1693     self->raw = raw;
   1694     self->readable = 0;
   1695     self->writable = 1;
   1696 
   1697     self->buffer_size = buffer_size;
   1698     if (_buffered_init(self) < 0)
   1699         return -1;
   1700     _bufferedwriter_reset_buf(self);
   1701     self->pos = 0;
   1702 
   1703     self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
   1704                                 Py_TYPE(raw) == &PyFileIO_Type);
   1705 
   1706     self->ok = 1;
   1707     return 0;
   1708 }
   1709 
   1710 static Py_ssize_t
   1711 _bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
   1712 {
   1713     Py_buffer buf;
   1714     PyObject *memobj, *res;
   1715     Py_ssize_t n;
   1716     int errnum;
   1717     /* NOTE: the buffer needn't be released as its object is NULL. */
   1718     if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
   1719         return -1;
   1720     memobj = PyMemoryView_FromBuffer(&buf);
   1721     if (memobj == NULL)
   1722         return -1;
   1723     /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
   1724        occurs so we needn't do it ourselves.
   1725        We then retry writing, ignoring the signal if no handler has
   1726        raised (see issue #10956).
   1727     */
   1728     do {
   1729         errno = 0;
   1730         res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
   1731         errnum = errno;
   1732     } while (res == NULL && _PyIO_trap_eintr());
   1733     Py_DECREF(memobj);
   1734     if (res == NULL)
   1735         return -1;
   1736     if (res == Py_None) {
   1737         /* Non-blocking stream would have blocked. Special return code!
   1738            Being paranoid we reset errno in case it is changed by code
   1739            triggered by a decref.  errno is used by _set_BlockingIOError(). */
   1740         Py_DECREF(res);
   1741         errno = errnum;
   1742         return -2;
   1743     }
   1744     n = PyNumber_AsSsize_t(res, PyExc_ValueError);
   1745     Py_DECREF(res);
   1746     if (n < 0 || n > len) {
   1747         PyErr_Format(PyExc_IOError,
   1748                      "raw write() returned invalid length %zd "
   1749                      "(should have been between 0 and %zd)", n, len);
   1750         return -1;
   1751     }
   1752     if (n > 0 && self->abs_pos != -1)
   1753         self->abs_pos += n;
   1754     return n;
   1755 }
   1756 
   1757 /* `restore_pos` is 1 if we need to restore the raw stream position at
   1758    the end, 0 otherwise. */
   1759 static PyObject *
   1760 _bufferedwriter_flush_unlocked(buffered *self)
   1761 {
   1762     Py_ssize_t written = 0;
   1763     Py_off_t n, rewind;
   1764 
   1765     if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
   1766         goto end;
   1767     /* First, rewind */
   1768     rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
   1769     if (rewind != 0) {
   1770         n = _buffered_raw_seek(self, -rewind, 1);
   1771         if (n < 0) {
   1772             goto error;
   1773         }
   1774         self->raw_pos -= rewind;
   1775     }
   1776     while (self->write_pos < self->write_end) {
   1777         n = _bufferedwriter_raw_write(self,
   1778             self->buffer + self->write_pos,
   1779             Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
   1780                              Py_off_t, Py_ssize_t));
   1781         if (n == -1) {
   1782             goto error;
   1783         }
   1784         else if (n == -2) {
   1785             _set_BlockingIOError("write could not complete without blocking",
   1786                                  0);
   1787             goto error;
   1788         }
   1789         self->write_pos += n;
   1790         self->raw_pos = self->write_pos;
   1791         written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
   1792         /* Partial writes can return successfully when interrupted by a
   1793            signal (see write(2)).  We must run signal handlers before
   1794            blocking another time, possibly indefinitely. */
   1795         if (PyErr_CheckSignals() < 0)
   1796             goto error;
   1797     }
   1798 
   1799     _bufferedwriter_reset_buf(self);
   1800 
   1801 end:
   1802     Py_RETURN_NONE;
   1803 
   1804 error:
   1805     return NULL;
   1806 }
   1807 
   1808 static PyObject *
   1809 bufferedwriter_write(buffered *self, PyObject *args)
   1810 {
   1811     PyObject *res = NULL;
   1812     Py_buffer buf;
   1813     Py_ssize_t written, avail, remaining;
   1814     Py_off_t offset;
   1815 
   1816     CHECK_INITIALIZED(self)
   1817     if (!PyArg_ParseTuple(args, "s*:write", &buf)) {
   1818         return NULL;
   1819     }
   1820 
   1821     if (IS_CLOSED(self)) {
   1822         PyErr_SetString(PyExc_ValueError, "write to closed file");
   1823         PyBuffer_Release(&buf);
   1824         return NULL;
   1825     }
   1826 
   1827     if (!ENTER_BUFFERED(self)) {
   1828         PyBuffer_Release(&buf);
   1829         return NULL;
   1830     }
   1831 
   1832     /* Fast path: the data to write can be fully buffered. */
   1833     if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
   1834         self->pos = 0;
   1835         self->raw_pos = 0;
   1836     }
   1837     avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
   1838     if (buf.len <= avail) {
   1839         memcpy(self->buffer + self->pos, buf.buf, buf.len);
   1840         if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
   1841             self->write_pos = self->pos;
   1842         }
   1843         ADJUST_POSITION(self, self->pos + buf.len);
   1844         if (self->pos > self->write_end)
   1845             self->write_end = self->pos;
   1846         written = buf.len;
   1847         goto end;
   1848     }
   1849 
   1850     /* First write the current buffer */
   1851     res = _bufferedwriter_flush_unlocked(self);
   1852     if (res == NULL) {
   1853         Py_ssize_t *w = _buffered_check_blocking_error();
   1854         if (w == NULL)
   1855             goto error;
   1856         if (self->readable)
   1857             _bufferedreader_reset_buf(self);
   1858         /* Make some place by shifting the buffer. */
   1859         assert(VALID_WRITE_BUFFER(self));
   1860         memmove(self->buffer, self->buffer + self->write_pos,
   1861                 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
   1862                                  Py_off_t, Py_ssize_t));
   1863         self->write_end -= self->write_pos;
   1864         self->raw_pos -= self->write_pos;
   1865         self->pos -= self->write_pos;
   1866         self->write_pos = 0;
   1867         avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
   1868                                  Py_off_t, Py_ssize_t);
   1869         if (buf.len <= avail) {
   1870             /* Everything can be buffered */
   1871             PyErr_Clear();
   1872             memcpy(self->buffer + self->write_end, buf.buf, buf.len);
   1873             self->write_end += buf.len;
   1874             self->pos += buf.len;
   1875             written = buf.len;
   1876             goto end;
   1877         }
   1878         /* Buffer as much as possible. */
   1879         memcpy(self->buffer + self->write_end, buf.buf, avail);
   1880         self->write_end += avail;
   1881         self->pos += avail;
   1882         /* XXX Modifying the existing exception e using the pointer w
   1883            will change e.characters_written but not e.args[2].
   1884            Therefore we just replace with a new error. */
   1885         _set_BlockingIOError("write could not complete without blocking",
   1886                              avail);
   1887         goto error;
   1888     }
   1889     Py_CLEAR(res);
   1890 
   1891     /* Adjust the raw stream position if it is away from the logical stream
   1892        position. This happens if the read buffer has been filled but not
   1893        modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
   1894        the raw stream by itself).
   1895        Fixes issue #6629.
   1896     */
   1897     offset = RAW_OFFSET(self);
   1898     if (offset != 0) {
   1899         if (_buffered_raw_seek(self, -offset, 1) < 0)
   1900             goto error;
   1901         self->raw_pos -= offset;
   1902     }
   1903 
   1904     /* Then write buf itself. At this point the buffer has been emptied. */
   1905     remaining = buf.len;
   1906     written = 0;
   1907     while (remaining > self->buffer_size) {
   1908         Py_ssize_t n = _bufferedwriter_raw_write(
   1909             self, (char *) buf.buf + written, buf.len - written);
   1910         if (n == -1) {
   1911             goto error;
   1912         } else if (n == -2) {
   1913             /* Write failed because raw file is non-blocking */
   1914             if (remaining > self->buffer_size) {
   1915                 /* Can't buffer everything, still buffer as much as possible */
   1916                 memcpy(self->buffer,
   1917                        (char *) buf.buf + written, self->buffer_size);
   1918                 self->raw_pos = 0;
   1919                 ADJUST_POSITION(self, self->buffer_size);
   1920                 self->write_end = self->buffer_size;
   1921                 written += self->buffer_size;
   1922                 _set_BlockingIOError("write could not complete without "
   1923                                      "blocking", written);
   1924                 goto error;
   1925             }
   1926             PyErr_Clear();
   1927             break;
   1928         }
   1929         written += n;
   1930         remaining -= n;
   1931         /* Partial writes can return successfully when interrupted by a
   1932            signal (see write(2)).  We must run signal handlers before
   1933            blocking another time, possibly indefinitely. */
   1934         if (PyErr_CheckSignals() < 0)
   1935             goto error;
   1936     }
   1937     if (self->readable)
   1938         _bufferedreader_reset_buf(self);
   1939     if (remaining > 0) {
   1940         memcpy(self->buffer, (char *) buf.buf + written, remaining);
   1941         written += remaining;
   1942     }
   1943     self->write_pos = 0;
   1944     /* TODO: sanity check (remaining >= 0) */
   1945     self->write_end = remaining;
   1946     ADJUST_POSITION(self, remaining);
   1947     self->raw_pos = 0;
   1948 
   1949 end:
   1950     res = PyLong_FromSsize_t(written);
   1951 
   1952 error:
   1953     LEAVE_BUFFERED(self)
   1954     PyBuffer_Release(&buf);
   1955     return res;
   1956 }
   1957 
   1958 static PyMethodDef bufferedwriter_methods[] = {
   1959     /* BufferedIOMixin methods */
   1960     {"close", (PyCFunction)buffered_close, METH_NOARGS},
   1961     {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
   1962     {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
   1963     {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
   1964     {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
   1965     {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
   1966     {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
   1967 
   1968     {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
   1969     {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
   1970     {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
   1971     {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
   1972     {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
   1973     {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
   1974     {NULL, NULL}
   1975 };
   1976 
   1977 static PyMemberDef bufferedwriter_members[] = {
   1978     {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
   1979     {NULL}
   1980 };
   1981 
   1982 static PyGetSetDef bufferedwriter_getset[] = {
   1983     {"closed", (getter)buffered_closed_get, NULL, NULL},
   1984     {"name", (getter)buffered_name_get, NULL, NULL},
   1985     {"mode", (getter)buffered_mode_get, NULL, NULL},
   1986     {NULL}
   1987 };
   1988 
   1989 
   1990 PyTypeObject PyBufferedWriter_Type = {
   1991     PyVarObject_HEAD_INIT(NULL, 0)
   1992     "_io.BufferedWriter",       /*tp_name*/
   1993     sizeof(buffered),           /*tp_basicsize*/
   1994     0,                          /*tp_itemsize*/
   1995     (destructor)buffered_dealloc,     /*tp_dealloc*/
   1996     0,                          /*tp_print*/
   1997     0,                          /*tp_getattr*/
   1998     0,                          /*tp_setattr*/
   1999     0,                          /*tp_compare */
   2000     (reprfunc)buffered_repr,    /*tp_repr*/
   2001     0,                          /*tp_as_number*/
   2002     0,                          /*tp_as_sequence*/
   2003     0,                          /*tp_as_mapping*/
   2004     0,                          /*tp_hash */
   2005     0,                          /*tp_call*/
   2006     0,                          /*tp_str*/
   2007     0,                          /*tp_getattro*/
   2008     0,                          /*tp_setattro*/
   2009     0,                          /*tp_as_buffer*/
   2010     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
   2011         | Py_TPFLAGS_HAVE_GC,   /*tp_flags*/
   2012     bufferedwriter_doc,         /* tp_doc */
   2013     (traverseproc)buffered_traverse, /* tp_traverse */
   2014     (inquiry)buffered_clear,    /* tp_clear */
   2015     0,                          /* tp_richcompare */
   2016     offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
   2017     0,                          /* tp_iter */
   2018     0,                          /* tp_iternext */
   2019     bufferedwriter_methods,     /* tp_methods */
   2020     bufferedwriter_members,     /* tp_members */
   2021     bufferedwriter_getset,      /* tp_getset */
   2022     0,                          /* tp_base */
   2023     0,                          /* tp_dict */
   2024     0,                          /* tp_descr_get */
   2025     0,                          /* tp_descr_set */
   2026     offsetof(buffered, dict),   /* tp_dictoffset */
   2027     (initproc)bufferedwriter_init, /* tp_init */
   2028     0,                          /* tp_alloc */
   2029     PyType_GenericNew,          /* tp_new */
   2030 };
   2031 
   2032 
   2034 
   2035 /*
   2036  * BufferedRWPair
   2037  */
   2038 
   2039 PyDoc_STRVAR(bufferedrwpair_doc,
   2040     "A buffered reader and writer object together.\n"
   2041     "\n"
   2042     "A buffered reader object and buffered writer object put together to\n"
   2043     "form a sequential IO object that can read and write. This is typically\n"
   2044     "used with a socket or two-way pipe.\n"
   2045     "\n"
   2046     "reader and writer are RawIOBase objects that are readable and\n"
   2047     "writeable respectively. If the buffer_size is omitted it defaults to\n"
   2048     "DEFAULT_BUFFER_SIZE.\n"
   2049     );
   2050 
   2051 /* XXX The usefulness of this (compared to having two separate IO objects) is
   2052  * questionable.
   2053  */
   2054 
   2055 typedef struct {
   2056     PyObject_HEAD
   2057     buffered *reader;
   2058     buffered *writer;
   2059     PyObject *dict;
   2060     PyObject *weakreflist;
   2061 } rwpair;
   2062 
   2063 static int
   2064 bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
   2065 {
   2066     PyObject *reader, *writer;
   2067     Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
   2068     Py_ssize_t max_buffer_size = -234;
   2069 
   2070     if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer,
   2071                           &buffer_size, &max_buffer_size)) {
   2072         return -1;
   2073     }
   2074 
   2075     if (max_buffer_size != -234 && !complain_about_max_buffer_size())
   2076         return -1;
   2077 
   2078     if (_PyIOBase_check_readable(reader, Py_True) == NULL)
   2079         return -1;
   2080     if (_PyIOBase_check_writable(writer, Py_True) == NULL)
   2081         return -1;
   2082 
   2083     self->reader = (buffered *) PyObject_CallFunction(
   2084             (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
   2085     if (self->reader == NULL)
   2086         return -1;
   2087 
   2088     self->writer = (buffered *) PyObject_CallFunction(
   2089             (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
   2090     if (self->writer == NULL) {
   2091         Py_CLEAR(self->reader);
   2092         return -1;
   2093     }
   2094 
   2095     return 0;
   2096 }
   2097 
   2098 static int
   2099 bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
   2100 {
   2101     Py_VISIT(self->dict);
   2102     return 0;
   2103 }
   2104 
   2105 static int
   2106 bufferedrwpair_clear(rwpair *self)
   2107 {
   2108     Py_CLEAR(self->reader);
   2109     Py_CLEAR(self->writer);
   2110     Py_CLEAR(self->dict);
   2111     return 0;
   2112 }
   2113 
   2114 static void
   2115 bufferedrwpair_dealloc(rwpair *self)
   2116 {
   2117     _PyObject_GC_UNTRACK(self);
   2118     if (self->weakreflist != NULL)
   2119         PyObject_ClearWeakRefs((PyObject *)self);
   2120     Py_CLEAR(self->reader);
   2121     Py_CLEAR(self->writer);
   2122     Py_CLEAR(self->dict);
   2123     Py_TYPE(self)->tp_free((PyObject *) self);
   2124 }
   2125 
   2126 static PyObject *
   2127 _forward_call(buffered *self, const char *name, PyObject *args)
   2128 {
   2129     PyObject *func, *ret;
   2130     if (self == NULL) {
   2131         PyErr_SetString(PyExc_ValueError,
   2132                         "I/O operation on uninitialized object");
   2133         return NULL;
   2134     }
   2135 
   2136     func = PyObject_GetAttrString((PyObject *)self, name);
   2137     if (func == NULL) {
   2138         PyErr_SetString(PyExc_AttributeError, name);
   2139         return NULL;
   2140     }
   2141 
   2142     ret = PyObject_CallObject(func, args);
   2143     Py_DECREF(func);
   2144     return ret;
   2145 }
   2146 
   2147 static PyObject *
   2148 bufferedrwpair_read(rwpair *self, PyObject *args)
   2149 {
   2150     return _forward_call(self->reader, "read", args);
   2151 }
   2152 
   2153 static PyObject *
   2154 bufferedrwpair_peek(rwpair *self, PyObject *args)
   2155 {
   2156     return _forward_call(self->reader, "peek", args);
   2157 }
   2158 
   2159 static PyObject *
   2160 bufferedrwpair_read1(rwpair *self, PyObject *args)
   2161 {
   2162     return _forward_call(self->reader, "read1", args);
   2163 }
   2164 
   2165 static PyObject *
   2166 bufferedrwpair_readinto(rwpair *self, PyObject *args)
   2167 {
   2168     return _forward_call(self->reader, "readinto", args);
   2169 }
   2170 
   2171 static PyObject *
   2172 bufferedrwpair_write(rwpair *self, PyObject *args)
   2173 {
   2174     return _forward_call(self->writer, "write", args);
   2175 }
   2176 
   2177 static PyObject *
   2178 bufferedrwpair_flush(rwpair *self, PyObject *args)
   2179 {
   2180     return _forward_call(self->writer, "flush", args);
   2181 }
   2182 
   2183 static PyObject *
   2184 bufferedrwpair_readable(rwpair *self, PyObject *args)
   2185 {
   2186     return _forward_call(self->reader, "readable", args);
   2187 }
   2188 
   2189 static PyObject *
   2190 bufferedrwpair_writable(rwpair *self, PyObject *args)
   2191 {
   2192     return _forward_call(self->writer, "writable", args);
   2193 }
   2194 
   2195 static PyObject *
   2196 bufferedrwpair_close(rwpair *self, PyObject *args)
   2197 {
   2198     PyObject *exc = NULL, *val, *tb;
   2199     PyObject *ret = _forward_call(self->writer, "close", args);
   2200     if (ret == NULL)
   2201         PyErr_Fetch(&exc, &val, &tb);
   2202     else
   2203         Py_DECREF(ret);
   2204     ret = _forward_call(self->reader, "close", args);
   2205     if (exc != NULL) {
   2206         if (ret != NULL) {
   2207             Py_CLEAR(ret);
   2208             PyErr_Restore(exc, val, tb);
   2209         }
   2210         else {
   2211             Py_DECREF(exc);
   2212             Py_XDECREF(val);
   2213             Py_XDECREF(tb);
   2214         }
   2215     }
   2216     return ret;
   2217 }
   2218 
   2219 static PyObject *
   2220 bufferedrwpair_isatty(rwpair *self, PyObject *args)
   2221 {
   2222     PyObject *ret = _forward_call(self->writer, "isatty", args);
   2223 
   2224     if (ret != Py_False) {
   2225         /* either True or exception */
   2226         return ret;
   2227     }
   2228     Py_DECREF(ret);
   2229 
   2230     return _forward_call(self->reader, "isatty", args);
   2231 }
   2232 
   2233 static PyObject *
   2234 bufferedrwpair_closed_get(rwpair *self, void *context)
   2235 {
   2236     if (self->writer == NULL) {
   2237         PyErr_SetString(PyExc_RuntimeError,
   2238                 "the BufferedRWPair object is being garbage-collected");
   2239         return NULL;
   2240     }
   2241     return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
   2242 }
   2243 
   2244 static PyMethodDef bufferedrwpair_methods[] = {
   2245     {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
   2246     {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
   2247     {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
   2248     {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
   2249 
   2250     {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
   2251     {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
   2252 
   2253     {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
   2254     {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
   2255 
   2256     {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
   2257     {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
   2258 
   2259     {NULL, NULL}
   2260 };
   2261 
   2262 static PyGetSetDef bufferedrwpair_getset[] = {
   2263     {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
   2264     {NULL}
   2265 };
   2266 
   2267 PyTypeObject PyBufferedRWPair_Type = {
   2268     PyVarObject_HEAD_INIT(NULL, 0)
   2269     "_io.BufferedRWPair",       /*tp_name*/
   2270     sizeof(rwpair),            /*tp_basicsize*/
   2271     0,                          /*tp_itemsize*/
   2272     (destructor)bufferedrwpair_dealloc,     /*tp_dealloc*/
   2273     0,                          /*tp_print*/
   2274     0,                          /*tp_getattr*/
   2275     0,                          /*tp_setattr*/
   2276     0,                          /*tp_compare */
   2277     0,                          /*tp_repr*/
   2278     0,                          /*tp_as_number*/
   2279     0,                          /*tp_as_sequence*/
   2280     0,                          /*tp_as_mapping*/
   2281     0,                          /*tp_hash */
   2282     0,                          /*tp_call*/
   2283     0,                          /*tp_str*/
   2284     0,                          /*tp_getattro*/
   2285     0,                          /*tp_setattro*/
   2286     0,                          /*tp_as_buffer*/
   2287     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
   2288         | Py_TPFLAGS_HAVE_GC,   /* tp_flags */
   2289     bufferedrwpair_doc,         /* tp_doc */
   2290     (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
   2291     (inquiry)bufferedrwpair_clear, /* tp_clear */
   2292     0,                          /* tp_richcompare */
   2293     offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
   2294     0,                          /* tp_iter */
   2295     0,                          /* tp_iternext */
   2296     bufferedrwpair_methods,     /* tp_methods */
   2297     0,                          /* tp_members */
   2298     bufferedrwpair_getset,      /* tp_getset */
   2299     0,                          /* tp_base */
   2300     0,                          /* tp_dict */
   2301     0,                          /* tp_descr_get */
   2302     0,                          /* tp_descr_set */
   2303     offsetof(rwpair, dict),     /* tp_dictoffset */
   2304     (initproc)bufferedrwpair_init, /* tp_init */
   2305     0,                          /* tp_alloc */
   2306     PyType_GenericNew,          /* tp_new */
   2307 };
   2308 
   2309 
   2311 
   2312 /*
   2313  * BufferedRandom
   2314  */
   2315 
   2316 PyDoc_STRVAR(bufferedrandom_doc,
   2317     "A buffered interface to random access streams.\n"
   2318     "\n"
   2319     "The constructor creates a reader and writer for a seekable stream,\n"
   2320     "raw, given in the first argument. If the buffer_size is omitted it\n"
   2321     "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
   2322     );
   2323 
   2324 static int
   2325 bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
   2326 {
   2327     char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
   2328     Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
   2329     Py_ssize_t max_buffer_size = -234;
   2330     PyObject *raw;
   2331 
   2332     self->ok = 0;
   2333     self->detached = 0;
   2334 
   2335     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedRandom", kwlist,
   2336                                      &raw, &buffer_size, &max_buffer_size)) {
   2337         return -1;
   2338     }
   2339 
   2340     if (max_buffer_size != -234 && !complain_about_max_buffer_size())
   2341         return -1;
   2342 
   2343     if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
   2344         return -1;
   2345     if (_PyIOBase_check_readable(raw, Py_True) == NULL)
   2346         return -1;
   2347     if (_PyIOBase_check_writable(raw, Py_True) == NULL)
   2348         return -1;
   2349 
   2350     Py_CLEAR(self->raw);
   2351     Py_INCREF(raw);
   2352     self->raw = raw;
   2353     self->buffer_size = buffer_size;
   2354     self->readable = 1;
   2355     self->writable = 1;
   2356 
   2357     if (_buffered_init(self) < 0)
   2358         return -1;
   2359     _bufferedreader_reset_buf(self);
   2360     _bufferedwriter_reset_buf(self);
   2361     self->pos = 0;
   2362 
   2363     self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
   2364                                 Py_TYPE(raw) == &PyFileIO_Type);
   2365 
   2366     self->ok = 1;
   2367     return 0;
   2368 }
   2369 
   2370 static PyMethodDef bufferedrandom_methods[] = {
   2371     /* BufferedIOMixin methods */
   2372     {"close", (PyCFunction)buffered_close, METH_NOARGS},
   2373     {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
   2374     {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
   2375     {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
   2376     {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
   2377     {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
   2378     {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
   2379 
   2380     {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
   2381 
   2382     {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
   2383     {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
   2384     {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
   2385     {"read", (PyCFunction)buffered_read, METH_VARARGS},
   2386     {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
   2387     {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
   2388     {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
   2389     {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
   2390     {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
   2391     {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
   2392     {NULL, NULL}
   2393 };
   2394 
   2395 static PyMemberDef bufferedrandom_members[] = {
   2396     {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
   2397     {NULL}
   2398 };
   2399 
   2400 static PyGetSetDef bufferedrandom_getset[] = {
   2401     {"closed", (getter)buffered_closed_get, NULL, NULL},
   2402     {"name", (getter)buffered_name_get, NULL, NULL},
   2403     {"mode", (getter)buffered_mode_get, NULL, NULL},
   2404     {NULL}
   2405 };
   2406 
   2407 
   2408 PyTypeObject PyBufferedRandom_Type = {
   2409     PyVarObject_HEAD_INIT(NULL, 0)
   2410     "_io.BufferedRandom",       /*tp_name*/
   2411     sizeof(buffered),           /*tp_basicsize*/
   2412     0,                          /*tp_itemsize*/
   2413     (destructor)buffered_dealloc,     /*tp_dealloc*/
   2414     0,                          /*tp_print*/
   2415     0,                          /*tp_getattr*/
   2416     0,                          /*tp_setattr*/
   2417     0,                          /*tp_compare */
   2418     (reprfunc)buffered_repr,    /*tp_repr*/
   2419     0,                          /*tp_as_number*/
   2420     0,                          /*tp_as_sequence*/
   2421     0,                          /*tp_as_mapping*/
   2422     0,                          /*tp_hash */
   2423     0,                          /*tp_call*/
   2424     0,                          /*tp_str*/
   2425     0,                          /*tp_getattro*/
   2426     0,                          /*tp_setattro*/
   2427     0,                          /*tp_as_buffer*/
   2428     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
   2429         | Py_TPFLAGS_HAVE_GC,   /*tp_flags*/
   2430     bufferedrandom_doc,         /* tp_doc */
   2431     (traverseproc)buffered_traverse, /* tp_traverse */
   2432     (inquiry)buffered_clear,    /* tp_clear */
   2433     0,                          /* tp_richcompare */
   2434     offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
   2435     0,                          /* tp_iter */
   2436     (iternextfunc)buffered_iternext, /* tp_iternext */
   2437     bufferedrandom_methods,     /* tp_methods */
   2438     bufferedrandom_members,     /* tp_members */
   2439     bufferedrandom_getset,      /* tp_getset */
   2440     0,                          /* tp_base */
   2441     0,                          /*tp_dict*/
   2442     0,                          /* tp_descr_get */
   2443     0,                          /* tp_descr_set */
   2444     offsetof(buffered, dict), /*tp_dictoffset*/
   2445     (initproc)bufferedrandom_init, /* tp_init */
   2446     0,                          /* tp_alloc */
   2447     PyType_GenericNew,          /* tp_new */
   2448 };
   2449 
   2450