Skip to content

Commit fd1ddc3

Browse files
committed
shared/runtime/pyexec: Call mp_hal_stdio_mode_orig/raw as appropriate.
This ensures that ctrl-C works on the unix port when executing code at the REPL. Signed-off-by: Damien George <damien@micropython.org>
1 parent e06ac9c commit fd1ddc3

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

ports/unix/main.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ static int do_repl(void) {
193193
// use MicroPython supplied readline-based REPL
194194

195195
int ret = 0;
196-
mp_hal_stdio_mode_raw();
197196
for (;;) {
198197
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
199198
if ((ret = pyexec_raw_repl()) != 0) {
@@ -205,7 +204,6 @@ static int do_repl(void) {
205204
}
206205
}
207206
}
208-
mp_hal_stdio_mode_orig();
209207
return ret;
210208

211209
#else

ports/unix/mphalport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
MP_THREAD_GIL_ENTER(); \
4949
} while (0)
5050

51+
// The port provides `mp_hal_stdio_mode_raw()` and `mp_hal_stdio_mode_orig()`.
52+
#define MICROPY_HAL_HAS_STDIO_MODE_SWITCH (1)
53+
5154
void mp_hal_set_interrupt_char(char c);
5255

5356
#define mp_hal_stdio_poll unused // this is not implemented, nor needed

shared/runtime/pyexec.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,20 @@ MP_REGISTER_ROOT_POINTER(vstr_t * repl_line);
536536

537537
#else // MICROPY_REPL_EVENT_DRIVEN
538538

539+
#if !MICROPY_HAL_HAS_STDIO_MODE_SWITCH
540+
// If the port doesn't need any stdio mode switching calls then provide trivial ones.
541+
static inline void mp_hal_stdio_mode_raw(void) {
542+
}
543+
static inline void mp_hal_stdio_mode_orig(void) {
544+
}
545+
#endif
546+
539547
int pyexec_raw_repl(void) {
540548
vstr_t line;
541549
vstr_init(&line, 32);
542550

551+
mp_hal_stdio_mode_raw();
552+
543553
raw_repl_reset:
544554
mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n");
545555

@@ -553,6 +563,7 @@ int pyexec_raw_repl(void) {
553563
if (vstr_len(&line) == 2 && vstr_str(&line)[0] == CHAR_CTRL_E) {
554564
int ret = do_reader_stdin(vstr_str(&line)[1]);
555565
if (ret & PYEXEC_FORCED_EXIT) {
566+
mp_hal_stdio_mode_orig();
556567
return ret;
557568
}
558569
vstr_reset(&line);
@@ -565,6 +576,7 @@ int pyexec_raw_repl(void) {
565576
mp_hal_stdout_tx_str("\r\n");
566577
vstr_clear(&line);
567578
pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
579+
mp_hal_stdio_mode_orig();
568580
return 0;
569581
} else if (c == CHAR_CTRL_C) {
570582
// clear line
@@ -585,20 +597,26 @@ int pyexec_raw_repl(void) {
585597
// exit for a soft reset
586598
mp_hal_stdout_tx_str("\r\n");
587599
vstr_clear(&line);
600+
mp_hal_stdio_mode_orig();
588601
return PYEXEC_FORCED_EXIT;
589602
}
590603

604+
// Switch to original terminal mode to execute code, eg to support keyboard interrupt (SIGINT).
605+
mp_hal_stdio_mode_orig();
591606
int ret = parse_compile_execute(&line, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR);
592607
if (ret & PYEXEC_FORCED_EXIT) {
593608
return ret;
594609
}
610+
mp_hal_stdio_mode_raw();
595611
}
596612
}
597613

598614
int pyexec_friendly_repl(void) {
599615
vstr_t line;
600616
vstr_init(&line, 32);
601617

618+
mp_hal_stdio_mode_raw();
619+
602620
friendly_repl_reset:
603621
mp_hal_stdout_tx_str(MICROPY_BANNER_NAME_AND_VERSION);
604622
mp_hal_stdout_tx_str("; " MICROPY_BANNER_MACHINE);
@@ -640,6 +658,7 @@ int pyexec_friendly_repl(void) {
640658
mp_hal_stdout_tx_str("\r\n");
641659
vstr_clear(&line);
642660
pyexec_mode_kind = PYEXEC_MODE_RAW_REPL;
661+
mp_hal_stdio_mode_orig();
643662
return 0;
644663
} else if (ret == CHAR_CTRL_B) {
645664
// reset friendly REPL
@@ -653,6 +672,7 @@ int pyexec_friendly_repl(void) {
653672
// exit for a soft reset
654673
mp_hal_stdout_tx_str("\r\n");
655674
vstr_clear(&line);
675+
mp_hal_stdio_mode_orig();
656676
return PYEXEC_FORCED_EXIT;
657677
} else if (ret == CHAR_CTRL_E) {
658678
// paste mode
@@ -697,10 +717,13 @@ int pyexec_friendly_repl(void) {
697717
}
698718
}
699719

720+
// Switch to original terminal mode to execute code, eg to support keyboard interrupt (SIGINT).
721+
mp_hal_stdio_mode_orig();
700722
ret = parse_compile_execute(&line, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR);
701723
if (ret & PYEXEC_FORCED_EXIT) {
702724
return ret;
703725
}
726+
mp_hal_stdio_mode_raw();
704727
}
705728
}
706729

0 commit comments

Comments
 (0)