i2pd/DaemonLinux.cpp

120 lines
2.4 KiB
C++
Raw Normal View History

2014-04-20 05:54:34 +04:00
#include "Daemon.h"
#ifndef _WIN32
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
2014-04-23 02:37:24 +04:00
#include <fcntl.h>
#include <sys/stat.h>
2014-04-20 05:54:34 +04:00
2014-04-23 02:37:24 +04:00
#include "Log.h"
2014-04-22 08:15:07 +04:00
#include "util.h"
2014-04-20 05:54:34 +04:00
void handle_signal(int sig)
{
switch (sig)
{
case SIGHUP:
if (i2p::util::config::GetArg("daemon", 0) == 1)
{
static bool first=true;
if (first)
{
first=false;
return;
}
}
2015-12-18 15:25:48 +03:00
LogPrint(eLogInfo, "Daemon: Got SIGHUP, reloading config.");
2014-04-20 05:54:34 +04:00
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
break;
case SIGABRT:
case SIGTERM:
case SIGINT:
2014-04-22 08:15:07 +04:00
Daemon.running = 0; // Exit loop
2014-04-20 05:54:34 +04:00
break;
}
}
namespace i2p
{
namespace util
{
bool DaemonLinux::start()
{
if (isDaemon == 1)
{
pid_t pid;
pid = fork();
2014-07-02 21:48:45 +04:00
if (pid > 0) // parent
::exit (EXIT_SUCCESS);
2014-04-20 05:54:34 +04:00
2014-07-02 21:48:45 +04:00
if (pid < 0) // error
return false;
// child
2014-04-20 05:54:34 +04:00
umask(0);
int sid = setsid();
if (sid < 0)
{
2015-12-18 15:25:48 +03:00
LogPrint(eLogError, "Daemon: could not create process group.");
2014-07-02 21:48:45 +04:00
return false;
2014-04-20 05:54:34 +04:00
}
2015-06-19 23:06:14 +03:00
std::string d(i2p::util::filesystem::GetDataDir().string ()); // make a copy
chdir(d.c_str());
2014-07-02 21:48:45 +04:00
// close stdin/stdout/stderr descriptors
::close (0);
::open ("/dev/null", O_RDWR);
::close (1);
::open ("/dev/null", O_RDWR);
::close (2);
::open ("/dev/null", O_RDWR);
2014-04-20 05:54:34 +04:00
}
// Pidfile
2014-10-17 17:55:41 +04:00
pidfile = IsService () ? "/var/run" : i2p::util::filesystem::GetDataDir().string();
2014-04-20 05:54:34 +04:00
pidfile.append("/i2pd.pid");
2014-04-22 08:15:07 +04:00
pidFilehandle = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600);
2014-04-20 05:54:34 +04:00
if (pidFilehandle == -1)
{
2015-12-18 15:25:48 +03:00
LogPrint(eLogError, "Daemon: could not create pid file ", pidfile, ": ", strerror(errno));
2014-07-02 21:48:45 +04:00
return false;
2014-04-20 05:54:34 +04:00
}
if (lockf(pidFilehandle, F_TLOCK, 0) == -1)
{
2015-12-18 15:25:48 +03:00
LogPrint(eLogError, "Daemon: could not lock pid file ", pidfile, ": ", strerror(errno));
2014-07-02 21:48:45 +04:00
return false;
2014-04-20 05:54:34 +04:00
}
char pid[10];
sprintf(pid, "%d\n", getpid());
write(pidFilehandle, pid, strlen(pid));
// Signal handler
struct sigaction sa;
sa.sa_handler = handle_signal;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGHUP, &sa, 0);
sigaction(SIGABRT, &sa, 0);
sigaction(SIGTERM, &sa, 0);
sigaction(SIGINT, &sa, 0);
2014-04-22 08:15:07 +04:00
return Daemon_Singleton::start();
2014-04-20 05:54:34 +04:00
}
bool DaemonLinux::stop()
{
close(pidFilehandle);
unlink(pidfile.c_str());
2014-07-02 21:48:45 +04:00
return Daemon_Singleton::stop();
2014-04-20 05:54:34 +04:00
}
}
}
2014-04-22 08:15:07 +04:00
#endif