aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--input.cpp2
-rw-r--r--reader.cpp25
-rw-r--r--reader.h14
3 files changed, 37 insertions, 4 deletions
diff --git a/input.cpp b/input.cpp
index 5c178be8..7ef8402a 100644
--- a/input.cpp
+++ b/input.cpp
@@ -507,7 +507,7 @@ wint_t input_readch()
/*
Clear the interrupted flag
*/
- reader_interrupted();
+ reader_reset_interrupted();
/*
Search for sequence in mapping tables
diff --git a/reader.cpp b/reader.cpp
index f90df311..b7d53112 100644
--- a/reader.cpp
+++ b/reader.cpp
@@ -323,6 +323,9 @@ public:
/** Whether a screen reset is needed after a repaint. */
bool screen_reset_needed;
+ /** Whether the reader should exit on ^C. */
+ bool interruptible;
+
/** Constructor */
reader_data_t() :
allow_autosuggestion(0),
@@ -339,7 +342,8 @@ public:
next(0),
search_mode(0),
repaint_needed(0),
- screen_reset_needed(0)
+ screen_reset_needed(0),
+ interruptible(0)
{
}
};
@@ -373,7 +377,7 @@ static pid_t original_pid;
/**
This variable is set to true by the signal handler when ^C is pressed
*/
-static int interrupted=0;
+static volatile int interrupted=0;
/*
@@ -632,11 +636,23 @@ static void remove_duplicates(std::vector<completion_t> &l)
l.erase(std::unique(l.begin(), l.end()), l.end());
}
+
+void reader_reset_interrupted()
+{
+ interrupted = 0;
+}
+
int reader_interrupted()
{
int res=interrupted;
if (res)
+ {
interrupted=0;
+ }
+ if (res && data && data->interruptible)
+ {
+ reader_exit(1, 0);
+ }
return res;
}
@@ -2380,6 +2396,11 @@ void reader_set_test_function(int (*f)(const wchar_t *))
data->test_func = f;
}
+void reader_set_interruptible(bool i)
+{
+ data->interruptible = i;
+}
+
void reader_import_history_if_necessary(void)
{
/* Import history from bash, etc. if our current history is empty */
diff --git a/reader.h b/reader.h
index ba024e86..f94d8a89 100644
--- a/reader.h
+++ b/reader.h
@@ -112,8 +112,17 @@ void reader_set_buffer(const wcstring &b, size_t p);
size_t reader_get_cursor_pos();
/**
+ Clear the interrupted flag unconditionally without handling anything. The
+ flag could have been set e.g. when an interrupt arrived just as we were
+ ending an earlier \c reader_readline invocation but before the
+ \c is_interactive_read flag was cleared.
+*/
+void reader_reset_interrupted();
+
+/**
Return the value of the interrupted flag, which is set by the sigint
- handler, and clear it if it was set.
+ handler, and clear it if it was set. If the current reader is interruptible,
+ call \c reader_exit().
*/
int reader_interrupted();
@@ -181,6 +190,9 @@ void reader_set_right_prompt(const wcstring &prompt);
/** Sets whether autosuggesting is allowed. */
void reader_set_allow_autosuggesting(bool flag);
+/** Sets whether the reader should exit on ^C. */
+void reader_set_interruptible(bool flag);
+
/**
Returns true if the shell is exiting, 0 otherwise.
*/