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