Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "daemon.h"
00012
00013 #include <sys/types.h>
00014 #include <sys/stat.h>
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <fcntl.h>
00018 #include <errno.h>
00019 #include <unistd.h>
00020 #include <syslog.h>
00021 #include <string.h>
00022
00023 #include <mutex>
00024 #include <condition_variable>
00025 #include <iostream>
00026 #include <signal.h>
00027
00028 namespace
00029 {
00030
00031 OpcUa::Daemon* DaemonInstance = 0;
00032
00033 void TerminateSignal(int signum)
00034 {
00035 std::cout << "terminating.." << std::endl;
00036 if (DaemonInstance)
00037 {
00038 DaemonInstance->Terminate();
00039 DaemonInstance = nullptr;
00040 }
00041 }
00042
00043 }
00044
00045 namespace OpcUa
00046 {
00047 void Daemon::SetTerminateHandlers()
00048 {
00049 if (signal(SIGTERM, TerminateSignal) == SIG_ERR)
00050 {
00051 std::cerr << "unable to set SIGTERM handler" << std::endl;
00052 }
00053 if (signal(SIGINT, TerminateSignal) == SIG_ERR)
00054 {
00055 std::cerr << "unable to set SIGINT handler" << std::endl;
00056 }
00057 if (signal(SIGSTOP, TerminateSignal) == SIG_ERR)
00058 {
00059 std::cerr << "unable to set SIGSTOP handler" << std::endl;
00060 }
00061 DaemonInstance = this;
00062 }
00063
00064 void Daemon::Daemonize(const std::string& logFile)
00065 {
00066 pid_t pid, sid;
00067
00068 pid = fork();
00069 if (pid < 0)
00070 {
00071 std::cerr << "Failed to fork: " << strerror(errno) << std::endl;
00072 exit(EXIT_FAILURE);
00073 }
00074 if (pid > 0)
00075 {
00076 exit(EXIT_SUCCESS);
00077 }
00078
00079 umask(0);
00080
00081 sid = setsid();
00082 if (sid < 0)
00083 {
00084 std::cerr << "setsid() failed: " << strerror(errno) << std::endl;
00085 exit(EXIT_FAILURE);
00086 }
00087
00088 if ((chdir("/")) < 0)
00089 {
00090 std::cerr << "Cannot change dir. " << strerror(errno) << std::endl;
00091 exit(EXIT_FAILURE);
00092 }
00093
00094 if (!logFile.empty())
00095 {
00096 FILE* tmp = fopen(logFile.c_str(), "w");
00097 if (!tmp)
00098 {
00099 std::cerr << "Cannot open log file " << logFile << ". " << strerror(errno) << std::endl;
00100 exit(EXIT_FAILURE);
00101 }
00102
00103 close(STDIN_FILENO);
00104 close(STDOUT_FILENO);
00105 close(STDERR_FILENO);
00106
00107 dup2(fileno(tmp), STDOUT_FILENO);
00108 dup2(fileno(tmp), STDERR_FILENO);
00109 }
00110 }
00111 }