diff --git a/CMakeLists.txt b/CMakeLists.txt index d2ee06fc..4f8687b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,6 +106,12 @@ else() install(FILES ${CMAKE_BINARY_DIR}/trojan.service ${CMAKE_BINARY_DIR}/trojan@.service DESTINATION ${SYSTEMD_SERVICE_PATH}) endif() + include(CheckSymbolExists) + check_symbol_exists(daemon "stdlib.h;unistd.h" HAVE_DAEMON) + if(HAVE_DAEMON) + add_definitions(-DHAVE_DAEMON) + endif() + enable_testing() add_test(NAME LinuxSmokeTest-basic COMMAND bash ${CMAKE_SOURCE_DIR}/tests/LinuxSmokeTest/basic.sh ${CMAKE_BINARY_DIR}/trojan) diff --git a/docs/trojan.1 b/docs/trojan.1 index 5f8ed0a8..5e0c08bb 100644 --- a/docs/trojan.1 +++ b/docs/trojan.1 @@ -14,6 +14,9 @@ and start either a proxy client or a proxy server. .BR \-c, " " \-\-config=\fICONFIG\fR Set the config file to be loaded. Default is \fI/etc/trojan/config.json\fR. .TP +.BR \-d, " " \-\-daemon +Detach from the terminal and run in the background as a daemon. +.TP .BR \-h, " " \-\-help Print help message. .TP diff --git a/docs/usage.md b/docs/usage.md index 132862b4..e887e00a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -4,6 +4,7 @@ usage: ./trojan [-htv] [-l LOG] [-k KEYLOG] [[-c] CONFIG] options: -c [ --config ] CONFIG specify config file + -d [ --daemon ] fork into background -h [ --help ] print help message -k [ --keylog ] KEYLOG specify keylog file location (OpenSSL >= 1.1.1) -l [ --log ] LOG specify log file location diff --git a/src/main.cpp b/src/main.cpp index 99483403..30642dc1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,6 +26,9 @@ #ifdef ENABLE_MYSQL #include #endif // ENABLE_MYSQL +#ifdef HAVE_DAEMON +#include +#endif // HAVE_DAEMON #include "core/service.h" #include "core/version.h" using namespace std; @@ -68,9 +71,11 @@ int main(int argc, const char *argv[]) { string log_file; string keylog_file; bool test; + bool do_daemon; po::options_description desc("options"); desc.add_options() ("config,c", po::value(&config_file)->default_value(DEFAULT_CONFIG)->value_name("CONFIG"), "specify config file") + ("daemon,d", po::bool_switch(&do_daemon), "fork into background") ("help,h", "print help message") ("keylog,k", po::value(&keylog_file)->value_name("KEYLOG"), "specify keylog file location (OpenSSL >= 1.1.1)") ("log,l", po::value(&log_file)->value_name("LOG"), "specify log file location") @@ -83,7 +88,7 @@ int main(int argc, const char *argv[]) { po::store(po::command_line_parser(argc, argv).options(desc).positional(pd).run(), vm); po::notify(vm); if (vm.count("help")) { - Log::log(string("usage: ") + argv[0] + " [-htv] [-l LOG] [-k KEYLOG] [[-c] CONFIG]", Log::FATAL); + Log::log(string("usage: ") + argv[0] + " [-hdtv] [-l LOG] [-k KEYLOG] [[-c] CONFIG]", Log::FATAL); cerr << desc; exit(EXIT_SUCCESS); } @@ -137,6 +142,16 @@ int main(int argc, const char *argv[]) { if (vm.count("keylog")) { Log::redirect_keylog(keylog_file); } +#ifdef HAVE_DAEMON + if (do_daemon && daemon(0, 0) == -1) { + Log::log(string("Failed to fork into background: ") + strerror(errno), Log::FATAL); + exit(EXIT_FAILURE); + } +#else // HAVE_DAEMON + if (do_daemon) { + Log::log("Daemon mode not supported on this system", Log::FATAL); + } +#endif // HAVE_DAEMON bool restart; Config config; do {