mirror of
https://github.com/monero-project/monero.git
synced 2025-01-28 18:56:31 +02:00
Allow daemon to fork on posix systems
This commit is contained in:
parent
31394c78d0
commit
ce38a70023
@ -4,7 +4,10 @@ file(GLOB_RECURSE COMMON common/*)
|
||||
file(GLOB_RECURSE CRYPTO crypto/*)
|
||||
file(GLOB_RECURSE CRYPTONOTE_CORE cryptonote_core/*)
|
||||
file(GLOB_RECURSE CRYPTONOTE_PROTOCOL cryptonote_protocol/*)
|
||||
file(GLOB_RECURSE DAEMON daemon/*)
|
||||
file(GLOB_RECURSE DAEMON daemon/*.cpp)
|
||||
if(WIN32)
|
||||
list(REMOVE_ITEM DAEMON "daemon/posix_fork.cpp")
|
||||
endif()
|
||||
file(GLOB_RECURSE P2P p2p/*)
|
||||
file(GLOB_RECURSE RPC rpc/*)
|
||||
file(GLOB_RECURSE SIMPLEWALLET simplewallet/*)
|
||||
|
@ -23,9 +23,9 @@ using namespace epee;
|
||||
#include "rpc/core_rpc_server.h"
|
||||
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
|
||||
|
||||
//#ifndef WIN32
|
||||
//#include "posix_daemonize.h"
|
||||
//#endif
|
||||
#ifndef WIN32
|
||||
#include "posix_fork.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <crtdbg.h>
|
||||
@ -166,8 +166,8 @@ int main(int argc, char* argv[])
|
||||
|
||||
#ifndef WIN32
|
||||
if (command_line::arg_present(vm, arg_detach)) {
|
||||
std::cout << "start daemon" << std::endl;
|
||||
return 0;
|
||||
std::cout << "forking to background..." << std::endl;
|
||||
posix_fork();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -225,9 +225,10 @@ int main(int argc, char* argv[])
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core");
|
||||
LOG_PRINT_L0("Core initialized OK");
|
||||
|
||||
// start components
|
||||
if(!command_line::has_arg(vm, arg_console))
|
||||
// Start handling console input if requested and not detached
|
||||
if(!command_line::arg_present(vm, arg_console) && !command_line::arg_present(vm, arg_detach))
|
||||
{
|
||||
LOG_PRINT_L0("Begin handling console input");
|
||||
console_command_thread.start();
|
||||
}
|
||||
|
||||
|
104
src/daemon/posix_fork.cpp
Normal file
104
src/daemon/posix_fork.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
#include "daemon/posix_fork.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <syslog.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
namespace daemonize {
|
||||
|
||||
void posix_fork()
|
||||
{
|
||||
// Fork the process and have the parent exit. If the process was started
|
||||
// from a shell, this returns control to the user. Forking a new process is
|
||||
// also a prerequisite for the subsequent call to setsid().
|
||||
if (pid_t pid = fork())
|
||||
{
|
||||
if (pid > 0)
|
||||
{
|
||||
// We're in the parent process and need to exit.
|
||||
//
|
||||
// When the exit() function is used, the program terminates without
|
||||
// invoking local variables' destructors. Only global variables are
|
||||
// destroyed. As the io_service object is a local variable, this means
|
||||
// we do not have to call:
|
||||
//
|
||||
// io_service.notify_fork(boost::asio::io_service::fork_parent);
|
||||
//
|
||||
// However, this line should be added before each call to exit() if
|
||||
// using a global io_service object. An additional call:
|
||||
//
|
||||
// io_service.notify_fork(boost::asio::io_service::fork_prepare);
|
||||
//
|
||||
// should also precede the second fork().
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_ERR | LOG_USER, "First fork failed: %m");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Make the process a new session leader. This detaches it from the
|
||||
// terminal.
|
||||
setsid();
|
||||
|
||||
// A process inherits its working directory from its parent. This could be
|
||||
// on a mounted filesystem, which means that the running daemon would
|
||||
// prevent this filesystem from being unmounted. Changing to the root
|
||||
// directory avoids this problem.
|
||||
chdir("/");
|
||||
|
||||
// The file mode creation mask is also inherited from the parent process.
|
||||
// We don't want to restrict the permissions on files created by the
|
||||
// daemon, so the mask is cleared.
|
||||
umask(0);
|
||||
|
||||
// A second fork ensures the process cannot acquire a controlling terminal.
|
||||
if (pid_t pid = fork())
|
||||
{
|
||||
if (pid > 0)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_ERR | LOG_USER, "Second fork failed: %m");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Close the standard streams. This decouples the daemon from the terminal
|
||||
// that started it.
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
|
||||
// We don't want the daemon to have any standard input.
|
||||
if (open("/dev/null", O_RDONLY) < 0)
|
||||
{
|
||||
syslog(LOG_ERR | LOG_USER, "Unable to open /dev/null: %m");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Send standard output to a log file.
|
||||
const char* output = "/tmp/bitmonero.daemon.out";
|
||||
const int flags = O_WRONLY | O_CREAT | O_APPEND;
|
||||
const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||
if (open(output, flags, mode) < 0)
|
||||
{
|
||||
syslog(LOG_ERR | LOG_USER, "Unable to open output file %s: %m", output);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Also send standard error to the same log file.
|
||||
if (dup(1) < 0)
|
||||
{
|
||||
syslog(LOG_ERR | LOG_USER, "Unable to dup output descriptor: %m");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
7
src/daemon/posix_fork.h
Normal file
7
src/daemon/posix_fork.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace daemonize {
|
||||
|
||||
void posix_fork();
|
||||
|
||||
} // namespace daemonize
|
Loading…
Reference in New Issue
Block a user