Added proper handling of SIGINT (C-c) and SIGPIPE (pager quits).
This commit is contained in:
parent
04ac5ffcb4
commit
863b5d8144
4 changed files with 52 additions and 11 deletions
|
|
@ -78,8 +78,10 @@ public:
|
|||
handler->flush();
|
||||
}
|
||||
virtual void operator()(T& item) {
|
||||
if (handler.get())
|
||||
if (handler.get()) {
|
||||
check_for_signal();
|
||||
(*handler.get())(item);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
20
src/main.cc
20
src/main.cc
|
|
@ -57,11 +57,6 @@ namespace {
|
|||
return s;
|
||||
}
|
||||
|
||||
void sigint_handler(int sig)
|
||||
{
|
||||
throw std::logic_error("Interrupted by user (use Control-D to quit)");
|
||||
}
|
||||
|
||||
strings_list split_arguments(char * line)
|
||||
{
|
||||
strings_list args;
|
||||
|
|
@ -177,12 +172,16 @@ namespace {
|
|||
catch (const std::exception& err) {
|
||||
std::cout.flush(); // first display anything that was pending
|
||||
|
||||
// Display any pending error context information
|
||||
string context = error_context();
|
||||
if (! context.empty())
|
||||
std::cerr << context << std::endl;
|
||||
if (caught_signal == NONE_CAUGHT) {
|
||||
// Display any pending error context information
|
||||
string context = error_context();
|
||||
if (! context.empty())
|
||||
std::cerr << context << std::endl;
|
||||
|
||||
std::cerr << "Error: " << err.what() << std::endl;
|
||||
std::cerr << "Error: " << err.what() << std::endl;
|
||||
} else {
|
||||
caught_signal = NONE_CAUGHT;
|
||||
}
|
||||
}
|
||||
catch (int _status) {
|
||||
status = _status; // used for a "quick" exit, and is used only
|
||||
|
|
@ -226,6 +225,7 @@ int main(int argc, char * argv[], char * envp[])
|
|||
session->option_version(*session);
|
||||
|
||||
std::signal(SIGINT, sigint_handler);
|
||||
std::signal(SIGPIPE, sigpipe_handler);
|
||||
|
||||
#ifdef HAVE_LIBEDIT
|
||||
|
||||
|
|
|
|||
17
src/utils.cc
17
src/utils.cc
|
|
@ -626,6 +626,23 @@ void finish_timer(const char * name)
|
|||
|
||||
#endif // LOGGING_ON && TIMERS_ON
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Signal handlers
|
||||
*/
|
||||
|
||||
caught_signal_t caught_signal = NONE_CAUGHT;
|
||||
|
||||
void sigint_handler(int sig)
|
||||
{
|
||||
caught_signal = INTERRUPTED;
|
||||
}
|
||||
|
||||
void sigpipe_handler(int sig)
|
||||
{
|
||||
caught_signal = PIPE_CLOSED;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* General utility functions
|
||||
|
|
|
|||
22
src/utils.h
22
src/utils.h
|
|
@ -475,6 +475,28 @@ void finish_timer(const char * name);
|
|||
#include "stream.h"
|
||||
#include "pushvar.h"
|
||||
|
||||
enum caught_signal_t {
|
||||
NONE_CAUGHT,
|
||||
INTERRUPTED,
|
||||
PIPE_CLOSED
|
||||
};
|
||||
|
||||
extern caught_signal_t caught_signal;
|
||||
|
||||
void sigint_handler(int sig);
|
||||
void sigpipe_handler(int sig);
|
||||
|
||||
inline void check_for_signal() {
|
||||
switch (caught_signal) {
|
||||
case NONE_CAUGHT:
|
||||
break;
|
||||
case INTERRUPTED:
|
||||
throw std::runtime_error("Interrupted by user (use Control-D to quit)");
|
||||
case PIPE_CLOSED:
|
||||
throw std::runtime_error("Pipe terminated");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name General utility functions
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue