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
** just change a Lua state (as there is no proper synchronization),
@ -387,6 +394,7 @@ int lua_loadline (lua_State *L) {
** interpreter.
*/
static void laction (int i) {
lua_sigint(globalL, i);
int flag = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT;
lua_sethook(globalL, lstop, flag, 1);
}

View file

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

View file

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