| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the documentation of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:FDL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Free Documentation License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Free |
| ** Documentation License version 1.3 as published by the Free Software |
| ** Foundation and appearing in the file included in the packaging of |
| ** this file. Please review the following information to ensure |
| ** the GNU Free Documentation License version 1.3 requirements |
| ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \page unix-signals.html |
| \title Calling Qt Functions From Unix Signal Handlers |
| \brief You can't. But don't despair, there is a way... |
| |
| \ingroup best-practices |
| |
| You \e can't call Qt functions from Unix signal handlers. The |
| standard POSIX rule applies: You can only call async-signal-safe |
| functions from signal handlers. See \l |
| {http://www.opengroup.org/onlinepubs/000095399/functions/xsh_chap02_04.html#tag_02_04_01} |
| {Signal Actions} for the complete list of functions you can call |
| from Unix signal handlers. |
| |
| But don't despair, there is a way to use Unix signal handlers with |
| Qt. The strategy is to have your Unix signal handler do something |
| that will eventually cause a Qt signal to be emitted, and then you |
| simply return from your Unix signal handler. Back in your Qt |
| program, that Qt signal gets emitted and then received by your Qt |
| slot function, where you can safely do whatever Qt stuff you |
| weren't allowed to do in the Unix signal handler. |
| |
| One simple way to make this happen is to declare a socket pair in |
| your class for each Unix signal you want to handle. The socket |
| pairs are declared as static data members. You also create a |
| QSocketNotifier to monitor the \e read end of each socket pair, |
| declare your Unix signal handlers to be static class methods, and |
| declare a slot function corresponding to each of your Unix signal |
| handlers. In this example, we intend to handle both the SIGHUP and |
| SIGTERM signals. Note: You should read the socketpair(2) and the |
| sigaction(2) man pages before plowing through the following code |
| snippets. |
| |
| \snippet snippets/code/doc_src_unix-signal-handlers.cpp 0 |
| |
| In the MyDaemon constructor, use the socketpair(2) function to |
| initialize each file descriptor pair, and then create the |
| QSocketNotifier to monitor the \e read end of each pair. The |
| activated() signal of each QSocketNotifier is connected to the |
| appropriate slot function, which effectively converts the Unix |
| signal to the QSocketNotifier::activated() signal. |
| |
| \snippet snippets/code/doc_src_unix-signal-handlers.cpp 1 |
| |
| Somewhere else in your startup code, you install your Unix signal |
| handlers with sigaction(2). |
| |
| \snippet snippets/code/doc_src_unix-signal-handlers.cpp 2 |
| |
| In your Unix signal handlers, you write a byte to the \e write end |
| of a socket pair and return. This will cause the corresponding |
| QSocketNotifier to emit its activated() signal, which will in turn |
| cause the appropriate Qt slot function to run. |
| |
| \snippet snippets/code/doc_src_unix-signal-handlers.cpp 3 |
| |
| In the slot functions connected to the |
| QSocketNotifier::activated() signals, you \e read the byte. Now |
| you are safely back in Qt with your signal, and you can do all the |
| Qt stuff you weren'tr allowed to do in the Unix signal handler. |
| |
| \snippet snippets/code/doc_src_unix-signal-handlers.cpp 4 |
| */ |