2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
42#include "utils/Daemon.h"
44#ifndef DOXYGEN_SHOULD_SKIP_THIS
46#include "core/system/poll.h"
55#include <sys/syscall.h>
62 : std::runtime_error(failureMessage) {
75 void Daemon::
startDaemon(
const std::string& pidFileName,
const std::string& userName,
const std::string& groupName) {
76 if (std::filesystem::exists(pidFileName)) {
77 throw DaemonFailure("Pid file '" + pidFileName +
"' exists. Daemon already running?");
97 if (signal(SIGHUP, SIG_IGN) == SIG_ERR) {
110 std::ofstream pidFile(pidFileName, std::ofstream::out);
112 if (!pidFile.good()) {
116 pidFile << pid << std::endl;
122 struct passwd* pw =
nullptr;
123 struct group* gr =
nullptr;
125 if (((
void) (errno = 0), gr = getgrnam(groupName.c_str())) ==
nullptr) {
131 if (setegid(gr->gr_gid) != 0) {
134 if (((
void) (errno = 0), (pw = getpwnam(userName.c_str())) ==
nullptr)) {
140 if (seteuid(pw->pw_uid) != 0) {
147 close(STDOUT_FILENO);
148 close(STDERR_FILENO);
150 if (std::freopen(
"/dev/null",
"r", stdin) ==
nullptr) {
152 if (std::freopen(
"/dev/null",
"w+", stdout) ==
nullptr) {
154 if (std::freopen(
"/dev/null",
"w+", stderr) ==
nullptr) {
159 if (pidFileName.empty()) {
162 std::ifstream pidFile(pidFileName, std::ifstream::in);
164 if (!pidFile.good()) {
172 const int pidfd =
static_cast<
int>(syscall(SYS_pidfd_open, pid, 0));
178 if (kill(pid, SIGTERM) != 0) {
181 struct pollfd pollfd{};
183 pollfd.events = POLLIN;
185 const int ready = core::system::poll(&pollfd, 1, 5000);
201 (
void) seteuid(getuid());
202 (
void) setegid(getgid());
203 std::filesystem::remove(pidFileName);
207 : std::runtime_error(message)
DaemonError(const std::string &errorMessage)
~DaemonFailure() override
DaemonFailure(const std::string &failureMessage)
~DaemonSignaled() override
DaemonSignaled(const std::string &message, pid_t pid)
static void startDaemon(const std::string &pidFileName, const std::string &userName, const std::string &groupName)
static pid_t stopDaemon(const std::string &pidFileName)
static void erasePidFile(const std::string &pidFileName)