forked from OctaForge/libcubescript
allow SIGINT to interrupt infinite loops
parent
605efea9e2
commit
fb8a793d66
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include <ostd/string.hh>
|
#include <ostd/string.hh>
|
||||||
#include <ostd/maybe.hh>
|
#include <ostd/maybe.hh>
|
||||||
|
@ -68,6 +69,7 @@ static ostd::Maybe<ostd::String> read_line(CsSvar *pr) {
|
||||||
if (!line) {
|
if (!line) {
|
||||||
/* linenoise traps ctrl-c, detect it and let the user exit */
|
/* linenoise traps ctrl-c, detect it and let the user exit */
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
|
raise(SIGINT);
|
||||||
return ostd::nothing;
|
return ostd::nothing;
|
||||||
}
|
}
|
||||||
return ostd::String();
|
return ostd::String();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include <ostd/platform.hh>
|
#include <ostd/platform.hh>
|
||||||
#include <ostd/io.hh>
|
#include <ostd/io.hh>
|
||||||
#include <ostd/string.hh>
|
#include <ostd/string.hh>
|
||||||
|
@ -162,6 +164,38 @@ static CsCommand *get_hint_cmd(ostd::ConstCharRange buf) {
|
||||||
#include "tools/edit_readline.hh"
|
#include "tools/edit_readline.hh"
|
||||||
#include "tools/edit_fallback.hh"
|
#include "tools/edit_fallback.hh"
|
||||||
|
|
||||||
|
struct InterruptedException {
|
||||||
|
};
|
||||||
|
|
||||||
|
static void do_sigint(int n) {
|
||||||
|
/* in case another SIGINT happens, terminate normally */
|
||||||
|
signal(n, SIG_DFL);
|
||||||
|
if (gcs) {
|
||||||
|
gcs->set_call_hook([]() {
|
||||||
|
gcs->set_call_hook(nullptr);
|
||||||
|
throw InterruptedException{};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_call(CsState &cs, ostd::ConstCharRange line) {
|
||||||
|
CsValue ret;
|
||||||
|
ret.set_null();
|
||||||
|
signal(SIGINT, do_sigint);
|
||||||
|
try {
|
||||||
|
cs.run_ret(line, ret);
|
||||||
|
} catch (InterruptedException) {
|
||||||
|
signal(SIGINT, SIG_DFL);
|
||||||
|
ret.cleanup();
|
||||||
|
ostd::writeln("<execution interrupted>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
signal(SIGINT, SIG_DFL);
|
||||||
|
if (ret.get_type() != CsValueType::null) {
|
||||||
|
ostd::writeln(ret.get_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void do_tty(CsState &cs) {
|
static void do_tty(CsState &cs) {
|
||||||
auto prompt = cs.new_svar("PROMPT", "> ");
|
auto prompt = cs.new_svar("PROMPT", "> ");
|
||||||
auto prompt2 = cs.new_svar("PROMPT2", ">> ");
|
auto prompt2 = cs.new_svar("PROMPT2", ">> ");
|
||||||
|
@ -207,12 +241,7 @@ static void do_tty(CsState &cs) {
|
||||||
lv += line2.value();
|
lv += line2.value();
|
||||||
}
|
}
|
||||||
add_history(lv);
|
add_history(lv);
|
||||||
CsValue ret;
|
do_call(cs, lv);
|
||||||
ret.set_null();
|
|
||||||
cs.run_ret(lv, ret);
|
|
||||||
if (ret.get_type() != CsValueType::null) {
|
|
||||||
ostd::writeln(ret.get_str());
|
|
||||||
}
|
|
||||||
if (do_exit) {
|
if (do_exit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue