diff --git a/inc/lektor/cmd.h b/inc/lektor/cmd.h index 94a96cde6a2480a4d96ae3d1fa7ef8c72bc1a397..39f27694f79ec856f4f4156c786c21713b7a7526 100644 --- a/inc/lektor/cmd.h +++ b/inc/lektor/cmd.h @@ -5,8 +5,7 @@ extern "C" { #endif -#include <stdnoreturn.h> -#include <stddef.h> +#include <lektor/common.h> #define CMD_OPT_NULL \ { \ @@ -31,14 +30,15 @@ struct cmd_opt { /* Parse the command line with the list of options. No parameter may be NULL. Does not return. */ -noreturn void cmd_parse(struct cmd_opt *opts, int argc, const char **argv); +EXIT_FUNCTION cmd_parse(struct cmd_opt *opts, int argc, const char **argv); /* Must be setted for the lkt_cmd_parse function to display the correct help in case of errors. */ -extern const char *executable_name; +void cmd_set_executable_name(const char *); +const char *cmd_get_executable_name(void); /* Prints the help and exit */ -noreturn void print_help(void); +EXIT_FUNCTION print_help(void); #if defined(__cplusplus) } diff --git a/inc/lektor/common.h b/inc/lektor/common.h index f5c04dee543e0fd3fabcadd29ccc8f6a8515b618..a9494ac9cdf8755a2094be39f4945c3e3aa1265a 100644 --- a/inc/lektor/common.h +++ b/inc/lektor/common.h @@ -99,7 +99,8 @@ typedef enum { LOG_LEVEL_DEBUG = 4, ___LAST_UNUSED_LOG_LEVEL, /* Usefull to enable all by default */ } LOG_LEVEL; -extern LOG_LEVEL ___log_level; +void lkt_set_log_level(LOG_LEVEL); +LOG_LEVEL lkt_get_log_level(void); void ___lkt_log(LOG_LEVEL, const char *sec, const char *func, const char *file, uint64_t l, const char *fmt, ...); #define LOG_DEBUG(sec, ...) ___lkt_log(LOG_LEVEL_DEBUG, sec, __func__, __FILE__, __LINE__, __VA_ARGS__) #define LOG_INFO(sec, ...) ___lkt_log(LOG_LEVEL_INFO, sec, __func__, __FILE__, __LINE__, __VA_ARGS__) diff --git a/inc/lektor/os.h b/inc/lektor/os.h index 1f1fbdc63ca59077e2ed678bedfb61ec4b0d57c9..9eeb5a0fc369b012d5d6f5d75122afa30343ae3b 100644 --- a/inc/lektor/os.h +++ b/inc/lektor/os.h @@ -12,6 +12,8 @@ extern "C" { #include <inttypes.h> #include <unistd.h> +#include <stdnoreturn.h> +#include <stddef.h> #if defined(__linux__) #include <linux/limits.h> @@ -55,7 +57,7 @@ typedef void (*function_ptr)(void); void lkt_thread_set_name(const char name[16]); /* Get the path to the currently executing binary */ -int read_self_exe(char *path, size_t len); +int lkt_read_self_exe(char *path, size_t len); /* OS specific defines */ #define SELF_EXECUTABLE_LINUX "/proc/self/exe" diff --git a/inc/lektor/segv.h b/inc/lektor/segv.h index 5ed3005fb2b694ad5636b98fdfc4c0ccc1318c09..1d3d73f571e839f654ce98b8997446398597e8a1 100644 --- a/inc/lektor/segv.h +++ b/inc/lektor/segv.h @@ -5,7 +5,9 @@ extern "C" { #endif -void install_segv_handler(void); +void lkt_install_segv_handler(void); +void lkt_segv_quiet(void); +void lkt_segv_verbose(void); #if defined(__cplusplus) } diff --git a/src/base/cmd.c b/src/base/cmd.c index b4098138d573df2b58b22b9b47fb80bc86149ba6..d610eec5e766076d88806d618044c1bcce49ef30 100644 --- a/src/base/cmd.c +++ b/src/base/cmd.c @@ -12,7 +12,29 @@ #include <wait.h> #include <errno.h> -const char *executable_name = NULL; +static const char *executable_name = NULL; + +void +cmd_set_executable_name(const char *str) +{ + if (executable_name != NULL) + free((void *)executable_name); + executable_name = strdup(str); + assert(executable_name); +} + +const char * +cmd_get_executable_name(void) +{ + return executable_name; +} + +DESTRUCTOR_FUNCTION +___cleanup_executable_name(void) +{ + if (executable_name != NULL) + free((void *)executable_name); +} EXIT_FUNCTION print_help(void) diff --git a/src/base/commands.c b/src/base/commands.c index c1f95b07e889176fe2be526e1179c145448262a0..a2804c26e241ac6aae6b0810de92a2b77f7105a5 100644 --- a/src/base/commands.c +++ b/src/base/commands.c @@ -21,12 +21,12 @@ inline bool command_restart(struct lkt_state *srv, size_t c, char UNUSED *__argv[LKT_MESSAGE_ARGS_MAX]) { - const char *const argv[] = { executable_name, NULL }; + const char *const argv[] = { cmd_get_executable_name(), NULL }; struct lkt_queue_state sta; memset(&sta, 0, sizeof(struct lkt_queue_state)); RETURN_UNLESS(lkt_client_auth(srv, c, false), "Failed to authentificate user", false); - if (!executable_name) { + if (!argv[0]) { LOG_ERROR("GENERAL", "Can't restart if the executable path was not found at start-up"); return false; } @@ -44,7 +44,7 @@ command_restart(struct lkt_state *srv, size_t c, char UNUSED *__argv[LKT_MESSAGE lkt_close_server(srv); - execv(executable_name, (char *const *)argv); + execv(argv[0], (char *const *)argv); LOG_ERROR("GENERAL", "Failed to exec lektor or OS not supported"); exit(EXIT_FAILURE); } diff --git a/src/base/common.c b/src/base/common.c index fb60ffd0bbaaa42681608f3fd6dee6a8444d0cfb..57f6bf8f2f8ee83e7a9474b25f540e62bda1aba2 100644 --- a/src/base/common.c +++ b/src/base/common.c @@ -51,7 +51,20 @@ __set_assert(void) /* Log functions */ -LOG_LEVEL ___log_level = ___LAST_UNUSED_LOG_LEVEL; /* All by default */ +static LOG_LEVEL ___log_level = ___LAST_UNUSED_LOG_LEVEL; /* All by default */ + +void +lkt_set_log_level(LOG_LEVEL lvl) +{ + assert(lvl != ___LAST_UNUSED_LOG_LEVEL); + ___log_level = lvl; +} + +LOG_LEVEL +lkt_get_log_level(void) +{ + return ___log_level; +} void ___lkt_log(LOG_LEVEL level, const char *section, const char *func, const char *file, uint64_t line_number, diff --git a/src/base/config.c b/src/base/config.c index fe0dc851acdf808ab11080151dca626a1568ba5c..0d6292ddbb81d9c04c2fa04bdaa1f1d783b63e37 100644 --- a/src/base/config.c +++ b/src/base/config.c @@ -58,17 +58,17 @@ __set_log_level(const char *name, const char *level) } if (STR_MATCH(level, "error")) - ___log_level = LOG_LEVEL_ERROR; + lkt_set_log_level(LOG_LEVEL_ERROR); else if (STR_MATCH(level, "warn") || STR_MATCH(level, "warning")) - ___log_level = LOG_LEVEL_WARN; + lkt_set_log_level(LOG_LEVEL_WARN); else if (STR_MATCH(level, "info")) - ___log_level = LOG_LEVEL_INFO; + lkt_set_log_level(LOG_LEVEL_INFO); else if (STR_MATCH(level, "debug")) - ___log_level = LOG_LEVEL_DEBUG; + lkt_set_log_level(LOG_LEVEL_DEBUG); else - ___log_level = strtol(level, NULL, 0); + lkt_set_log_level(strtol(level, NULL, 0)); - LOG_INFO("CONFIG", "Log level set to %d", ___log_level); + LOG_INFO("CONFIG", "Log level set to %d", lkt_get_log_level()); } static inline int diff --git a/src/base/launch.c b/src/base/launch.c index e8dc05e79fba97bc5f55291bc40120225ca2f88e..e7755565d2b1eea0e4d053aea75ea1c0f5532d39 100644 --- a/src/base/launch.c +++ b/src/base/launch.c @@ -23,7 +23,7 @@ extern char **environ; /* Private implementation details */ -static pid_t ___klkt_pid = 0; +static pid_t ___klkt_pid = 0; static int ___is_appimage = 0; char exe[PATH_MAX]; @@ -37,7 +37,7 @@ resolve_path(void) RETURN_UNLESS(env_PATH, "Failed to get PATH in env", NOTHING); char new_path[PATH_MAX]; char exe_path[LKT_LINE_MAX]; - GOTO_IF(read_self_exe(exe_path, LKT_LINE_MAX), "Failed to get exe path", error); + GOTO_IF(lkt_read_self_exe(exe_path, LKT_LINE_MAX), "Failed to get exe path", error); char *self_dir = dirname(exe_path); LOG_DEBUG("INIT", "Try to patch PATH with %s", self_dir); safe_snprintf(new_path, PATH_MAX, "%s:%s", self_dir, env_PATH); @@ -49,7 +49,6 @@ error: LOG_DEBUG("INIT", "Failed to patch PATH, it will remain as: %s", env_PATH); } - void resolve_appimage(void) { @@ -70,7 +69,6 @@ resolve_appimage(void) LOG_DEBUG("INIT", "No AppImage env variable found!"); } - DESTRUCTOR_FUNCTION ___kill_klkt(void) { @@ -128,7 +126,7 @@ launch_ext_klkt(va_list UNUSED *___args) if (appimage == NULL) { retry_without_appimage: appimage_once_goto = true; - if (read_self_exe(exe_path, LKT_LINE_MAX)) { + if (lkt_read_self_exe(exe_path, LKT_LINE_MAX)) { LOG_ERROR("INIT", "Failed to get the current executable path, not patching the PATH"); goto error; } @@ -199,4 +197,3 @@ launch_caching(va_list *args) va_end(copy); return ret_code; } - diff --git a/src/base/os.c b/src/base/os.c index ce1c9dc3c6e741d2ab4018a7d1b2682b98ffabbb..dd9d73c6c71649a170db9e11f0d9ca7be8226ae1 100644 --- a/src/base/os.c +++ b/src/base/os.c @@ -16,7 +16,7 @@ #endif int -read_self_exe(char *path, size_t len) +lkt_read_self_exe(char *path, size_t len) { return !((readlink(SELF_EXECUTABLE_LINUX, path, len - 1) > 0) || (readlink(SELF_EXECUTABLE_FREEBSD, path, len - 1) > 0) || diff --git a/src/base/segv.c b/src/base/segv.c index 7ea66721c1b73eba209f39d40f81dd5adec3c118..203455b707307c1cbcac19968ae3b1b3ad7da53f 100644 --- a/src/base/segv.c +++ b/src/base/segv.c @@ -12,9 +12,16 @@ #define BT_BUF_SIZE 100 +/* If you want to suppress the messages in install_segv_handler, declare the + * following variable as extern and set it to 0. */ +static int ___install_segv_handler_verbose = 1; + static void -__segv_handler(int sig) +___segv_handler(int sig) { + if (___install_segv_handler_verbose != 1) + return; + void *buffer[LKT_BACKLOG]; int nptrs = backtrace(buffer, LKT_BACKLOG); LOG_ERROR("SEGV", "Got signal %d", sig); @@ -32,15 +39,23 @@ __segv_handler(int sig) exit(EXIT_FAILURE); } -/* If you want to suppress the messages in install_segv_handler, declare the - * following variable as extern and set it to 0. */ -int __install_segv_handler_verbose = 1; +void +lkt_segv_quiet(void) +{ + ___install_segv_handler_verbose = 0; +} + +void +lkt_segv_verbose(void) +{ + ___install_segv_handler_verbose = 1; +} void -install_segv_handler(void) +lkt_install_segv_handler(void) { - if (SIG_ERR == signal(SIGSEGV, __segv_handler) && __install_segv_handler_verbose == 1) + if (SIG_ERR == signal(SIGSEGV, ___segv_handler) && ___install_segv_handler_verbose == 1) LOG_WARN("SIGNAL", "Failed to install the segv handler"); - if (__install_segv_handler_verbose == 1) + if (___install_segv_handler_verbose == 1) LOG_INFO("SIGNAL", "The segv handler has been installed"); } diff --git a/src/main/lkt.c b/src/main/lkt.c index 00c98e3ad8329bd872d44a2fcb4a7efc377090f2..00348aa82c48a9695a80c2c2cbf20245942b8139 100644 --- a/src/main/lkt.c +++ b/src/main/lkt.c @@ -28,9 +28,6 @@ #include <limits.h> #include <ctype.h> -/* Suppress logs with segv handler only for lkt to preserv a pretty output */ -extern int __install_segv_handler_verbose; - #define LKT_KEY_VALUE_SEP ": \n\t\0" #define fail_if(cond, msg) \ { \ @@ -1335,10 +1332,10 @@ parse_args(args_t *args, int argc, const char **argv) int main(int argc, const char **argv) { - __install_segv_handler_verbose = 0; - install_segv_handler(); - ___log_level = LOG_LEVEL_ERROR; - executable_name = "lkt"; + lkt_segv_quiet(); + lkt_install_segv_handler(); + lkt_set_log_level(LOG_LEVEL_ERROR); + cmd_set_executable_name("lkt"); assert(NULL != setlocale(LC_ALL, "en_US.UTF-8")); /* BECAUSE! */ if (signal(SIGPIPE, sigpipe__)) LOG_ERROR("SYS", "Failed to install handler for SIGPIPE signal (you may be using php...)"); diff --git a/src/main/luka.c b/src/main/luka.c index 237e2779ee8f467a30a24919bc6c8b3325153742..a83762ab4df4e72744cb228778e163378ecdb612 100644 --- a/src/main/luka.c +++ b/src/main/luka.c @@ -214,10 +214,6 @@ ___search(struct cmd_args *args, ___init_search_function init_function) exit(EXIT_SUCCESS); } -/* Suppress logs with segv handler only for lkt to preserv a pretty output */ - -extern int __install_segv_handler_verbose; - PRIVATE_FUNCTION void __sigpipe(int sig) { @@ -449,10 +445,10 @@ __SUB_COMMAND(admin) int main(const int argc, const char **argv) { - ___log_level = LOG_LEVEL_ERROR; - executable_name = "luka"; - __install_segv_handler_verbose = 0; - install_segv_handler(); + cmd_set_executable_name("luka"); + lkt_set_log_level(LOG_LEVEL_ERROR); + lkt_segv_quiet(); + lkt_install_segv_handler(); assert(NULL != setlocale(LC_ALL, "en_US.UTF-8")); /* BECAUSE! */ if (signal(SIGPIPE, __sigpipe)) LOG_ERROR("SYS", "Failed to install handler for SIGPIPE signal (you may be using php...)"); diff --git a/src/main/server.c b/src/main/server.c index 9901fb9da1367c21da50fb751dc1cf8c405215eb..383c69620c0650bef6691b3e4b1c8d10daefdd32 100644 --- a/src/main/server.c +++ b/src/main/server.c @@ -90,7 +90,7 @@ __mkdir(const char *dir) int main(int argc, char *argv[]) { - install_segv_handler(); + lkt_install_segv_handler(); lkt_thread_set_name("lektord/daemon"); REG_BEGIN(server_reg) @@ -109,7 +109,7 @@ main(int argc, char *argv[]) int autoclear, check_exclusive = 1, opt, dump_and_abort = 0; char *conf_file = safe_malloc(PATH_MAX * sizeof(char)); - executable_name = "lektord"; + cmd_set_executable_name("lektord"); /* Check args */ while ((opt = getopt(argc, argv, "DhFf:")) != -1) { @@ -131,9 +131,9 @@ main(int argc, char *argv[]) } reg_export(server_reg); - if (read_self_exe(exe, PATH_MAX)) + if (lkt_read_self_exe(exe, PATH_MAX)) LOG_WARN("INIT", "Failed to read self executable path, restart may not work"); - executable_name = exe; + cmd_set_executable_name(exe); LOG_WARN("INIT", "The argv[0] from main is: %s", exe); /* Resolves */