From c2e0ec801502ae26dae3dfdd035ff10436cffedd Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 6 Sep 2015 18:35:48 -0700 Subject: Allow evaluation from repl to be interrupted. * eval.c (do_eval): Check for pending signals. * parser.c (repl_intr): New static function. (repl): Set up signal handler for SIGINT around REPL. * signal.h (sig_deferred): declared. (sig_check_fast): New inline function/macro. A bit of a rearrangement here. --- eval.c | 1 + parser.c | 7 +++++++ signal.h | 11 ++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/eval.c b/eval.c index 2afc431c..a31a9bce 100644 --- a/eval.c +++ b/eval.c @@ -955,6 +955,7 @@ static val do_eval(val form, val env, val ctx_form, debug_enter; debug_check(consp(form) ? form : ctx_form, env, nil, nil, nil, nil); + sig_check_fast(); if (nilp(form)) { debug_return (nil); diff --git a/parser.c b/parser.c index c682f100..9a6217e8 100644 --- a/parser.c +++ b/parser.c @@ -473,6 +473,11 @@ static void provide_completions(const char *data, } } +static val repl_intr(val signo, val async_p) +{ + uw_throw(error_s, lit("intr")); +} + val repl(val bindings, val in_stream, val out_stream) { val ifd = stream_get_prop(in_stream, fd_k); @@ -489,6 +494,7 @@ val repl(val bindings, val in_stream, val out_stream) val result_hash = make_hash(nil, nil, nil); val done = nil; val counter = one; + val old_sig_handler = set_sig_handler(num(SIGINT), func_n2(repl_intr)); reg_varl(result_hash_sym, result_hash); @@ -570,6 +576,7 @@ val repl(val bindings, val in_stream, val out_stream) gc_hint(prompt); } + set_sig_handler(num(SIGINT), old_sig_handler); free(prompt_u8); free(line_u8); lino_free(ls); diff --git a/signal.h b/signal.h index 4b942275..2b6245e0 100644 --- a/signal.h +++ b/signal.h @@ -70,6 +70,14 @@ extern int debug_depth; sig_check(); \ } while(0) +val sig_check(void); + +INLINE val sig_check_fast(void) +{ + extern volatile unsigned long sig_deferred; + return if2(sig_deferred, sig_check()); +} + typedef struct { jmp_buf jb; sig_atomic_t se; @@ -112,6 +120,8 @@ extern volatile sig_atomic_t async_sig_enabled; #define sig_restore_enable } while (0) #define sig_restore_disable } while (0) +#define sig_check_fast() ((void) 0) + typedef struct { jmp_buf jb; val de; @@ -146,7 +156,6 @@ extern val dyn_env; /* eval.c */ void sig_init(void); val set_sig_handler(val signo, val lambda); val get_sig_handler(val signo); -val sig_check(void); #if HAVE_POSIX_SIGS int sig_mask(int how, const sigset_t *set, sigset_t *oldset); #endif -- cgit v1.2.3