For now only SIGTERM is processed to kindly stop the service.
Change-Id: If754002a8af9f8ca70323f22b06fbd22da0ddb19
${COMMON_PATH}/protocol/ProtocolSignal.cpp
${COMMON_PATH}/request/CheckRequest.cpp
${COMMON_PATH}/request/RequestTaker.cpp
+ ${COMMON_PATH}/request/SignalRequest.cpp
${COMMON_PATH}/response/CheckResponse.cpp
${COMMON_PATH}/response/ResponseTaker.cpp
${COMMON_PATH}/sockets/Socket.cpp
/*
* @file ProtocolSignal.cpp
* @author Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @author Adam Malinowski <a.malinowsk2@partner.samsung.com>
* @version 1.0
* @brief This file implements protocol class for signals
*/
-#include <common.h>
#include <memory>
+#include <sys/signalfd.h>
+
+#include <common.h>
+#include <exceptions/NotImplementedException.h>
+#include <request/SignalRequest.h>
+
#include "ProtocolSignal.h"
namespace Cynara {
ProtocolSignal::~ProtocolSignal() {
}
+void ProtocolSignal::execute(RequestContextPtr context UNUSED, SignalRequestPtr request UNUSED) {
+ throw NotImplementedException();
+}
+
ProtocolPtr ProtocolSignal::clone(void) {
return std::make_shared<ProtocolSignal>();
}
RequestPtr ProtocolSignal::extractRequestFromBuffer(BinaryQueue &bufferQueue) {
- TODO_USE_ME(bufferQueue);
- return RequestPtr(nullptr);
+ if (bufferQueue.size() >= sizeof(struct signalfd_siginfo)) {
+ struct signalfd_siginfo sigInfo;
+ bufferQueue.flattenConsume(&sigInfo, sizeof(sigInfo));
+ return std::make_shared<SignalRequest>(sigInfo);
+ }
+
+ return nullptr;
}
-ResponsePtr ProtocolSignal::extractResponseFromBuffer(BinaryQueue &bufferQueue) {
- TODO_USE_ME(bufferQueue);
- return ResponsePtr(nullptr);
+ResponsePtr ProtocolSignal::extractResponseFromBuffer(BinaryQueue &bufferQueue UNUSED) {
+ throw NotImplementedException();
}
} // namespace Cynara
#ifndef SRC_COMMON_PROTOCOL_PROTOCOLSIGNAL_H_
#define SRC_COMMON_PROTOCOL_PROTOCOLSIGNAL_H_
+#include <request/pointers.h>
+
#include "Protocol.h"
namespace Cynara {
virtual RequestPtr extractRequestFromBuffer(BinaryQueue &bufferQueue);
virtual ResponsePtr extractResponseFromBuffer(BinaryQueue &bufferQueue);
+
+ virtual void execute(RequestContextPtr context, SignalRequestPtr request);
};
} // namespace Cynara
#include <attributes/attributes.h>
#include <exceptions/NotImplementedException.h>
-#include <request/CheckRequest.h>
#include <request/RequestContext.h>
#include "RequestTaker.h"
throw NotImplementedException();
}
+void RequestTaker::execute(RequestContextPtr context UNUSED, SignalRequestPtr request UNUSED) {
+ throw NotImplementedException();
+}
+
} // namespace Cynara
virtual ~RequestTaker() = default;
virtual void execute(RequestContextPtr context, CheckRequestPtr request);
+ virtual void execute(RequestContextPtr context, SignalRequestPtr request);
};
} // namespace Cynara
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file SignalRequest.cpp
+ * @author Adam Malinowski <a.malinowsk2@partner.samsung.com>
+ * @version 1.0
+ * @brief This file implements signal request class
+ */
+
+#include <memory>
+
+#include "SignalRequest.h"
+
+namespace Cynara {
+
+void SignalRequest::execute(RequestPtr self, RequestTakerPtr taker,
+ RequestContextPtr context) const {
+ taker->execute(context, std::dynamic_pointer_cast<SignalRequest>(self));
+}
+
+} // namespace Cynara
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file SignalRequest.h
+ * @author Adam Malinowski <a.malinowsk2@partner.samsung.com>
+ * @version 1.0
+ * @brief This file defines signal request class
+ */
+
+#ifndef SRC_COMMON_REQUEST_SIGNALREQUEST_H_
+#define SRC_COMMON_REQUEST_SIGNALREQUEST_H_
+
+#include <sys/signalfd.h>
+
+#include <request/pointers.h>
+#include <request/Request.h>
+
+namespace Cynara {
+
+class SignalRequest : public Request {
+private:
+ struct signalfd_siginfo m_sigInfo;
+
+public:
+ SignalRequest(struct signalfd_siginfo sigInfo) : Request(0), m_sigInfo(sigInfo) {
+ }
+
+ virtual ~SignalRequest() = default;
+
+ virtual void execute(RequestPtr self, RequestTakerPtr taker, RequestContextPtr context) const;
+
+ uint32_t signalNumber(void) {
+ return m_sigInfo.ssi_signo;
+ }
+
+ struct signalfd_siginfo &sigInfo(void) {
+ return m_sigInfo;
+ }
+};
+
+} // namespace Cynara
+
+#endif /* SRC_COMMON_REQUEST_SIGNALREQUEST_H_ */
class RequestTaker;
typedef std::shared_ptr<RequestTaker> RequestTakerPtr;
+class SignalRequest;
+typedef std::shared_ptr<SignalRequest> SignalRequestPtr;
+
} // namespace Cynara
#endif /* SRC_COMMON_REQUEST_POINTERS_H_ */
#include <log/log.h>
#include <common.h>
#include <exceptions/PluginNotFoundException.h>
+#include <signal.h>
#include <main/Cynara.h>
#include <request/CheckRequest.h>
#include <request/RequestContext.h>
+#include <request/SignalRequest.h>
#include <response/CheckResponse.h>
#include <storage/Storage.h>
+#include <sockets/SocketManager.h>
+
#include "Logic.h"
namespace Cynara {
Logic::~Logic() {
}
+void Logic::execute(RequestContextPtr context UNUSED, SignalRequestPtr request) {
+ LOGD("Processing signal: [%d]", request->signalNumber());
+
+ switch (request->signalNumber()) {
+ case SIGTERM:
+ LOGI("SIGTERM received!");
+ m_socketManager->mainLoopStop();
+ break;
+ }
+}
+
void Logic::execute(RequestContextPtr context, CheckRequestPtr request) {
PolicyResult result(PredefinedPolicyType::DENY);
if (check(context, request->key(), result)) {
}
virtual void execute(RequestContextPtr context, CheckRequestPtr request);
+ virtual void execute(RequestContextPtr context, SignalRequestPtr request);
private:
StoragePtr m_storage;
/*
* @file SocketManager.cpp
* @author Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @author Adam Malinowski <a.malinowsk2@partner.samsung.com>
* @version 1.0
* @brief This file implements socket layer manager for cynara
*/
#include <errno.h>
#include <fcntl.h>
#include <memory>
+#include <signal.h>
#include <sys/select.h>
+#include <sys/signalfd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
createDomainSocket(std::make_shared<ProtocolClient>(), clientSocketPath, clientSocketUMask);
createDomainSocket(std::make_shared<ProtocolAdmin>(), adminSocketPath, adminSocketUMask);
- // todo create signal descriptor
+ createSignalSocket(std::make_shared<ProtocolSignal>());
LOGI("SocketManger init done");
}
return -1;
}
+void SocketManager::createSignalSocket(ProtocolPtr protocol) {
+ sigset_t mask;
+
+ // Maybe someone will find useful some kind of registering signals with callbacks
+ // but for now I'm making it as simple as possible.
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGTERM); // systemd terminates service sending this signal
+
+ if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
+ LOGE("sigprocmask failed: <%s>", strerror(errno));
+ return;
+ }
+
+ int fd = signalfd(-1, &mask, SFD_NONBLOCK);
+ if (fd < 0) {
+ LOGE("Creating signal file descriptor failed: <%s>", strerror(errno));
+ return;
+ }
+
+ auto &desc = createDescriptor(fd);
+ desc.setListen(false);
+ desc.setProtocol(protocol);
+ addReadSocket(fd);
+
+ LOGD("Signal socket: [%d] added.", fd);
+}
+
Descriptor &SocketManager::createDescriptor(int fd) {
if (fd > m_maxDesc) {
m_maxDesc = fd;
void createDomainSocket(ProtocolPtr protocol, const std::string &path, mode_t mask);
int createDomainSocketHelp(const std::string &path, mode_t mask);
int getSocketFromSystemD(const std::string &path);
+ void createSignalSocket(ProtocolPtr protocol);
Descriptor &createDescriptor(int fd);