diff --git a/tools/cabana/cabana.cc b/tools/cabana/cabana.cc index d2c451be89..49b8fcf6ca 100644 --- a/tools/cabana/cabana.cc +++ b/tools/cabana/cabana.cc @@ -15,6 +15,8 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); app.setApplicationDisplayName("Cabana"); app.setWindowIcon(QIcon(":cabana-icon.png")); + + UnixSignalHandler signalHandler; utils::setTheme(settings.theme); QCommandLineParser cmd_parser; diff --git a/tools/cabana/util.cc b/tools/cabana/util.cc index bb588ad05f..1df90d32e6 100644 --- a/tools/cabana/util.cc +++ b/tools/cabana/util.cc @@ -1,7 +1,11 @@ #include "tools/cabana/util.h" #include +#include +#include +#include +#include #include #include #include @@ -145,6 +149,40 @@ void TabBar::closeTabClicked() { } } +// UnixSignalHandler + +UnixSignalHandler::UnixSignalHandler(QObject *parent) : QObject(nullptr) { + if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sig_fd)) { + qFatal("Couldn't create TERM socketpair"); + } + + sn = new QSocketNotifier(sig_fd[1], QSocketNotifier::Read, this); + connect(sn, SIGNAL(activated(QSocketDescriptor)), this, SLOT(handleSigTerm())); + std::signal(SIGINT, signalHandler); + std::signal(SIGTERM, UnixSignalHandler::signalHandler); +} + +UnixSignalHandler::~UnixSignalHandler() { + ::close(sig_fd[0]); + ::close(sig_fd[1]); +} + +void UnixSignalHandler::signalHandler(int s) { + ::write(sig_fd[0], &s, sizeof(s)); +} + +void UnixSignalHandler::handleSigTerm() { + sn->setEnabled(false); + int tmp; + ::read(sig_fd[1], &tmp, sizeof(tmp)); + + printf("\nexiting...\n"); + qApp->closeAllWindows(); + qApp->exit(); +} + +// NameValidator + NameValidator::NameValidator(QObject *parent) : QRegExpValidator(QRegExp("^(\\w+)"), parent) {} QValidator::State NameValidator::validate(QString &input, int &pos) const { diff --git a/tools/cabana/util.h b/tools/cabana/util.h index 74724dfb33..25dc245fe0 100644 --- a/tools/cabana/util.h +++ b/tools/cabana/util.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -135,5 +136,21 @@ private: void closeTabClicked(); }; +class UnixSignalHandler : public QObject { + Q_OBJECT + +public: + UnixSignalHandler(QObject *parent = nullptr); + ~UnixSignalHandler(); + static void signalHandler(int s); + +public slots: + void handleSigTerm(); + +private: + inline static int sig_fd[2] = {}; + QSocketNotifier *sn; +}; + int num_decimals(double num); QString signalToolTip(const cabana::Signal *sig);