lxcpp: Stopping container's init process
[platform/core/security/vasum.git] / common / utils / signal.cpp
1 /*
2  *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Jan Olszak <j.olszak@samsung.com>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18
19 /**
20  * @file
21  * @author  Jan Olszak (j.olszak@samsung.com)
22  * @brief   Signal related functions
23  */
24
25 #include "utils/signal.hpp"
26 #include "utils/exception.hpp"
27 #include "logger/logger.hpp"
28
29 #include <string>
30 #include <cerrno>
31 #include <cstring>
32 #include <csignal>
33
34 namespace utils {
35
36 namespace {
37
38 void setSignalMask(int how, const ::sigset_t& set)
39 {
40     int ret = ::pthread_sigmask(how, &set, nullptr /*&oldSet*/);
41     if(ret != 0) {
42         const std::string msg = "Error in pthread_sigmask: " + getSystemErrorMessage(ret);
43         LOGE(msg);
44         throw UtilsException(msg);
45     }
46 }
47
48 void changeSignal(int how, const int sigNum) {
49     ::sigset_t set;
50     if(-1 == ::sigemptyset(&set)) {
51         const std::string msg = "Error in sigfillset: " + getSystemErrorMessage();
52         LOGE(msg);
53         throw UtilsException(msg);
54     }
55
56     if(-1 ==::sigaddset(&set, sigNum)) {
57         const std::string msg = "Error in sigdelset: " + getSystemErrorMessage();
58         LOGE(msg);
59         throw UtilsException(msg);
60     }
61
62     setSignalMask(how, set);
63 }
64
65 }// namespace
66
67 ::sigset_t getSignalMask()
68 {
69     ::sigset_t set;
70     int ret = ::pthread_sigmask(0 /*ignored*/, nullptr /*get the oldset*/, &set);
71     if(ret != 0) {
72         const std::string msg = "Error in pthread_sigmask: " + getSystemErrorMessage(ret);
73         LOGE(msg);
74         throw UtilsException(msg);
75     }
76     return set;
77 }
78
79 bool isSignalBlocked(const int sigNum)
80 {
81     ::sigset_t set = getSignalMask();
82
83     int ret = ::sigismember(&set, sigNum);
84     if(-1 == ret) {
85         const std::string msg = "Error in sigismember: " + getSystemErrorMessage();
86         LOGE(msg);
87         throw UtilsException(msg);
88     }
89
90     return ret == 1;
91 }
92
93 void signalBlock(const int sigNum)
94 {
95     changeSignal(SIG_BLOCK, sigNum);
96 }
97
98 void signalBlockAllExcept(const std::initializer_list<int>& signals)
99 {
100     ::sigset_t set;
101     if(-1 == ::sigfillset(&set)) {
102         const std::string msg = "Error in sigfillset: " + getSystemErrorMessage();
103         LOGE(msg);
104         throw UtilsException(msg);
105     }
106
107     for(const int s: signals) {
108         if(-1 == ::sigaddset(&set, s)) {
109             const std::string msg = "Error in sigaddset: " + getSystemErrorMessage();
110             LOGE(msg);
111             throw UtilsException(msg);
112         }
113     }
114     setSignalMask(SIG_BLOCK, set);
115 }
116
117 void signalUnblock(const int sigNum)
118 {
119     changeSignal(SIG_UNBLOCK, sigNum);
120 }
121
122 void signalIgnore(const std::initializer_list<int>& signals)
123 {
124     struct ::sigaction act;
125     act.sa_handler = SIG_IGN;
126
127     for(const int s: signals) {
128         if(-1 == ::sigaction(s, &act, nullptr)) {
129             const std::string msg = "Error in sigaction: " + getSystemErrorMessage();
130             LOGE(msg);
131             throw UtilsException(msg);
132         }
133     }
134 }
135
136 void sendSignal(const pid_t pid, const int sigNum)
137 {
138     if (-1 == ::kill(pid, sigNum)) {
139         const std::string msg = "Error during killing pid: " + std::to_string(pid) +
140                                 " sigNum: " + std::to_string(sigNum) +
141                                 ": "  + getSystemErrorMessage();
142         LOGE(msg);
143         throw UtilsException(msg);
144     }
145 }
146
147 } // namespace utils
148
149
150
151
152