Skip to content
Permalink
Browse files

Add external qt-unix-signals library

This library, original taken from https://github.com/sijk/qt-unix-signals
(but a maintained fork exists at https://github.com/nyalldawson/qt-unix-signals),
handles unix signal watching using the Qt libraries.

It allows for detection of signals like SIGINT and SIGTERM,
and allows Qt applications to respond gracefully to these.

Included in external libraries for use in QGIS terminal
applications.
  • Loading branch information
nyalldawson committed Feb 28, 2019
1 parent a33bf30 commit 620db06324cc33dd424da537f0bfd633a2937ab0
@@ -0,0 +1,42 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)

project(QTSignals)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

SET(QTSignal_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "QTSignal Include Dir")

find_package(Qt5Core REQUIRED)

if (Qt5_POSITION_INDEPENDENT_CODE)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif(Qt5_POSITION_INDEPENDENT_CODE)

SET(CMAKE_CXX_STANDARD 11)

option(CMAKE_ENABLE "Enable automatic path configuration" ON)


# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)


include_directories(
${Qt5Core_INCLUDE_DIRS})
add_library(QTSignal SHARED
sigwatch.cpp
)
target_link_libraries (QTSignal
${Qt5Core_LIBRARIES}
)

#option(WITH_EXAMPLE "Build example executable" ON)
#if (WITH_EXAMPLE)
# add_executable (sigwatch-demo example.cpp )
# target_link_libraries (sigwatch-demo
# QTSignal
# )
#endif(WITH_EXAMPLE)
@@ -0,0 +1,22 @@
Unix signal watcher for Qt.

Copyright (C) 2014 Simon Knopp

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@@ -0,0 +1,98 @@
Unix Signal Watcher For Qt
==========================

Author: Simon Knopp
Licence: [MIT](http://opensource.org/licenses/MIT)


## Summary

When writing a Qt application, as with any application, it is sometimes useful
to handle Unix signals. Of course, Qt already incorporates the notion of
signals, so it would be nice if Unix signals could be mapped to Qt signals. Then
we could write handlers for Unix signals and connect them up in the same way as
normal Qt slots.

The class described below does just this. It is heavily based on [this
example](http://qt-project.org/doc/qt-5.0/qtdoc/unix-signals.html) in the Qt
documentation, but it encapsulates that functionality in a generic re-usable
class.

## Interface

The interface is simple: you call `watchForSignal()` with the signals you're
interested in, and `connect()` your handlers to `SIGNAL(unixSignal(int))`.

``` c++
class UnixSignalWatcher : public QObject
{
Q_OBJECT
public:
explicit UnixSignalWatcher(QObject *parent = 0);
~UnixSignalWatcher();
void watchForSignal(int signal);
signals:
void unixSignal(int signal);
};
```
## Example usage
Let's look at an example program.
``` c++
#include <QCoreApplication>
#include <QDebug>
#include "sigwatch.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
qDebug() << "Hello from process" << QCoreApplication::applicationPid();
UnixSignalWatcher sigwatch;
sigwatch.watchForSignal(SIGINT);
sigwatch.watchForSignal(SIGTERM);
QObject::connect(&sigwatch, SIGNAL(unixSignal(int)), &app, SLOT(quit()));
int exitcode = app.exec();
qDebug() << "Goodbye";
return exitcode;
}
```
This simply registers signal handlers for `SIGINT` and `SIGTERM` and then idles
forever. If you run it (`qmake && make && ./sigwatch-demo`) you'll see a
greeting and the pid of the process:
Hello from process 6811
Press `^C` to send `SIGINT`. The `UnixSignalWatcher` will handle the signal,
which in turn is connected to `QCoreApplication::quit()`, so the event loop
exits and the farewell message is printed.
^CCaught signal: Interrupt
Goodbye
Similarly, you could use `kill` to send `SIGTERM`.
$ ./sigwatch-demo &
Hello from process 6848
$ kill 6848
Caught signal: Terminated
Goodbye
If you send a signal that does not have a handler, though, you won't see the
farewell message. For instance:
$ ./sigwatch-demo
Hello from process 6906
$ kill -SIGABRT 6906
Aborted (core dumped)
## Compatibility
Tested with Qt 4.6 and 5.2 on Linux.
@@ -0,0 +1,19 @@
#include <QCoreApplication>
#include <QDebug>
#include "sigwatch.h"

int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
qDebug() << "Hello from process" << QCoreApplication::applicationPid();

UnixSignalWatcher sigwatch;
sigwatch.watchForSignal(SIGINT);
sigwatch.watchForSignal(SIGTERM);
QObject::connect(&sigwatch, SIGNAL(unixSignal(int)), &app, SLOT(quit()));

int exitcode = app.exec();
qDebug() << "Goodbye";
return exitcode;
}

@@ -0,0 +1,42 @@

#ifndef QTSIGNAL_EXPORT_H
#define QTSIGNAL_EXPORT_H

#ifdef QTSIGNAL_STATIC_DEFINE
# define QTSIGNAL_EXPORT
# define QTSIGNAL_NO_EXPORT
#else
# ifndef QTSIGNAL_EXPORT
# ifdef QTSignal_EXPORTS
/* We are building this library */
# define QTSIGNAL_EXPORT __attribute__((visibility("default")))
# else
/* We are using this library */
# define QTSIGNAL_EXPORT __attribute__((visibility("default")))
# endif
# endif

# ifndef QTSIGNAL_NO_EXPORT
# define QTSIGNAL_NO_EXPORT __attribute__((visibility("hidden")))
# endif
#endif

#ifndef QTSIGNAL_DEPRECATED
# define QTSIGNAL_DEPRECATED __attribute__ ((__deprecated__))
#endif

#ifndef QTSIGNAL_DEPRECATED_EXPORT
# define QTSIGNAL_DEPRECATED_EXPORT QTSIGNAL_EXPORT QTSIGNAL_DEPRECATED
#endif

#ifndef QTSIGNAL_DEPRECATED_NO_EXPORT
# define QTSIGNAL_DEPRECATED_NO_EXPORT QTSIGNAL_NO_EXPORT QTSIGNAL_DEPRECATED
#endif

#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef QTSIGNAL_NO_DEPRECATED
# define QTSIGNAL_NO_DEPRECATED
# endif
#endif

#endif /* QTSIGNAL_EXPORT_H */

0 comments on commit 620db06

Please sign in to comment.
You can’t perform that action at this time.