diff --git a/cfg.c b/cfg.c index 1fcbd0d6..2410fbf9 100644 --- a/cfg.c +++ b/cfg.c @@ -157,6 +157,9 @@ cfg_default_done(__unused struct cmd_q *cmdq) cfg_finished = 1; #ifdef TMATE + /* We do it this late, this way, CLI options take precedence over cfg file */ + tmate_load_cli_options(); + tmate_session_start(); if (tmate_foreground && cfg_ncauses) { print_cfg_errors(); diff --git a/client.c b/client.c index ad349972..456fe793 100644 --- a/client.c +++ b/client.c @@ -217,37 +217,37 @@ extern const struct cmd_entry cmd_new_session_entry; /* For foreground mode */ static int __argc; -static char **__argv; +static const char **__argv; #endif -static void _run_initial_client_cmd(int argc, char **argv) +int run_headless_command(int argc, const char **argv, int flags, void (*err_callback)(const char *)) { struct cmd_q *cmd_q; struct cmd_list *cmdlist; char *cause; - const char *default_argv[] = {"new-session"}; - - if (argc == 0) { - argc = 1; - argv = (char **)default_argv; - } - cmd_q = cmdq_new(NULL); /* No client */ if ((cmdlist = cmd_list_parse(argc, (char **)argv, NULL, 0, &cause)) == NULL) { - tmate_fatal("%s", cause); + if (err_callback) + err_callback(cause); + return -1; } cmdq_run(cmd_q, cmdlist, NULL); cmd_list_free(cmdlist); cmdq_free(cmd_q); + if (flags & DEFER_ERRORS_CFG) + return 0; + /* error messages land in cfg_causes */ extern char **cfg_causes; extern u_int cfg_ncauses; - int has_error = !!cfg_ncauses; + + int ret = cfg_ncauses ? -1 : 0; for (u_int i = 0; i < cfg_ncauses; i++) { - tmate_info("%s", cfg_causes[i]); + if (err_callback) + err_callback(cfg_causes[i]); free(cfg_causes[i]); } @@ -255,13 +255,27 @@ static void _run_initial_client_cmd(int argc, char **argv) cfg_causes = NULL; cfg_ncauses = 0; - if (has_error) - exit(1); + return ret; +} + +static void initial_client_cmd_err_callback(const char *cause) +{ + tmate_info("%s", cause); } void run_initial_client_cmd(void) { - _run_initial_client_cmd(__argc, __argv); + int argc = __argc; + const char **argv = __argv; + + const char *default_argv[] = {"new-session"}; + if (argc == 0) { + argc = 1; + argv = default_argv; + } + + if (run_headless_command(argc, argv, 0, initial_client_cmd_err_callback) < 0) + exit(1); } /* Client main loop. */ @@ -282,7 +296,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags, #ifdef TMATE int cant_nest = 0; __argc = argc; - __argv = argv; + __argv = (const char **)argv; #endif /* Ignore SIGCHLD now or daemon() in the server will leave a zombie. */ diff --git a/server.c b/server.c index f8f08d12..05706769 100644 --- a/server.c +++ b/server.c @@ -203,7 +203,6 @@ server_start(struct event_base *base, int lockfd, char *lockfile) #ifdef TMATE tmate_set_editor_mode(); - tmate_init_boot_options(); #endif start_cfg(); diff --git a/tmux.c b/tmux.c index 90b46403..2c790eca 100644 --- a/tmux.c +++ b/tmux.c @@ -207,26 +207,20 @@ static char *session_name; static char *session_name_ro; static char *authorized_keys; -void tmate_init_boot_options(void) +void tmate_load_cli_options(void) { - if (account_key) - tmate_exec_cmd_args(4, (const char *[]){"set-option", "-g", "tmate-account-key", account_key}); - if (session_name) - tmate_exec_cmd_args(4, (const char *[]){"set-option", "-g", "tmate-session-name", session_name}); - if (session_name_ro) - tmate_exec_cmd_args(4, (const char *[]){"set-option", "-g", "tmate-session-name-ro", session_name_ro}); - if (authorized_keys) - tmate_exec_cmd_args(4, (const char *[]){"set-option", "-g", "tmate-authorized-keys", authorized_keys}); - - free(account_key); - free(session_name); - free(session_name_ro); - free(authorized_keys_file); - - account_key = NULL; - session_name = NULL; - session_name_ro = NULL; - authorized_keys = NULL; +#define SET_OPT(name, val) ({\ + if (val) { \ + run_headless_command(3, (const char *[]){"set-option", name, val}, DEFER_ERRORS_CFG, NULL); \ + free(val); \ + val = NULL; \ + } \ +}) + SET_OPT("tmate-account-key", account_key); + SET_OPT("tmate-account-name", session_name); + SET_OPT("tmate-account-name-ro", session_name_ro); + SET_OPT("tmate-authorized-keys", authorized_keys); +#undef SET_OPT } #endif diff --git a/tmux.h b/tmux.h index 83a573c1..9f3ca7bd 100644 --- a/tmux.h +++ b/tmux.h @@ -1551,7 +1551,7 @@ extern struct timeval start_time; extern const char *socket_path; #ifdef TMATE extern int tmate_foreground; -void tmate_init_boot_options(void); +void tmate_load_cli_options(void); #endif const char *getshell(void); int checkshell(const char *); @@ -1879,6 +1879,8 @@ void signal_waiting_clients(const char *name); void cmd_wait_for_flush(void); /* client.c */ +#define DEFER_ERRORS_CFG 1 +int run_headless_command(int argc, const char **argv, int flags, void (*err_callback)(const char *)); void run_initial_client_cmd(void); int client_main(struct event_base *, int, char **, int, const char *);