mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Add ability to run the daemon in foreground
Useful for things like a Docker container or just running it in the terminal. Complements the stdout logging option. This is actually why the stdout logging was added in the first place -- to be used in the foreground mode, though nothing stops one from using stdout in the background mode, which one could redirect to a file.
This commit is contained in:
parent
2ef1ce9421
commit
e1fc8c1d3c
@ -523,6 +523,7 @@ bool print_help()
|
|||||||
{
|
{
|
||||||
// 2 space ident
|
// 2 space ident
|
||||||
// make sure all lines fit into 80 columns
|
// make sure all lines fit into 80 columns
|
||||||
|
// make sure options are listed in alphabetical order
|
||||||
write_log(LOG_LEVEL_INFO,
|
write_log(LOG_LEVEL_INFO,
|
||||||
"Usage: tox-bootstrapd [OPTION]... --config=FILE_PATH\n"
|
"Usage: tox-bootstrapd [OPTION]... --config=FILE_PATH\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -531,6 +532,8 @@ bool print_help()
|
|||||||
" This is a required option.\n"
|
" This is a required option.\n"
|
||||||
" Set FILE_PATH to a path to an empty file in order to\n"
|
" Set FILE_PATH to a path to an empty file in order to\n"
|
||||||
" use default settings.\n"
|
" use default settings.\n"
|
||||||
|
" --foreground Run the daemon in foreground. The daemon won't fork\n"
|
||||||
|
" (detach from the terminal) and won't use the PID file.\n"
|
||||||
" --help Print this help message.\n"
|
" --help Print this help message.\n"
|
||||||
" --log-backend=BACKEND Specify which logging backend to use.\n"
|
" --log-backend=BACKEND Specify which logging backend to use.\n"
|
||||||
" Valid BACKEND values (case sensetive):\n"
|
" Valid BACKEND values (case sensetive):\n"
|
||||||
@ -544,7 +547,7 @@ bool print_help()
|
|||||||
// Handels command line arguments, setting cfg_file_path and log_backend.
|
// Handels command line arguments, setting cfg_file_path and log_backend.
|
||||||
// Terminates the application if incorrect arguments are specified.
|
// Terminates the application if incorrect arguments are specified.
|
||||||
|
|
||||||
void handle_command_line_arguments(int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend)
|
void handle_command_line_arguments(int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend, bool *run_in_foreground)
|
||||||
{
|
{
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
write_log(LOG_LEVEL_ERROR, "Error: No arguments provided.\n\n");
|
write_log(LOG_LEVEL_ERROR, "Error: No arguments provided.\n\n");
|
||||||
@ -557,6 +560,7 @@ void handle_command_line_arguments(int argc, char *argv[], char **cfg_file_path,
|
|||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
{"config", required_argument, 0, 'c'}, // required option
|
{"config", required_argument, 0, 'c'}, // required option
|
||||||
|
{"foreground", no_argument, 0, 'f'},
|
||||||
{"log-backend", required_argument, 0, 'l'}, // optional, defaults to syslog
|
{"log-backend", required_argument, 0, 'l'}, // optional, defaults to syslog
|
||||||
{"version", no_argument, 0, 'v'},
|
{"version", no_argument, 0, 'v'},
|
||||||
{0, 0, 0, 0 }
|
{0, 0, 0, 0 }
|
||||||
@ -565,6 +569,8 @@ void handle_command_line_arguments(int argc, char *argv[], char **cfg_file_path,
|
|||||||
bool cfg_file_path_set = false;
|
bool cfg_file_path_set = false;
|
||||||
bool log_backend_set = false;
|
bool log_backend_set = false;
|
||||||
|
|
||||||
|
*run_in_foreground = false;
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, ":", long_options, NULL)) != -1) {
|
while ((opt = getopt_long(argc, argv, ":", long_options, NULL)) != -1) {
|
||||||
@ -579,6 +585,10 @@ void handle_command_line_arguments(int argc, char *argv[], char **cfg_file_path,
|
|||||||
cfg_file_path_set = true;
|
cfg_file_path_set = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
*run_in_foreground = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
if (strcmp(optarg, "syslog") == 0) {
|
if (strcmp(optarg, "syslog") == 0) {
|
||||||
*log_backend = LOG_BACKEND_SYSLOG;
|
*log_backend = LOG_BACKEND_SYSLOG;
|
||||||
@ -620,16 +630,77 @@ void handle_command_line_arguments(int argc, char *argv[], char **cfg_file_path,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Demonizes the process, appending PID to the PID file and closing file descriptors based on log backend
|
||||||
|
// Terminates the application if the daemonization fails.
|
||||||
|
|
||||||
|
void daemonize(LOG_BACKEND log_backend, char *pid_file_path)
|
||||||
|
{
|
||||||
|
// Check if the PID file exists
|
||||||
|
FILE *pid_file;
|
||||||
|
|
||||||
|
if ((pid_file = fopen(pid_file_path, "r"))) {
|
||||||
|
write_log(LOG_LEVEL_WARNING, "Another instance of the daemon is already running, PID file %s exists.\n", pid_file_path);
|
||||||
|
fclose(pid_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the PID file for writing
|
||||||
|
pid_file = fopen(pid_file_path, "a+");
|
||||||
|
if (pid_file == NULL) {
|
||||||
|
write_log(LOG_LEVEL_ERROR, "Couldn't open the PID file for writing: %s. Exiting.\n", pid_file_path);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fork off from the parent process
|
||||||
|
const pid_t pid = fork();
|
||||||
|
|
||||||
|
if (pid > 0) {
|
||||||
|
fprintf(pid_file, "%d", pid);
|
||||||
|
fclose(pid_file);
|
||||||
|
write_log(LOG_LEVEL_INFO, "Forked successfully: PID: %d.\n", pid);
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
fclose(pid_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid < 0) {
|
||||||
|
write_log(LOG_LEVEL_ERROR, "Forking failed. Exiting.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new SID for the child process
|
||||||
|
if (setsid() < 0) {
|
||||||
|
write_log(LOG_LEVEL_ERROR, "SID creation failure. Exiting.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the file mode mask
|
||||||
|
umask(0);
|
||||||
|
|
||||||
|
// Change the current working directory
|
||||||
|
if ((chdir("/")) < 0) {
|
||||||
|
write_log(LOG_LEVEL_ERROR, "Couldn't change working directory to '/'. Exiting.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go quiet
|
||||||
|
if (log_backend != LOG_BACKEND_STDOUT) {
|
||||||
|
close(STDOUT_FILENO);
|
||||||
|
close(STDIN_FILENO);
|
||||||
|
close(STDERR_FILENO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *cfg_file_path;
|
char *cfg_file_path;
|
||||||
LOG_BACKEND log_backend;
|
LOG_BACKEND log_backend;
|
||||||
|
bool run_in_foreground;
|
||||||
|
|
||||||
// choose backend for printing command line argument parsing output based on whether the daemon is being run from a terminal
|
// choose backend for printing command line argument parsing output based on whether the daemon is being run from a terminal
|
||||||
log_backend = isatty(STDOUT_FILENO) ? LOG_BACKEND_STDOUT : LOG_BACKEND_SYSLOG;
|
log_backend = isatty(STDOUT_FILENO) ? LOG_BACKEND_STDOUT : LOG_BACKEND_SYSLOG;
|
||||||
|
|
||||||
open_log(log_backend);
|
open_log(log_backend);
|
||||||
handle_command_line_arguments(argc, argv, &cfg_file_path, &log_backend);
|
handle_command_line_arguments(argc, argv, &cfg_file_path, &log_backend, &run_in_foreground);
|
||||||
close_log();
|
close_log();
|
||||||
|
|
||||||
open_log(log_backend);
|
open_log(log_backend);
|
||||||
@ -660,14 +731,12 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the PID file exists
|
if (!run_in_foreground) {
|
||||||
FILE *pid_file;
|
daemonize(log_backend, pid_file_path);
|
||||||
|
|
||||||
if ((pid_file = fopen(pid_file_path, "r"))) {
|
|
||||||
write_log(LOG_LEVEL_WARNING, "Another instance of the daemon is already running, PID file %s exists.\n", pid_file_path);
|
|
||||||
fclose(pid_file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(pid_file_path);
|
||||||
|
|
||||||
IP ip;
|
IP ip;
|
||||||
ip_init(&ip, enable_ipv6);
|
ip_init(&ip, enable_ipv6);
|
||||||
|
|
||||||
@ -690,7 +759,6 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DHT *dht = new_DHT(net);
|
DHT *dht = new_DHT(net);
|
||||||
|
|
||||||
if (dht == NULL) {
|
if (dht == NULL) {
|
||||||
@ -724,6 +792,8 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(keys_file_path);
|
||||||
|
|
||||||
TCP_Server *tcp_server = NULL;
|
TCP_Server *tcp_server = NULL;
|
||||||
|
|
||||||
if (enable_tcp_relay) {
|
if (enable_tcp_relay) {
|
||||||
@ -754,56 +824,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
print_public_key(dht->self_public_key);
|
print_public_key(dht->self_public_key);
|
||||||
|
|
||||||
// Write the PID file
|
|
||||||
FILE *pidf = fopen(pid_file_path, "a+");
|
|
||||||
|
|
||||||
if (pidf == NULL) {
|
|
||||||
write_log(LOG_LEVEL_ERROR, "Couldn't open the PID file for writing: %s. Exiting.\n", pid_file_path);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pid_file_path);
|
|
||||||
free(keys_file_path);
|
|
||||||
|
|
||||||
// Fork off from the parent process
|
|
||||||
const pid_t pid = fork();
|
|
||||||
|
|
||||||
if (pid > 0) {
|
|
||||||
fprintf(pidf, "%d", pid);
|
|
||||||
fclose(pidf);
|
|
||||||
write_log(LOG_LEVEL_INFO, "Forked successfully: PID: %d.\n", pid);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
fclose(pidf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid < 0) {
|
|
||||||
write_log(LOG_LEVEL_ERROR, "Forking failed. Exiting.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the file mode mask
|
|
||||||
umask(0);
|
|
||||||
|
|
||||||
// Create a new SID for the child process
|
|
||||||
if (setsid() < 0) {
|
|
||||||
write_log(LOG_LEVEL_ERROR, "SID creation failure. Exiting.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the current working directory
|
|
||||||
if ((chdir("/")) < 0) {
|
|
||||||
write_log(LOG_LEVEL_ERROR, "Couldn't change working directory to '/'. Exiting.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go quiet
|
|
||||||
if (log_backend != LOG_BACKEND_STDOUT) {
|
|
||||||
close(STDOUT_FILENO);
|
|
||||||
close(STDIN_FILENO);
|
|
||||||
close(STDERR_FILENO);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t last_LANdiscovery = 0;
|
uint64_t last_LANdiscovery = 0;
|
||||||
const uint16_t htons_port = htons(port);
|
const uint16_t htons_port = htons(port);
|
||||||
|
|
||||||
@ -811,7 +831,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (enable_lan_discovery) {
|
if (enable_lan_discovery) {
|
||||||
LANdiscovery_init(dht);
|
LANdiscovery_init(dht);
|
||||||
write_log(LOG_LEVEL_INFO, "Initialized LAN discovery.\n");
|
write_log(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -829,7 +849,7 @@ int main(int argc, char *argv[])
|
|||||||
networking_poll(dht->net);
|
networking_poll(dht->net);
|
||||||
|
|
||||||
if (waiting_for_dht_connection && DHT_isconnected(dht)) {
|
if (waiting_for_dht_connection && DHT_isconnected(dht)) {
|
||||||
write_log(LOG_LEVEL_INFO, "Connected to other bootstrap node successfully.\n");
|
write_log(LOG_LEVEL_INFO, "Connected to another bootstrap node successfully.\n");
|
||||||
waiting_for_dht_connection = 0;
|
waiting_for_dht_connection = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user