lxcpp: Stopping container's init process
[platform/core/security/vasum.git] / common / utils / signal.cpp
index fdb571c..51c45b1 100644 (file)
 #include <cstring>
 #include <csignal>
 
-namespace vasum {
 namespace utils {
 
-void signalBlock(const int signalToBlock)
+namespace {
+
+void setSignalMask(int how, const ::sigset_t& set)
 {
+    int ret = ::pthread_sigmask(how, &set, nullptr /*&oldSet*/);
+    if(ret != 0) {
+        const std::string msg = "Error in pthread_sigmask: " + getSystemErrorMessage(ret);
+        LOGE(msg);
+        throw UtilsException(msg);
+    }
+}
+
+void changeSignal(int how, const int sigNum) {
     ::sigset_t set;
-    if (-1 == ::sigemptyset(&set)) {
-        LOGE("Error in sigemptyset: " << std::string(strerror(errno)));
-        throw UtilsException("Error in sigemptyset: " + std::string(strerror(errno)));
+    if(-1 == ::sigemptyset(&set)) {
+        const std::string msg = "Error in sigfillset: " + getSystemErrorMessage();
+        LOGE(msg);
+        throw UtilsException(msg);
     }
 
-    if (-1 ==::sigaddset(&set, signalToBlock)) {
-        LOGE("Error in sigaddset: " << std::string(strerror(errno)));
-        throw UtilsException("Error in sigaddset: " + std::string(strerror(errno)));
+    if(-1 ==::sigaddset(&set, sigNum)) {
+        const std::string msg = "Error in sigdelset: " + getSystemErrorMessage();
+        LOGE(msg);
+        throw UtilsException(msg);
     }
 
-    int ret = ::pthread_sigmask(SIG_BLOCK, &set, nullptr /*&oldSet*/);
-    if (ret != 0) {
-        LOGE("Error in pthread_sigmask: " << std::to_string(ret));
-        throw UtilsException("Error in pthread_sigmask: " + std::to_string(ret));
+    setSignalMask(how, set);
+}
+
+}// namespace
+
+::sigset_t getSignalMask()
+{
+    ::sigset_t set;
+    int ret = ::pthread_sigmask(0 /*ignored*/, nullptr /*get the oldset*/, &set);
+    if(ret != 0) {
+        const std::string msg = "Error in pthread_sigmask: " + getSystemErrorMessage(ret);
+        LOGE(msg);
+        throw UtilsException(msg);
+    }
+    return set;
+}
+
+bool isSignalBlocked(const int sigNum)
+{
+    ::sigset_t set = getSignalMask();
+
+    int ret = ::sigismember(&set, sigNum);
+    if(-1 == ret) {
+        const std::string msg = "Error in sigismember: " + getSystemErrorMessage();
+        LOGE(msg);
+        throw UtilsException(msg);
+    }
+
+    return ret == 1;
+}
+
+void signalBlock(const int sigNum)
+{
+    changeSignal(SIG_BLOCK, sigNum);
+}
+
+void signalBlockAllExcept(const std::initializer_list<int>& signals)
+{
+    ::sigset_t set;
+    if(-1 == ::sigfillset(&set)) {
+        const std::string msg = "Error in sigfillset: " + getSystemErrorMessage();
+        LOGE(msg);
+        throw UtilsException(msg);
+    }
+
+    for(const int s: signals) {
+        if(-1 == ::sigaddset(&set, s)) {
+            const std::string msg = "Error in sigaddset: " + getSystemErrorMessage();
+            LOGE(msg);
+            throw UtilsException(msg);
+        }
+    }
+    setSignalMask(SIG_BLOCK, set);
+}
+
+void signalUnblock(const int sigNum)
+{
+    changeSignal(SIG_UNBLOCK, sigNum);
+}
+
+void signalIgnore(const std::initializer_list<int>& signals)
+{
+    struct ::sigaction act;
+    act.sa_handler = SIG_IGN;
+
+    for(const int s: signals) {
+        if(-1 == ::sigaction(s, &act, nullptr)) {
+            const std::string msg = "Error in sigaction: " + getSystemErrorMessage();
+            LOGE(msg);
+            throw UtilsException(msg);
+        }
+    }
+}
+
+void sendSignal(const pid_t pid, const int sigNum)
+{
+    if (-1 == ::kill(pid, sigNum)) {
+        const std::string msg = "Error during killing pid: " + std::to_string(pid) +
+                                " sigNum: " + std::to_string(sigNum) +
+                                ": "  + getSystemErrorMessage();
+        LOGE(msg);
+        throw UtilsException(msg);
     }
 }
 
 } // namespace utils
-} // namespace vasum