Handle SIGINT to cancel the current line
This commit is contained in:
parent
504563ea44
commit
4fb82d3d80
1 changed files with 37 additions and 5 deletions
42
nix-repl.cc
42
nix-repl.cc
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue