8000 ports/unix: Add full uos.dupterm support. · micropython/micropython@7199c61 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7199c61

Browse files
committed
ports/unix: Add full uos.dupterm support.
1 parent cae77da commit 7199c61

File tree

3 files changed

+93
-45
lines changed

3 files changed

+93
-45
lines changed

ports/unix/main.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,12 @@ long heap_size = 1024 * 1024 * (sizeof(mp_uint_t) / 4);
6464

6565
STATIC void stderr_print_strn(void *env, const char *str, size_t len) {
6666
(void)env;
67+
#if MICROPY_PY_OS_DUPTERM
68+
mp_uos_dupterm_tx_strn(str, len);
69+
#else
6770
ssize_t ret;
6871
MP_HAL_RETRY_SYSCALL(ret, write(STDERR_FILENO, str, len), {});
69-
mp_uos_dupterm_tx_strn(str, len);
72+
#endif
7073
}
7174

7275
const mp_print_t mp_stderr_print = {NULL, stderr_print_strn};
@@ -535,6 +538,10 @@ MP_NOINLINE int main_(int argc, char **argv) {
535538
}
536539
#endif
537540

541+
#if MICROPY_PY_OS_DUPTERM
542+
init_dupterm_stdio();
543+
#endif
544+
538545
// Here is some example code to create a class and instance of that class.
539546
// First is the Python, then the C code.
540547
//

ports/unix/mphalport.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,7 @@ enum {
103103

104104
void mp_hal_get_mac(int idx, uint8_t buf[6]);
105105
#endif
106+
107+
#if MICROPY_PY_OS_DUPTERM
108+
void init_dupterm_stdio();
109+
#endif

ports/unix/unix_mphal.c

Lines changed: 81 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include "py/mphal.h"
3434
#include "py/mpthread.h"
3535
#include "py/runtime.h"
36+
#include "py/stream.h"
37+
#include "py/mperrno.h"
3638
#include "extmod/misc.h"
3739

3840
#ifndef _WIN32
@@ -64,8 +66,11 @@ STATIC void sighandler(int signum) {
6466
}
6567
#endif
6668

69+
int mp_interrupt_char = -1;
70+
6771
void mp_hal_set_interrupt_char(char c) {
6872
// configure terminal settings to (not) let ctrl-C through
73+
mp_interrupt_char = c;
6974
if (c == CHAR_CTRL_C) {
7075
#ifndef _WIN32
7176
// enable signal handler
@@ -114,57 +119,85 @@ void mp_hal_stdio_mode_orig(void) {
114119
#endif
115120

116121
#if MICROPY_PY_OS_DUPTERM
117-
static int call_dupterm_read(size_t idx) {
118-
nlr_buf_t nlr;
119-
if (nlr_push(&nlr) == 0) {
120-
mp_obj_t read_m[3];
121-
mp_load_method(MP_STATE_VM(dupterm_objs[idx]), MP_QSTR_read, read_m);
122-
read_m[2] = MP_OBJ_NEW_SMALL_INT(1);
123-
mp_obj_t res = mp_call_method_n_kw(1, 0, read_m);
124-
if (res == mp_const_none) {
125-
return -2;
126-
}
127-
mp_buffer_info_t bufinfo;
128-
mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ);
129-
if (bufinfo.len == 0) {
130-
mp_printf(&mp_plat_print, "dupterm: EOF received, deactivating\n");
131-
MP_STATE_VM(dupterm_objs[idx]) = MP_OBJ_NULL;
132-
return -1;
133-
}
134-
nlr_pop();
135-
return *(byte *)bufinfo.buf;
136-
} else {
137-
// Temporarily disable dupterm to avoid infinite recursion
138-
mp_obj_t save_term = MP_STATE_VM(dupterm_objs[idx]);
139-
MP_STATE_VM(dupterm_objs[idx]) = NULL;
140-
mp_printf(&mp_plat_print, "dupterm: ");
141-
mp_obj_print_exception(&mp_plat_print, nlr.ret_val);
142-
MP_STATE_VM(dupterm_objs[idx]) = save_term;
122+
STATIC mp_uint_t unix_stdio_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
123+
ssize_t ret;
124+
MP_HAL_RETRY_SYSCALL(ret, read(STDIN_FILENO, (byte *)buf, size), {});
125+
if (ret == 0) {
126+
// return EAGAIN error to indicate non-blocking
127+
*errcode = MP_EAGAIN;
128+
return MP_STREAM_ERROR;
129+
}
130+
return ret;
131+
}
132+
133+
STATIC mp_uint_t unix_stdio_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
134+
int r 9E7A et;
135+
MP_HAL_RETRY_SYSCALL(ret, write(STDOUT_FILENO, (const byte *)buf, size), {});
136+
if (ret == 0) {
137+
// return EAGAIN error to indicate non-blocking
138+
*errcode = MP_EAGAIN;
139+
return MP_STREAM_ERROR;
143140
}
141+
return ret;
142+
}
143+
144+
STATIC mp_uint_t unix_stdio_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
145+
*errcode = MP_EINVAL;
146+
return MP_STREAM_ERROR;
147+
}
148+
149+
STATIC mp_obj_t unix_stdio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
150+
151+
STATIC const mp_stream_p_t unix_stdio_stream_p = {
152+
.read = unix_stdio_read,
153+
.write = unix_stdio_write,
154+
.ioctl = unix_stdio_ioctl,
155+
};
156+
157+
STATIC const mp_rom_map_elem_t unix_stdio_locals_dict_table[] = {
158+
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
159+
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
160+
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)},
161+
{ MP_ROM_QSTR( F438 MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj)},
162+
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
163+
};
164+
STATIC MP_DEFINE_CONST_DICT(unix_stdio_locals_dict, unix_stdio_locals_dict_table);
165+
166+
const mp_obj_type_t unix_stdio_type = {
167+
{ &mp_type_type },
168+
.name = MP_QSTR_UNIX_STDIO,
169+
.make_new = unix_stdio_make_new,
170+
.protocol = &unix_stdio_stream_p,
171+
.locals_dict = (mp_obj_dict_t *)&unix_stdio_locals_dict,
172+
};
173+
174+
typedef struct _unix_stdio_obj_t {
175+
mp_obj_base_t base;
176+
} unix_stdio_obj_t;
177+
178+
STATIC const unix_stdio_obj_t unix_stdio_obj = {{&unix_stdio_type}};
179+
180+
STATIC mp_obj_t unix_stdio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
181+
mp_arg_check_num(n_args, n_kw, 0, 0, false);
182+
return MP_OBJ_FROM_PTR(&unix_stdio_obj);
183+
}
144184

145-
return -1;
185+
void init_dupterm_stdio() {
186+
MP_STATE_VM(dupterm_objs[0]) = MP_OBJ_FROM_PTR(&unix_stdio_obj);
146187
}
147188
#endif
148189

149190
int mp_hal_stdin_rx_chr(void) {
150191
#if MICROPY_PY_OS_DUPTERM
151-
// TODO only support dupterm one slot at the moment
152-
if (MP_STATE_VM(dupterm_objs[0]) != MP_OBJ_NULL) {
153-
int c;
154-
do {
155-
c = call_dupterm_read(0);
156-
} while (c == -2);
157-
if (c == -1) {
158-
goto main_term;
159-
}
160-
if (c == '\n') {
161-
c = '\r';
162-
}
163-
return c;
192+
int c;
193+
do {
194+
c = mp_uos_dupterm_rx_chr();
195+
} while (c == -2);
196+
if (c == '\n') {
197+
c = '\r';
164198
}
165-
main_term:;
166-
#endif
167-
199+
return c;
200+
#else
168201
unsigned char c;
169202
ssize_t ret;
170203
MP_HAL_RETRY_SYSCALL(ret, read(STDIN_FILENO, &c, 1), {});
@@ -174,12 +207,16 @@ main_term:;
174207
c = '\r';
175208
}
176209
return c;
210+
#endif
177211
}
178212

179213
void mp_hal_stdout_tx_strn(const char *str, size_t len) {
214+
#if MICROPY_PY_OS_DUPTERM
215+
mp_uos_dupterm_tx_strn(str, len);
216+
#else
180217
ssize_t ret;
181218
MP_HAL_RETRY_SYSCALL(ret, write(STDOUT_FILENO, str, len), {});
182-
mp_uos_dupterm_tx_strn(str, len);
219+
#endif
183220
}
184221

185222
// cooked is same as uncooked because the terminal does some postprocessing

0 commit comments

Comments
 (0)
0