1 /***************************************************************************
2  *  Copyright (C) 2015-2020 by Mihai Moldovan <ionic@ionic.de>             *
3  *                                                                         *
4  *  This program is free software; you can redistribute it and/or modify   *
5  *  it under the terms of the GNU General Public License as published by   *
6  *  the Free Software Foundation; either version 2 of the License, or      *
7  *  (at your option) any later version.                                    *
8  *                                                                         *
9  *  This program is distributed in the hope that it will be useful,        *
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
12  *  GNU General Public License for more details.                           *
13  *                                                                         *
14  *  You should have received a copy of the GNU General Public License      *
15  *  along with this program; if not, write to the                          *
16  *  Free Software Foundation, Inc.,                                        *
17  *  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
18  ***************************************************************************/
19 
20 
21 #ifndef UNIXHELPER_H
22 #define UNIXHELPER_H
23 
24 #include <QtCore/qglobal.h>
25 #include <unistd.h>
26 
27 #ifdef Q_OS_UNIX
28 
29 namespace unixhelper {
30   /*
31    * Unblocks all signals and installs a signal handler for SIGHUP,
32    * which calls kill_pgroup ().
33    *
34    * Should signal unblocking or installing the signal handler fail,
35    * an emergency exit is performed and
36    * the whole process group killed.
37    *
38    * The signals SIGINT, SIGTERM, SIGPIPE, SIGQUIT, SIGUSR1 and
39    * SIGUSR2 are ignored.
40    *
41    * Loops indefinitely afterwards.
42    *
43    * In this loop, the current parent PID is polled and compared against
44    * the original value passed via parameter parent.
45    * Should they mismatch, the parent died and kill_pgroup () is called.
46    */
47   int unix_cleanup (const pid_t parent);
48 
49   /*
50    * Wrapper for killing a whole process group.
51    * The "real" killing work is done by real_kill_pgroup ().
52    * This function tries to fork off another process and change
53    * the new function's process group ID.
54    * If any of these operations fail, killing the original process
55    * group ID will still continue, albeit with warning messages.
56    *
57    * signal may be any of:
58    *   * -1       to indicate an error leading to emergency termination
59    *   * SIGHUP   as the standard signal that is sent when the
60    *              group leader dies under specific circumstances
61    *              (we cannot rely that this always happens, though,
62    *               so a polling solution is needed, see unix_cleanup().)
63    * Other values are not handled.
64    */
65   void kill_pgroup (const int signal);
66 
67   /*
68    * Kills the whole process group.
69    * First, SIGTERM is sent to the group.
70    * A 10 seconds grace period is granted to make sure
71    * processes exit cleanly on their own.
72    * Lastly, SIGKILL is sent to the group -- which also
73    * implies the demise of this program.
74    *
75    * pgid is the process group ID to be killed.
76    */
77   void real_kill_pgroup (const pid_t pgid);
78 }
79 
80 #endif /* defined (Q_OS_UNIX) */
81 
82 #endif /* !defined (UNIXHELPER_H) */
83