Handle SIGINT to cancel the current line

This commit is contained in:
Eelco Dolstra 2013-09-06 13:01:02 +02:00
parent 504563ea44
commit 4fb82d3d80

View file

@ -1,6 +1,8 @@
#include <iostream> #include <iostream>
#include <cstdlib> #include <cstdlib>
#include <setjmp.h>
#include <readline/readline.h> #include <readline/readline.h>
#include <readline/history.h> #include <readline/history.h>
@ -42,13 +44,41 @@ void printHelp()
} }
/* Apparently, the only way to get readline() to return on Ctrl-C
(SIGINT) is to use siglongjmp(). That's fucked up... */
static sigjmp_buf sigintJmpBuf;
static void sigintHandler(int signo)
{
siglongjmp(sigintJmpBuf, 1);
}
bool getLine(string & line) bool getLine(string & line)
{ {
char * s = readline("nix-repl> "); struct sigaction act, old;
if (!s) return false; act.sa_handler = sigintHandler;
line = chomp(string(s)); sigfillset(&act.sa_mask);
free(s); act.sa_flags = 0;
if (line != "") add_history(line.c_str()); if (sigaction(SIGINT, &act, &old))
throw SysError("installing handler for SIGINT");
if (sigsetjmp(sigintJmpBuf, 1))
line = "";
else {
char * s = readline("nix-repl> ");
if (!s) return false;
line = chomp(string(s));
free(s);
if (line != "") add_history(line.c_str());
}
_isInterrupted = 0;
if (sigaction(SIGINT, &old, 0))
throw SysError("restoring handler for SIGINT");
return true; return true;
} }
@ -98,6 +128,8 @@ void NixRepl::mainLoop()
void NixRepl::processLine(string line) void NixRepl::processLine(string line)
{ {
if (line == "") return;
if (string(line, 0, 2) == ":a") { if (string(line, 0, 2) == ":a") {
Value v; Value v;
evalString(string(line, 2), v); evalString(string(line, 2), v);