diff --git a/include/constant.h b/include/constant.h index 3bc8dbb..2e560c9 100644 --- a/include/constant.h +++ b/include/constant.h @@ -36,6 +36,12 @@ #define ASSET_CHINA_IP "china-ip.txt" #define ASSET_CHINA_LIST "chinalist.txt" +#define EXIT_NORMAL 0 +#define EXIT_FILE_ERROR 1 +#define EXIT_FORK_ERROR 2 +#define EXIT_EXEC_ERROR 3 +#define EXIT_WAIT_ERROR 4 + #define HELP_MSG "\ ClearDNS usage \n\ --debug ...\n\ diff --git a/include/utils/process.h b/include/utils/process.h index 2d8e5b0..8fb82fd 100644 --- a/include/utils/process.h +++ b/include/utils/process.h @@ -4,10 +4,12 @@ #include typedef struct { + int pid; char *name; char **cmd; char **env; char *cwd; + // TODO: add is_daemon option int8_t is_group; // bool value } process; @@ -18,6 +20,6 @@ void process_add_arg(process *proc, const char *arg); process* process_init(const char *caption, const char *bin); #include -pid_t process_exec(process *proc); +void process_exec(process *proc); #endif diff --git a/src/cleardns.c b/src/cleardns.c index 2a464b3..62e6e50 100644 --- a/src/cleardns.c +++ b/src/cleardns.c @@ -48,9 +48,6 @@ int main(int argc, char *argv[]) { // ClearDNS service LOG_LEVEL = LOG_DEBUG; log_info("ClearDNS server start (%s)", VERSION); -// remove_file("/tmp/test.txt"); - create_folder("/tmp/test"); - return 0; // process *test = process_init("TEST", "lls"); // process *test = process_init("TEST", "ls"); @@ -65,15 +62,12 @@ int main(int argc, char *argv[]) { // ClearDNS service create_folder(WORK_DIR); - // TODO: load assets first extract_assets(); load_config(config_file); free(config_file); assets_load(loader.assets); - return 0; - if (LOG_LEVEL == LOG_DEBUG) { // debug mode enabled loader.filter->debug = TRUE; loader.diverter->debug = TRUE; @@ -82,7 +76,9 @@ int main(int argc, char *argv[]) { // ClearDNS service } process_list_init(); + // TODO: crontab of assets +// process_list_append(assets_load(loader.assets)); process_list_append(dnsproxy_load("Domestic", loader.domestic, "domestic.json")); process_list_append(dnsproxy_load("Foreign", loader.foreign, "foreign.json")); @@ -90,25 +86,15 @@ int main(int argc, char *argv[]) { // ClearDNS service if (loader.filter != NULL) { process_list_append(adguard_load(loader.filter, ADGUARD_DIR)); } - // TODO: running custom script for (char **script = loader.script; *script != NULL; ++script) { log_info("Run custom script -> `%s`", *script); + run_command(*script); } -// process_list_run(); - - -// init_server(init_script, custom_script); // run init script and custom script -// -// load_start_command(adguard_workdir, overture_config, upstream_config, debug_mode); // generate commands -// if (debug_mode) { // show exec command -// fprintf(stderr, "[ClearDNS] Debug mode.\n"); -// show_command("[ClearDNS] adguard", adguard_command); -// show_command("[ClearDNS] overture", overture_command); -// show_command("[ClearDNS] dnsproxy (domestic)", domestic_dnsproxy_command); -// show_command("[ClearDNS] dnsproxy (foreign)", foreign_dnsproxy_command); -// } -// -// server_daemon(); // run as daemon to manage process in docker + process_list_run(); + + int status; + wait(&status); + return 0; } diff --git a/src/utils/process.c b/src/utils/process.c index 9e1d61e..fd9f617 100644 --- a/src/utils/process.c +++ b/src/utils/process.c @@ -14,6 +14,7 @@ process **process_list; process* process_init(const char *caption, const char *bin) { // init process struct process *proc = (process *)malloc(sizeof(process)); + proc->pid = 0; // process not running proc->name = string_init(caption); // process caption proc->cmd = string_list_init(); string_list_append(&proc->cmd, bin); // argv[0] normally be process file name @@ -41,16 +42,42 @@ void process_list_append(process *proc) { // add new process into process list log_debug("%s process added", proc->name); } +void server_exit(int exit_code) { // kill sub process and exit + log_info("Kill subprocess"); + + // TODO: kill subprocess and exit cleardns + + exit(exit_code); +} + +void get_exit_signal() { // get SIGINT or SIGTERM signal + log_info("Get exit signal"); + + server_exit(EXIT_NORMAL); +} + +void get_sub_exit() { // catch child process exit + + log_debug("Get SIGCHLD signal"); + + // TODO: check exit subprocess and restart it +} + void process_list_run() { + + signal(SIGINT, get_exit_signal); // catch Ctrl + C (2) + signal(SIGTERM, get_exit_signal); // catch exit signal (15) + signal(SIGCHLD, get_sub_exit); // callback when child process die + for (process **p = process_list; *p != NULL; ++p) { - log_warn("proc -> %s", (*p)->name); + + process_exec(*p); + } -} -void server_exit() { - // TODO: kill subprocess and exit cleardns -} + log_warn("Process list start complete"); +} void process_dump(process *proc) { char *process_cmd = string_list_dump(proc->cmd); @@ -63,17 +90,19 @@ void process_dump(process *proc) { free(process_cmd); } -pid_t process_exec(process *proc) { +void process_exec(process *proc) { pid_t pid; process_dump(proc); + log_info("%s start", proc->name); + if ((pid = fork()) < 0) { // fork error - log_perror("Fork error"); - server_exit(); + log_perror("%s fork error", proc->name); + server_exit(EXIT_FORK_ERROR); } else if (pid == 0) { // child process - // TODO: new process group + // TODO: new process group if (proc->is_group) { setpgrp(); // new process group } @@ -90,7 +119,8 @@ pid_t process_exec(process *proc) { } } - return pid; + proc->pid = pid; + log_info("%s running success -> PID = %d", proc->name, proc->pid); }