From 13394a632dda24298e80ec034dd13903059b4a4b Mon Sep 17 00:00:00 2001
From: Paul Sokolovsky <pfalcon@users.sourceforge.net>
Date: Sun, 27 Mar 2016 13:57:50 +0300
Subject: [PATCH] unix/unix_mphal: Hack to make uos.dupterm() actually work.

See https://github.com/micropython/micropython/issues/1736 for the
list of complications. This workaround instead of duplicating REPL
to another stream, switches to it, because read(STDIN) we use otherwise
is blocking call, so it and custom REPL stream can't be used together.
---
 unix/unix_mphal.c | 33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/unix/unix_mphal.c b/unix/unix_mphal.c
index 03488b9a5..df3797627 100644
--- a/unix/unix_mphal.c
+++ b/unix/unix_mphal.c
@@ -117,7 +117,7 @@ static int call_dupterm_read(void) {
         read_m[2] = MP_OBJ_NEW_SMALL_INT(1);
         mp_obj_t res = mp_call_method_n_kw(1, 0, read_m);
         if (res == mp_const_none) {
-            return -1;
+            return -2;
         }
         mp_buffer_info_t bufinfo;
         mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ);
@@ -143,25 +143,32 @@ static int call_dupterm_read(void) {
 
 int mp_hal_stdin_rx_chr(void) {
     unsigned char c;
-    #if MICROPY_PY_OS_DUPTERM
-    while (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) {
-        int c = call_dupterm_read();
+#if MICROPY_PY_OS_DUPTERM
+    if (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) {
+        int c;
+        do {
+             c = call_dupterm_read();
+        } while (c == -2);
         if (c == -1) {
-            break;
+            goto main_term;
         }
         if (c == '\n') {
             c = '\r';
         }
         return c;
+    } else {
+        main_term:;
+#endif
+        int ret = read(0, &c, 1);
+        if (ret == 0) {
+            c = 4; // EOF, ctrl-D
+        } else if (c == '\n') {
+            c = '\r';
+        }
+        return c;
+#if MICROPY_PY_OS_DUPTERM
     }
-    #endif
-    int ret = read(0, &c, 1);
-    if (ret == 0) {
-        c = 4; // EOF, ctrl-D
-    } else if (c == '\n') {
-        c = '\r';
-    }
-    return c;
+#endif
 }
 
 void mp_hal_stdout_tx_strn(const char *str, size_t len) {
-- 
GitLab