2014-04-20 01:54:34 +00:00
|
|
|
#include "Daemon.h"
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
|
|
|
|
|
|
|
#include <signal.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
2014-04-22 22:37:24 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/stat.h>
|
2014-04-20 01:54:34 +00:00
|
|
|
|
2014-04-22 22:37:24 +00:00
|
|
|
#include "Log.h"
|
2014-04-22 04:15:07 +00:00
|
|
|
#include "util.h"
|
|
|
|
|
|
|
|
|
2014-04-20 01:54:34 +00: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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
LogPrint("Reloading config.");
|
|
|
|
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
|
|
|
|
break;
|
|
|
|
case SIGABRT:
|
|
|
|
case SIGTERM:
|
|
|
|
case SIGINT:
|
2014-04-22 04:15:07 +00:00
|
|
|
Daemon.running = 0; // Exit loop
|
2014-04-20 01:54:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
namespace i2p
|
|
|
|
{
|
|
|
|
namespace util
|
|
|
|
{
|
|
|
|
bool DaemonLinux::start()
|
|
|
|
{
|
|
|
|
if (isDaemon == 1)
|
|
|
|
{
|
|
|
|
pid_t pid;
|
|
|
|
pid = fork();
|
2014-07-02 17:48:45 +00:00
|
|
|
if (pid > 0) // parent
|
|
|
|
::exit (EXIT_SUCCESS);
|
2014-04-20 01:54:34 +00:00
|
|
|
|
2014-07-02 17:48:45 +00:00
|
|
|
if (pid < 0) // error
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// child
|
2014-04-20 01:54:34 +00:00
|
|
|
umask(0);
|
|
|
|
int sid = setsid();
|
|
|
|
if (sid < 0)
|
|
|
|
{
|
|
|
|
LogPrint("Error, could not create process group.");
|
2014-07-02 17:48:45 +00:00
|
|
|
return false;
|
2014-04-20 01:54:34 +00:00
|
|
|
}
|
2015-06-19 20:06:14 +00:00
|
|
|
std::string d(i2p::util::filesystem::GetDataDir().string ()); // make a copy
|
2015-06-19 19:44:50 +00:00
|
|
|
chdir(d.c_str());
|
2014-07-02 17:48:45 +00: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 01:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Pidfile
|
2014-10-17 13:55:41 +00:00
|
|
|
pidfile = IsService () ? "/var/run" : i2p::util::filesystem::GetDataDir().string();
|
2014-04-20 01:54:34 +00:00
|
|
|
pidfile.append("/i2pd.pid");
|
2014-04-22 04:15:07 +00:00
|
|
|
pidFilehandle = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600);
|
2014-04-20 01:54:34 +00:00
|
|
|
if (pidFilehandle == -1)
|
|
|
|
{
|
|
|
|
LogPrint("Error, could not create pid file (", pidfile, ")\nIs an instance already running?");
|
2014-07-02 17:48:45 +00:00
|
|
|
return false;
|
2014-04-20 01:54:34 +00:00
|
|
|
}
|
|
|
|
if (lockf(pidFilehandle, F_TLOCK, 0) == -1)
|
|
|
|
{
|
|
|
|
LogPrint("Error, could not lock pid file (", pidfile, ")\nIs an instance already running?");
|
2014-07-02 17:48:45 +00:00
|
|
|
return false;
|
2014-04-20 01:54:34 +00: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 04:15:07 +00:00
|
|
|
return Daemon_Singleton::start();
|
2014-04-20 01:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool DaemonLinux::stop()
|
|
|
|
{
|
|
|
|
close(pidFilehandle);
|
|
|
|
unlink(pidfile.c_str());
|
|
|
|
|
2014-07-02 17:48:45 +00:00
|
|
|
return Daemon_Singleton::stop();
|
2014-04-20 01:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-22 04:15:07 +00:00
|
|
|
#endif
|