summaryrefslogtreecommitdiffstatshomepage
path: root/unix/main.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-10-25 18:19:55 +0100
committerDamien George <damien.p.george@gmail.com>2014-10-25 23:37:57 +0100
commit124df6f8d07b53542b6960dbeea9b63bff469a67 (patch)
tree39ea11d0bed72ed828c406d2b4a8fc069b00ca4e /unix/main.c
parentd7353fe6fe9c9d421ef045c0eea8d4591710e1ba (diff)
downloadmicropython-124df6f8d07b53542b6960dbeea9b63bff469a67.tar.gz
micropython-124df6f8d07b53542b6960dbeea9b63bff469a67.zip
py: Add mp_pending_exception global variable, for VM soft interrupt.
This allows to implement KeyboardInterrupt on unix, and a much safer ctrl-C in stmhal port. First ctrl-C is a soft one, with hope that VM will notice it; second ctrl-C is a hard one that kills anything (for both unix and stmhal). One needs to check for a pending exception in the VM only for jump opcodes. Others can't produce an infinite loop (infinite recursion is caught by stack check).
Diffstat (limited to 'unix/main.c')
-rw-r--r--unix/main.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/unix/main.c b/unix/main.c
index a8de9fdee3..44542af51b 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -34,6 +34,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
+#include <signal.h>
#include "mpconfig.h"
#include "nlr.h"
@@ -64,6 +65,20 @@ mp_uint_t mp_verbose_flag = 0;
long heap_size = 128*1024 * (sizeof(mp_uint_t) / 4);
#endif
+STATIC mp_obj_t keyboard_interrupt_obj;
+
+STATIC void sighandler(int signum) {
+ if (signum == SIGINT) {
+ mp_obj_exception_clear_traceback(keyboard_interrupt_obj);
+ mp_pending_exception = keyboard_interrupt_obj;
+ // disable our handler so next we really die
+ struct sigaction sa;
+ sa.sa_handler = SIG_DFL;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGINT, &sa, NULL);
+ }
+}
+
#define FORCED_EXIT (0x100)
// returns standard error codes: 0 for success, 1 for all other errors
// if FORCED_EXIT bit is set then script raised SystemExit and the
@@ -119,14 +134,23 @@ STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind,
return 0;
}
+ // enable signal handler
+ struct sigaction sa;
+ sa.sa_handler = sighandler;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGINT, &sa, NULL);
+ sa.sa_handler = SIG_DFL;
+
// execute it
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_call_function_0(module_fun);
+ sigaction(SIGINT, &sa, NULL);
nlr_pop();
return 0;
} else {
// uncaught exception
+ sigaction(SIGINT, &sa, NULL);
// check for SystemExit
mp_obj_t exc = (mp_obj_t)nlr.ret_val;
if (mp_obj_is_subclass_fast(mp_obj_get_type(exc), &mp_type_SystemExit)) {
@@ -305,6 +329,9 @@ int main(int argc, char **argv) {
mp_init();
+ // create keyboard interrupt object
+ keyboard_interrupt_obj = mp_obj_new_exception(&mp_type_KeyboardInterrupt);
+
char *home = getenv("HOME");
char *path = getenv("MICROPYPATH");
if (path == NULL) {