SELKIELogger  1.0.0
LoggerSignals.c
1 /*
2  * Copyright (C) 2023 Swansea University
3  *
4  * This file is part of the SELKIELogger suite of tools.
5  *
6  * SELKIELogger is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation, either version 3 of the License, or (at your option)
9  * any later version.
10  *
11  * SELKIELogger is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this SELKIELogger product.
18  * If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include <pthread.h>
22 
23 #include "Logger.h"
24 
25 #include "LoggerSignals.h"
26 
34 atomic_bool shutdownFlag = false;
35 
42 atomic_bool rotateNow = false;
43 
50 atomic_bool pauseLog = false;
51 
59 void signalShutdown(int signnum __attribute__((unused))) {
60  shutdownFlag = true;
61 }
62 
73 void signalRotate(int signnum __attribute__((unused))) {
74  rotateNow = true;
75 }
76 
87 void signalPause(int signnum __attribute__((unused))) {
88  pauseLog = true;
89 }
90 
100 void signalUnpause(int signnum __attribute__((unused))) {
101  pauseLog = false;
102 }
103 
108  sigset_t *hMask = signalHandlerMask();
109 
110  /*
111  * While handling pause, unpause and rotate signals, we still want to
112  * pay attention to shutdown requests. As it doesn't matter if multiple
113  * shutdown signals are received, we just clear the mask for SIGINT and
114  * SIGQUIT.
115  */
116  sigdelset(hMask, SIGINT);
117  sigdelset(hMask, SIGQUIT);
118 
119  const struct sigaction saShutdown = {
120  .sa_handler = signalShutdown, .sa_mask = *hMask, .sa_flags = SA_RESTART};
121  const struct sigaction saRotate = {
122  .sa_handler = signalRotate, .sa_mask = *hMask, .sa_flags = SA_RESTART};
123  const struct sigaction saPause = {
124  .sa_handler = signalPause, .sa_mask = *hMask, .sa_flags = SA_RESTART};
125  const struct sigaction saUnpause = {
126  .sa_handler = signalUnpause, .sa_mask = *hMask, .sa_flags = SA_RESTART};
127 
128  // As well as the "standard" signals, we use SIGRTMIN+n to make each handler
129  // available directly
130 
131  // Shutdown signalled on SIGINT and SIGQUIT (standard) and SIGRTMIN+1
132  sigaction(SIGINT, &saShutdown, NULL);
133  sigaction(SIGQUIT, &saShutdown, NULL);
134  sigaction(SIGRTMIN + 1, &saShutdown, NULL);
135 
136  // Log rotate on common signals (SIGUSR1, SIGHUP) and SIGRTMIN+2
137  sigaction(SIGUSR1, &saRotate, NULL);
138  sigaction(SIGHUP, &saRotate, NULL);
139  sigaction(SIGRTMIN + 2, &saRotate, NULL);
140 
141  /*
142  * There isn't really a standard pause/resume signals except SIGSTOP/CONT which
143  * the system handles (and is somewhat more forceful). We use SIGRTMIN+3 and +4
144  * for pause and unpause respectively
145  */
146  sigaction(SIGRTMIN + 3, &saPause, NULL);
147  sigaction(SIGRTMIN + 4, &saUnpause, NULL);
148 
149  free(hMask);
150 }
151 
164 sigset_t *signalHandlerMask() {
165  sigset_t *blocking = calloc(1, sizeof(sigset_t));
166 
168  sigemptyset(blocking);
169  sigaddset(blocking, SIGINT);
170  sigaddset(blocking, SIGQUIT);
171  sigaddset(blocking, SIGUSR1);
172  sigaddset(blocking, SIGHUP);
173  sigaddset(blocking, SIGRTMIN + 1);
174  sigaddset(blocking, SIGRTMIN + 2);
175  sigaddset(blocking, SIGRTMIN + 3);
176  sigaddset(blocking, SIGRTMIN + 4);
177  return blocking;
178 }
179 
181  sigset_t *hMask = signalHandlerMask();
182  pthread_sigmask(SIG_BLOCK, hMask, NULL);
183  free(hMask);
184 }
185 
187  sigset_t *hMask = signalHandlerMask();
188  pthread_sigmask(SIG_UNBLOCK, hMask, NULL);
189  free(hMask);
190 }
void signalHandlersUnblock(void)
Unblock signals that we have handlers for.
sigset_t * signalHandlerMask(void)
Return a signal mask with suitable defaults.
void signalHandlersInstall(void)
Install signal handlers.
void signalHandlersBlock(void)
Block signals that we have handlers for.
void signalShutdown(int signnum)
Set safe shutdown flag.
Definition: LoggerSignals.c:59
void signalRotate(int signnum)
Set log rotate flag.
Definition: LoggerSignals.c:73
void signalPause(int signnum)
Set logger pause flag.
Definition: LoggerSignals.c:87
atomic_bool pauseLog
Pause logging.
Definition: LoggerSignals.c:50
atomic_bool rotateNow
Trigger immediate log rotation.
Definition: LoggerSignals.c:42
void signalUnpause(int signnum)
Clear logger pause flag.
atomic_bool shutdownFlag
Trigger clean software shutdown.
Definition: LoggerSignals.c:34