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 CRYPTO crypto/*)
|
||||||
file(GLOB_RECURSE CRYPTONOTE_CORE cryptonote_core/*)
|
file(GLOB_RECURSE CRYPTONOTE_CORE cryptonote_core/*)
|
||||||
file(GLOB_RECURSE CRYPTONOTE_PROTOCOL cryptonote_protocol/*)
|
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 P2P p2p/*)
|
||||||
file(GLOB_RECURSE RPC rpc/*)
|
file(GLOB_RECURSE RPC rpc/*)
|
||||||
file(GLOB_RECURSE SIMPLEWALLET simplewallet/*)
|
file(GLOB_RECURSE SIMPLEWALLET simplewallet/*)
|
||||||
|
@ -23,9 +23,9 @@ using namespace epee;
|
|||||||
#include "rpc/core_rpc_server.h"
|
#include "rpc/core_rpc_server.h"
|
||||||
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
|
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
|
||||||
|
|
||||||
//#ifndef WIN32
|
#ifndef WIN32
|
||||||
//#include "posix_daemonize.h"
|
#include "posix_fork.h"
|
||||||
//#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
@ -166,8 +166,8 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
if (command_line::arg_present(vm, arg_detach)) {
|
if (command_line::arg_present(vm, arg_detach)) {
|
||||||
std::cout << "start daemon" << std::endl;
|
std::cout << "forking to background..." << std::endl;
|
||||||
return 0;
|
posix_fork();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -225,9 +225,10 @@ int main(int argc, char* argv[])
|
|||||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core");
|
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core");
|
||||||
LOG_PRINT_L0("Core initialized OK");
|
LOG_PRINT_L0("Core initialized OK");
|
||||||
|
|
||||||
// start components
|
// Start handling console input if requested and not detached
|
||||||
if(!command_line::has_arg(vm, arg_console))
|
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();
|
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