Skip to content

Commit

Permalink
feat: Catch SIGINT and SIGTERM
Browse files Browse the repository at this point in the history
Need tests on windows

related issue: #178
  • Loading branch information
neko-para authored and ouuan committed Apr 29, 2020
1 parent f612879 commit 3c76cd3
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ add_executable(cpeditor
src/appwindow.hpp
src/mainwindow.cpp
src/mainwindow.hpp
src/signal.cpp
src/signal.hpp

src/Util.cpp
src/Util.hpp
Expand Down
10 changes: 7 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "Core/EventLogger.hpp"
#include "appwindow.hpp"
#include "mainwindow.hpp"
#include "signal.hpp"
#include <QApplication>
#include <QCommandLineParser>
#include <QJsonArray>
Expand Down Expand Up @@ -134,9 +135,10 @@ int main(int argc, char *argv[])
LOG_INFO("Launching the new Appwindow with args: " << BOOL_INFO_OF(cpp) << BOOL_INFO_OF(java)
<< BOOL_INFO_OF(python) << BOOL_INFO_OF(noHotExit)
<< INFO_OF(number) << INFO_OF(path));

Daemon d;
Daemon::setup();
AppWindow w(cpp, java, python, noHotExit, number, path);
LOG_INFO("Launched window connecting this window to onReceiveMessage()");
QObject::connect(&d, &Daemon::signalActivated, &w, &AppWindow::close);
QObject::connect(&app, &SingleApplication::receivedMessage, &w, &AppWindow::onReceivedMessage);
LOG_INFO("Showing the application window and beginning the event loop");
w.show();
Expand Down Expand Up @@ -187,8 +189,10 @@ int main(int argc, char *argv[])
<< BOOL_INFO_OF(python) << BOOL_INFO_OF(noHotExit)
<< INFO_OF(args.join(", ")));

Daemon d;
Daemon::setup();
AppWindow w(depth, cpp, java, python, noHotExit, args);
LOG_INFO("Launched window connecting this window to onReceiveMessage()");
QObject::connect(&d, &Daemon::signalActivated, &w, &AppWindow::close);
QObject::connect(&app, &SingleApplication::receivedMessage, &w, &AppWindow::onReceivedMessage);
LOG_INFO("Showing the application window and beginning the event loop");

Expand Down
107 changes: 107 additions & 0 deletions src/signal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright (C) 2019-2020 Ashar Khan <ashar786khan@gmail.com>
*
* This file is part of CP Editor.
*
* CP Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* I will not be responsible if CP Editor behaves in unexpected way and
* causes your ratings to go down and or lose any important contest.
*
* Believe Software is "Software" and it isn't immune to bugs.
*
*/

#include "signal.hpp"

#ifdef Q_OS_WIN32

#include <Windows.h>

#else

#include <signal.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#endif

#ifdef Q_OS_WIN32

static Daemon *daemon;

BOOL WINAPI HandlerRoutine(DWORD type)
{
switch (type)
{
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
if (daemon)
daemon->handleSignal();
return TRUE;
default:
return FALSE;
}
}

#else
int sigFd[2];

void signalHandler(int)
{
char a = 1;
::write(sigFd[0], &a, sizeof(a));
}
#endif

Daemon::Daemon(QObject *parent) : QObject(parent)
{
#ifdef Q_OS_WIN32
daemon = this;
#else
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigFd))
qFatal("Couldn't create socketpair");

notifier = new QSocketNotifier(sigFd[1], QSocketNotifier::Read, this);
connect(notifier, SIGNAL(activated(int)), this, SLOT(handleSignal()));
#endif
}

Daemon::~Daemon()
{
delete notifier;
}

void Daemon::setup()
{
#ifdef Q_OS_WIN32
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
#else
struct sigaction act;

act.sa_handler = signalHandler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_flags |= SA_RESTART;

sigaction(SIGINT, &act, 0);
sigaction(SIGTERM, &act, 0);
#endif
}

void Daemon::handleSignal()
{
#ifndef Q_OS_WIN32
notifier->setEnabled(false);
char tmp;
::read(sigFd[1], &tmp, sizeof(tmp));
#endif
emit signalActivated();
#ifndef Q_OS_WIN32
notifier->setEnabled(true);
#endif
}
44 changes: 44 additions & 0 deletions src/signal.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2019-2020 Ashar Khan <ashar786khan@gmail.com>
*
* This file is part of CP Editor.
*
* CP Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* I will not be responsible if CP Editor behaves in unexpected way and
* causes your ratings to go down and or lose any important contest.
*
* Believe Software is "Software" and it isn't immune to bugs.
*
*/

#ifndef SIGNAL_HPP
#define SIGNAL_HPP

#include <QSocketNotifier>

class Daemon : public QObject
{
Q_OBJECT

public:
Daemon(QObject *parent = nullptr);
~Daemon();

static void setup();

signals:
void signalActivated();

public slots:
// Qt signal handlers.
void handleSignal();

private:
QSocketNotifier *notifier;
};

#endif // SIGNAL_HPP

0 comments on commit 3c76cd3

Please sign in to comment.