From 923a8a83200f7f1061b8bdad9457d093f7cec147 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 16 Oct 2014 12:22:52 +0300 Subject: [PATCH] stream: Handle non-blocking errors in readline() properly. Just like they handled in other read*(). Note that behavior of readline() in case there's no data when it's called is underspecified in Python lib spec, implemented to behave as read() - return None. --- py/stream.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/py/stream.c b/py/stream.c index 862f3e6259..ca474ba83f 100644 --- a/py/stream.c +++ b/py/stream.c @@ -293,9 +293,24 @@ STATIC mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) { mp_uint_t out_sz = o->type->stream_p->read(o, p, 1, &error); if (out_sz == MP_STREAM_ERROR) { + if (is_nonblocking_error(error)) { + if (vstr->len == 1) { + // We just incremented it, but otherwise we read nothing + // and immediately got EAGAIN. This is case is not well + // specified in + // https://docs.python.org/3/library/io.html#io.IOBase.readline + // unlike similar case for read(). But we follow the latter's + // behavior - return None. + vstr_free(vstr); + return mp_const_none; + } else { + goto done; + } + } nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(error))); } if (out_sz == 0) { +done: // Back out previously added byte // Consider, what's better - read a char and get OutOfMemory (so read // char is lost), or allocate first as we do.