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