Skip to content

Commit 2c1620c

Browse files
committed
unix: Implement uos.dupterm(). Conditional on MICROPY_PY_OS_DUPTERM.
1 parent 3ea03a1 commit 2c1620c

6 files changed

Lines changed: 82 additions & 0 deletions

File tree

unix/file.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "py/runtime.h"
3636
#include "py/stream.h"
3737
#include "py/builtin.h"
38+
#include "py/mphal.h"
3839

3940
#if MICROPY_PY_IO
4041

@@ -80,6 +81,12 @@ STATIC mp_uint_t fdfile_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errc
8081
STATIC mp_uint_t fdfile_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
8182
mp_obj_fdfile_t *o = MP_OBJ_TO_PTR(o_in);
8283
check_fd_is_open(o);
84+
#if MICROPY_PY_OS_DUPTERM
85+
if (o->fd <= STDERR_FILENO) {
86+
mp_hal_stdout_tx_strn(buf, size);
87+
return size;
88+
}
89+
#endif
8390
mp_int_t r = write(o->fd, buf, size);
8491
if (r == -1) {
8592
*errcode = errno;

unix/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ long heap_size = 1024*1024 * (sizeof(mp_uint_t) / 4);
6161
STATIC void stderr_print_strn(void *env, const char *str, size_t len) {
6262
(void)env;
6363
ssize_t dummy = write(STDERR_FILENO, str, len);
64+
mp_hal_dupterm_tx_strn(str, len);
6465
(void)dummy;
6566
}
6667

unix/modos.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,26 @@ STATIC mp_obj_t mod_os_errno(mp_uint_t n_args, const mp_obj_t *args) {
215215
}
216216
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_os_errno_obj, 0, 1, mod_os_errno);
217217

218+
#if MICROPY_PY_OS_DUPTERM
219+
STATIC mp_obj_t mod_os_dupterm(mp_uint_t n_args, const mp_obj_t *args) {
220+
if (n_args == 0) {
221+
if (MP_STATE_PORT(term_obj) == MP_OBJ_NULL) {
222+
return mp_const_none;
223+
} else {
224+
return MP_STATE_PORT(term_obj);
225+
}
226+
} else {
227+
if (args[0] == mp_const_none) {
228+
MP_STATE_PORT(term_obj) = NULL;
229+
} else {
230+
MP_STATE_PORT(term_obj) = args[0];
231+
}
232+
return mp_const_none;
233+
}
234+
}
235+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_os_dupterm_obj, 0, 1, mod_os_dupterm);
236+
#endif
237+
218238
STATIC const mp_rom_map_elem_t mp_module_os_globals_table[] = {
219239
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) },
220240
{ MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mod_os_errno_obj) },
@@ -227,6 +247,9 @@ STATIC const mp_rom_map_elem_t mp_module_os_globals_table[] = {
227247
{ MP_ROM_QSTR(MP_QSTR_getenv), MP_ROM_PTR(&mod_os_getenv_obj) },
228248
{ MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mod_os_mkdir_obj) },
229249
{ MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mod_os_ilistdir_obj) },
250+
#if MICROPY_PY_OS_DUPTERM
251+
{ MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mod_os_dupterm_obj) },
252+
#endif
230253
};
231254

232255
STATIC MP_DEFINE_CONST_DICT(mp_module_os_globals, mp_module_os_globals_table);

unix/mpconfigport.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,12 @@ void mp_unix_mark_exec(void);
210210
#define MP_PLAT_ALLOC_EXEC(min_size, ptr, size) mp_unix_alloc_exec(min_size, ptr, size)
211211
#define MP_PLAT_FREE_EXEC(ptr, size) mp_unix_free_exec(ptr, size)
212212

213+
#if MICROPY_PY_OS_DUPTERM
214+
#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
215+
#else
213216
#include <unistd.h>
214217
#define MP_PLAT_PRINT_STRN(str, len) do { ssize_t ret = write(1, str, len); (void)ret; } while (0)
218+
#endif
215219

216220
#ifdef __linux__
217221
// Can access physical memory using /dev/mem
@@ -239,9 +243,19 @@ extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
239243

240244
#define MP_STATE_PORT MP_STATE_VM
241245

246+
#if MICROPY_PY_OS_DUPTERM
247+
#define ROOT_POINTERS_1 mp_obj_t term_obj
248+
#include <stddef.h>
249+
void mp_hal_dupterm_tx_strn(const char *str, size_t len);
250+
#else
251+
#define ROOT_POINTERS_1
252+
#define mp_hal_dupterm_tx_strn(s, l)
253+
#endif
254+
242255
#define MICROPY_PORT_ROOT_POINTERS \
243256
const char *readline_hist[50]; \
244257
mp_obj_t keyboard_interrupt_obj; \
258+
ROOT_POINTERS_1; \
245259
void *mmap_region_head; \
246260

247261
// We need to provide a declaration/definition of alloca()

unix/qstrdefsport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ Q(getenv)
4545
Q(mkdir)
4646
Q(ilistdir)
4747
Q(errno)
48+
#if MICROPY_PY_OS_DUPTERM
49+
Q(dupterm)
50+
#endif
4851

4952
Q(uselect)
5053
Q(poll)

unix/unix_mphal.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include "py/mpstate.h"
3333
#include "py/mphal.h"
34+
#include "py/runtime.h"
3435

3536
#ifndef _WIN32
3637
#include <signal.h>
@@ -106,8 +107,40 @@ void mp_hal_stdio_mode_orig(void) {
106107

107108
#endif
108109

110+
#if MICROPY_PY_OS_DUPTERM
111+
void mp_hal_dupterm_tx_strn(const char *str, size_t len) {
112+
if (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) {
113+
mp_obj_t write_m[3];
114+
mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_write, write_m);
115+
write_m[2] = mp_obj_new_bytearray_by_ref(len, (char*)str);
116+
mp_call_method_n_kw(1, 0, write_m);
117+
}
118+
}
119+
#endif
120+
109121
int mp_hal_stdin_rx_chr(void) {
110122
unsigned char c;
123+
#if MICROPY_PY_OS_DUPTERM
124+
while (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) {
125+
mp_obj_t read_m[3];
126+
mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_read, read_m);
127+
read_m[2] = MP_OBJ_NEW_SMALL_INT(1);
128+
mp_obj_t res = mp_call_method_n_kw(1, 0, read_m);
129+
if (res == mp_const_none) {
130+
break;
131+
}
132+
mp_buffer_info_t bufinfo;
133+
mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ);
134+
if (bufinfo.len == 0) {
135+
break;
136+
}
137+
c = *(byte*)bufinfo.buf;
138+
if (c == '\n') {
139+
c = '\r';
140+
}
141+
return c;
142+
}
143+
#endif
111144
int ret = read(0, &c, 1);
112145
if (ret == 0) {
113146
c = 4; // EOF, ctrl-D
@@ -119,6 +152,7 @@ int mp_hal_stdin_rx_chr(void) {
119152

120153
void mp_hal_stdout_tx_strn(const char *str, size_t len) {
121154
int ret = write(1, str, len);
155+
mp_hal_dupterm_tx_strn(str, len);
122156
(void)ret; // to suppress compiler warning
123157
}
124158

0 commit comments

Comments
 (0)