diff --git a/issues/11-ctrl-c-repl-behaviour.md b/issues/11-ctrl-c-repl-behaviour.md index b3432c24..ec220fc3 100644 --- a/issues/11-ctrl-c-repl-behaviour.md +++ b/issues/11-ctrl-c-repl-behaviour.md @@ -1,6 +1,6 @@ # Issue #11 — Ctrl-C REPL behaviour -**Status:** open +**Status:** resolved ## Problem diff --git a/lua.c b/lua.c index b2967a44..9576f271 100644 --- a/lua.c +++ b/lua.c @@ -37,6 +37,11 @@ static lua_State *globalL = NULL; static const char *progname = LUA_PROGNAME; +#include + +static volatile sig_atomic_t sigint_in_repl = 0; +static sigjmp_buf repl_jmp; + #if defined(LUA_USE_POSIX) /* { */ @@ -81,6 +86,16 @@ static void laction (int i) { } +static void repl_sigint_handler (int i) { + if (sigint_in_repl) { + sigint_in_repl = 0; + siglongjmp(repl_jmp, 1); + } + signal(i, SIG_DFL); + raise(i); +} + + static void print_usage (const char *badoption) { lua_writestringerror("%s: ", progname); if (badoption[1] == 'e' || badoption[1] == 'l') @@ -566,8 +581,11 @@ static int incomplete (lua_State *L, int status) { static int pushline (lua_State *L, int firstline) { char buffer[LUA_MAXINPUT]; size_t l; + char *b; const char *prmt = get_prompt(L, firstline); - char *b = lua_readline(buffer, prmt); + sigint_in_repl = 1; + b = lua_readline(buffer, prmt); + sigint_in_repl = 0; lua_pop(L, 1); /* remove prompt */ if (b == NULL) return 0; /* no input */ @@ -678,11 +696,19 @@ static void doREPL (lua_State *L) { const char *oldprogname = progname; progname = NULL; /* no 'progname' on errors in interactive mode */ lua_initreadline(L); + setsignal(SIGINT, repl_sigint_handler); + if (sigsetjmp(repl_jmp, 1)) { + /* Ctrl-C during input — print newline, clear stack, re-prompt */ + lua_writestringerror("%s", "\n"); + lua_settop(L, 0); + setsignal(SIGINT, repl_sigint_handler); + } while ((status = loadline(L)) != -1) { if (status == LUA_OK) status = docall(L, 0, LUA_MULTRET); if (status == LUA_OK) l_print(L); else report(L, status); + setsignal(SIGINT, repl_sigint_handler); /* re-install after docall */ } lua_settop(L, 0); /* clear stack */ lua_writeline();