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
|
||||
// make sure all lines fit into 80 columns
|
||||
// make sure options are listed in alphabetical order
|
||||
write_log(LOG_LEVEL_INFO,
|
||||
"Usage: tox-bootstrapd [OPTION]... --config=FILE_PATH\n"
|
||||
"\n"
|
||||
@ -531,6 +532,8 @@ bool print_help()
|
||||
" This is a required option.\n"
|
||||
" Set FILE_PATH to a path to an empty file in order to\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"
|
||||
" --log-backend=BACKEND Specify which logging backend to use.\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.
|
||||
// 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) {
|
||||
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[] = {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"config", required_argument, 0, 'c'}, // required option
|
||||
{"foreground", no_argument, 0, 'f'},
|
||||
{"log-backend", required_argument, 0, 'l'}, // optional, defaults to syslog
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{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 log_backend_set = false;
|
||||
|
||||
*run_in_foreground = false;
|
||||
|
||||
int opt;
|
||||
|
||||
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;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
*run_in_foreground = true;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if (strcmp(optarg, "syslog") == 0) {
|
||||
*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[])
|
||||
{
|
||||
char *cfg_file_path;
|
||||
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
|
||||
log_backend = isatty(STDOUT_FILENO) ? LOG_BACKEND_STDOUT : LOG_BACKEND_SYSLOG;
|
||||
|
||||
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();
|
||||
|
||||
open_log(log_backend);
|
||||
@ -660,14 +731,12 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (!run_in_foreground) {
|
||||
daemonize(log_backend, pid_file_path);
|
||||
}
|
||||
|
||||
free(pid_file_path);
|
||||
|
||||
IP ip;
|
||||
ip_init(&ip, enable_ipv6);
|
||||
|
||||
@ -690,7 +759,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DHT *dht = new_DHT(net);
|
||||
|
||||
if (dht == NULL) {
|
||||
@ -724,6 +792,8 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(keys_file_path);
|
||||
|
||||
TCP_Server *tcp_server = NULL;
|
||||
|
||||
if (enable_tcp_relay) {
|
||||
@ -754,56 +824,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
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;
|
||||
const uint16_t htons_port = htons(port);
|
||||
|
||||
@ -811,7 +831,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (enable_lan_discovery) {
|
||||
LANdiscovery_init(dht);
|
||||
write_log(LOG_LEVEL_INFO, "Initialized LAN discovery.\n");
|
||||
write_log(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n");
|
||||
}
|
||||
|
||||
while (1) {
|
||||
@ -829,7 +849,7 @@ int main(int argc, char *argv[])
|
||||
networking_poll(dht->net);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user