blob: 6bc7fcd17df18dcb87694641d61084f2d1ee17ce (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "signalhandler.h"
#include <cassert>
namespace vespalib {
std::vector<SignalHandler*> SignalHandler::_handlers;
namespace {
class Shutdown
{
public:
~Shutdown() {
SignalHandler::shutdown();
}
};
}
// Clear SignalHandler::_handlers in a slightly less unsafe manner.
Shutdown shutdown;
SignalHandler SignalHandler::HUP(SIGHUP);
SignalHandler SignalHandler::INT(SIGINT);
SignalHandler SignalHandler::TERM(SIGTERM);
SignalHandler SignalHandler::PIPE(SIGPIPE);
SignalHandler SignalHandler::SEGV(SIGSEGV);
SignalHandler SignalHandler::ABRT(SIGABRT);
SignalHandler SignalHandler::BUS(SIGBUS);
SignalHandler SignalHandler::ILL(SIGILL);
SignalHandler SignalHandler::TRAP(SIGTRAP);
SignalHandler SignalHandler::FPE(SIGFPE);
SignalHandler SignalHandler::QUIT(SIGQUIT);
SignalHandler SignalHandler::USR1(SIGUSR1);
void
SignalHandler::handleSignal(int signal)
{
if ((((size_t)signal) < _handlers.size()) && (_handlers[signal] != 0)) {
_handlers[signal]->gotSignal();
}
}
void
SignalHandler::gotSignal()
{
_gotSignal = 1;
}
SignalHandler::SignalHandler(int signal)
: _signal(signal),
_gotSignal(0)
{
assert(signal >= 0);
while (_handlers.size() < ((size_t)(signal + 1))) {
_handlers.push_back(0);
}
assert(_handlers[signal] == 0);
_handlers[signal] = this;
}
void
SignalHandler::hook()
{
struct sigaction act;
act.sa_handler = handleSignal;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(_signal, &act, nullptr);
}
void
SignalHandler::ignore()
{
struct sigaction act;
act.sa_handler = SIG_IGN;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(_signal, &act, nullptr);
}
bool
SignalHandler::check() const
{
return (_gotSignal != 0);
}
void
SignalHandler::clear()
{
_gotSignal = 0;
}
void
SignalHandler::unhook()
{
struct sigaction act;
act.sa_handler = SIG_DFL;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(_signal, &act, nullptr);
}
void
SignalHandler::shutdown()
{
for (std::vector<SignalHandler*>::iterator
it = _handlers.begin(), ite = _handlers.end();
it != ite;
++it) {
if (*it != nullptr)
(*it)->unhook();
}
std::vector<SignalHandler *>().swap(_handlers);
}
} // vespalib
|