SignalManager.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include "sys/socket.h"
  2. #include "unistd.h"
  3. #include "signal.h"
  4. #include "QsLog.h"
  5. #include "SignalManager.h"
  6. #include "settings/SettingsComponent.h"
  7. int SignalManager::g_sigtermFd[2];
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////
  9. SignalManager::SignalManager(QGuiApplication* app) : QObject(nullptr), m_app(app)
  10. {
  11. if (setupHandlers())
  12. {
  13. QLOG_ERROR() << "Failed to install SignalDaemon handlers.";
  14. }
  15. QLOG_DEBUG() << "Signal handlers installed successfully.";
  16. if (socketpair(AF_UNIX, SOCK_STREAM, 0, SignalManager::g_sigtermFd))
  17. {
  18. QLOG_ERROR() << "Couldn't create TERM socketpair";
  19. }
  20. m_snTerm = new QSocketNotifier(SignalManager::g_sigtermFd[1], QSocketNotifier::Read, this);
  21. connect(m_snTerm, SIGNAL(activated(int)), this, SLOT(handleSignal()));
  22. }
  23. ///////////////////////////////////////////////////////////////////////////////////////////////////
  24. int SignalManager::setupHandlers()
  25. {
  26. struct sigaction term;
  27. term.sa_handler = SignalManager::signalHandler;
  28. sigemptyset(&term.sa_mask);
  29. term.sa_flags = SA_RESTART | SA_RESETHAND;
  30. if (sigaction(SIGHUP, &term, nullptr) < 0)
  31. return -1;
  32. if (sigaction(SIGTERM, &term, nullptr) < 0)
  33. return -2;
  34. term.sa_flags = SA_RESTART;
  35. if (sigaction(SIGUSR1, &term, nullptr) < 0)
  36. return -3;
  37. return 0;
  38. }
  39. ///////////////////////////////////////////////////////////////////////////////////////////////////
  40. void SignalManager::signalHandler(int signal_num)
  41. {
  42. unsigned char a = signal_num < 255 ? signal_num : 0;
  43. write(g_sigtermFd[0], &a, sizeof(a));
  44. }
  45. ///////////////////////////////////////////////////////////////////////////////////////////////////
  46. void SignalManager::handleSignal()
  47. {
  48. m_snTerm->setEnabled(false);
  49. unsigned char signalNumber = 0;
  50. read(g_sigtermFd[1], &signalNumber, sizeof(signalNumber));
  51. // do Qt stuff
  52. if (signalNumber == SIGUSR1)
  53. {
  54. QLOG_DEBUG() << "Received SIGUSR1, reloading config file";
  55. SettingsComponent::Get().load();
  56. }
  57. else
  58. {
  59. QLOG_DEBUG() << "Received signal, closing application";
  60. closeApplication();
  61. }
  62. m_snTerm->setEnabled(true);
  63. }
  64. ///////////////////////////////////////////////////////////////////////////////////////////////////
  65. void SignalManager::closeApplication()
  66. {
  67. if (m_app)
  68. m_app->quit();
  69. }