33
33
#include "py/mphal.h"
34
34
#include "py/mpthread.h"
35
35
#include "py/runtime.h"
36
+ #include "py/stream.h"
37
+ #include "py/mperrno.h"
36
38
#include "extmod/misc.h"
37
39
38
40
#ifndef _WIN32
@@ -64,8 +66,11 @@ STATIC void sighandler(int signum) {
64
66
}
65
67
#endif
66
68
69
+ int mp_interrupt_char = -1 ;
70
+
67
71
void mp_hal_set_interrupt_char (char c ) {
68
72
// configure terminal settings to (not) let ctrl-C through
73
+ mp_interrupt_char = c ;
69
74
if (c == CHAR_CTRL_C ) {
70
75
#ifndef _WIN32
71
76
// enable signal handler
@@ -114,57 +119,85 @@ void mp_hal_stdio_mode_orig(void) {
114
119
#endif
115
120
116
121
#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 ;
143
140
}
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
+ }
144
184
145
- return -1 ;
185
+ void init_dupterm_stdio () {
186
+ MP_STATE_VM (dupterm_objs [0 ]) = MP_OBJ_FROM_PTR (& unix_stdio_obj );
146
187
}
147
188
#endif
148
189
149
190
int mp_hal_stdin_rx_chr (void ) {
150
191
#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' ;
164
198
}
165
- main_term :;
166
- #endif
167
-
199
+ return c ;
200
+ #else
168
201
unsigned char c ;
169
202
ssize_t ret ;
170
203
MP_HAL_RETRY_SYSCALL (ret , read (STDIN_FILENO , & c , 1 ), {});
@@ -174,12 +207,16 @@ main_term:;
174
207
c = '\r' ;
175
208
}
176
209
return c ;
210
+ #endif
177
211
}
178
212
179
213
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
180
217
ssize_t ret ;
181
218
MP_HAL_RETRY_SYSCALL (ret , write (STDOUT_FILENO , str , len ), {});
182
- mp_uos_dupterm_tx_strn ( str , len );
219
+ #endif
183
220
}
184
221
185
222
// cooked is same as uncooked because the terminal does some postprocessing
0 commit comments