summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-10-16 12:22:52 +0300
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-10-16 12:22:52 +0300
commit923a8a83200f7f1061b8bdad9457d093f7cec147 (patch)
tree1eed700cb3e647facc368906ee3d0dc433c5f905 /py
parent0c7b26c0f816664222c8495d7cb5c44d40acd009 (diff)
downloadmicropython-923a8a83200f7f1061b8bdad9457d093f7cec147.tar.gz
micropython-923a8a83200f7f1061b8bdad9457d093f7cec147.zip
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.
Diffstat (limited to 'py')
-rw-r--r--py/stream.c15
1 files changed, 15 insertions, 0 deletions
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.