Let ctrl-c interrupt lua server pages in repl mode

This commit is contained in:
Justine Tunney 2022-05-14 11:47:16 -07:00
parent 178a6da4b9
commit 54e6f564c1
3 changed files with 32 additions and 3 deletions

View file

@ -380,6 +380,13 @@ int lua_loadline (lua_State *L) {
} }
void lua_sigint (lua_State *L, int sig) {
int flag = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT;
lua_sethook(L, lstop, flag, 1);
}
/* /*
** Function to be called at a C signal. Because a C signal cannot ** Function to be called at a C signal. Because a C signal cannot
** just change a Lua state (as there is no proper synchronization), ** just change a Lua state (as there is no proper synchronization),
@ -387,6 +394,7 @@ int lua_loadline (lua_State *L) {
** interpreter. ** interpreter.
*/ */
static void laction (int i) { static void laction (int i) {
lua_sigint(globalL, i);
int flag = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT; int flag = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT;
lua_sethook(globalL, lstop, flag, 1); lua_sethook(globalL, lstop, flag, 1);
} }

View file

@ -28,6 +28,7 @@ extern linenoiseCompletionCallback *lua_repl_completions_callback;
void lua_freerepl(void); void lua_freerepl(void);
int lua_loadline(lua_State *); int lua_loadline(lua_State *);
void lua_l_print(lua_State *); void lua_l_print(lua_State *);
void lua_sigint(lua_State *, int);
void lua_initrepl(lua_State *, const char *); void lua_initrepl(lua_State *, const char *);
int lua_report(lua_State *, int); int lua_report(lua_State *, int);
int lua_runchunk(lua_State *, int, int); int lua_runchunk(lua_State *, int, int);

View file

@ -42,6 +42,7 @@
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/fmt/fmt.h" #include "libc/fmt/fmt.h"
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/nomultics.internal.h" #include "libc/intrin/nomultics.internal.h"
#include "libc/intrin/spinlock.h" #include "libc/intrin/spinlock.h"
#include "libc/log/backtrace.internal.h" #include "libc/log/backtrace.internal.h"
@ -102,6 +103,7 @@
#include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/rusage.h" #include "libc/sysv/consts/rusage.h"
#include "libc/sysv/consts/s.h" #include "libc/sysv/consts/s.h"
#include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/shut.h" #include "libc/sysv/consts/shut.h"
#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/so.h" #include "libc/sysv/consts/so.h"
@ -2465,13 +2467,28 @@ static ssize_t YieldGenerator(struct iovec v[3]) {
return contentlength; return contentlength;
} }
static void OnLuaServerPageCtrlc(int i) {
lua_sigint(GL, i);
}
static int LuaCallWithYield(lua_State *L) { static int LuaCallWithYield(lua_State *L) {
int status; int status;
// since yield may happen in OnHttpRequest and in ServeLua, // since yield may happen in OnHttpRequest and in ServeLua,
// need to fully restart the yield generator; // need to fully restart the yield generator;
// the second set of headers is not going to be sent // the second set of headers is not going to be sent
struct sigaction sa, saold;
lua_State *co = lua_newthread(L); lua_State *co = lua_newthread(L);
if ((status = LuaCallWithTrace(L, 0, 0, co)) == LUA_YIELD) { if (__replmode) {
sa.sa_flags = SA_RESETHAND;
sa.sa_handler = OnLuaServerPageCtrlc;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, &saold);
}
status = LuaCallWithTrace(L, 0, 0, co);
if (__replmode) {
sigaction(SIGINT, &saold, 0);
}
if (status == LUA_YIELD) {
CHECK_GT(lua_gettop(L), 0); // make sure that coroutine is anchored CHECK_GT(lua_gettop(L), 0); // make sure that coroutine is anchored
YL = co; YL = co;
generator = YieldGenerator; generator = YieldGenerator;
@ -4924,10 +4941,10 @@ static int LuaLaunchBrowser(lua_State *L) {
} }
static bool LuaRunAsset(const char *path, bool mandatory) { static bool LuaRunAsset(const char *path, bool mandatory) {
int status;
struct Asset *a; struct Asset *a;
const char *code; const char *code;
size_t pathlen, codelen; size_t pathlen, codelen;
int status;
pathlen = strlen(path); pathlen = strlen(path);
if ((a = GetAsset(path, pathlen))) { if ((a = GetAsset(path, pathlen))) {
if ((code = FreeLater(LoadAsset(a, &codelen)))) { if ((code = FreeLater(LoadAsset(a, &codelen)))) {
@ -5310,7 +5327,7 @@ static void LuaInterpreter(lua_State *L) {
if (status == -2) { if (status == -2) {
if (errno == EINTR) { if (errno == EINTR) {
if ((sig = linenoiseGetInterrupt())) { if ((sig = linenoiseGetInterrupt())) {
raise(sig); kill(0, sig);
} }
} }
fprintf(stderr, "i/o error: %m\n"); fprintf(stderr, "i/o error: %m\n");
@ -6742,6 +6759,9 @@ static int HandleReadline(void) {
} else if (errno == EINTR) { } else if (errno == EINTR) {
errno = 0; errno = 0;
VERBOSEF("(repl) interrupt"); VERBOSEF("(repl) interrupt");
shutdownsig = SIGINT;
OnInt(SIGINT);
kill(0, SIGINT);
return -1; return -1;
} else if (errno == EAGAIN) { } else if (errno == EAGAIN) {
errno = 0; errno = 0;