mirror of
https://github.com/tmate-io/tmate.git
synced 2024-11-24 17:13:56 +01:00
Send commands with their arguments in an array
This commit is contained in:
parent
c88870b0a3
commit
02694d2a96
@ -201,12 +201,13 @@ cmdq_continue_one(struct cmd_q *cmdq)
|
||||
char *tmp;
|
||||
int flags = !!(cmd->flags & CMD_CONTROL);
|
||||
|
||||
tmp = cmd_print(cmd);
|
||||
log_debug("cmdq %p: %s", cmdq, tmp);
|
||||
#ifdef TMATE
|
||||
if (tmate_should_replicate_cmd(cmd->entry))
|
||||
tmate_exec_cmd(tmp);
|
||||
tmate_exec_cmd(cmd);
|
||||
#endif
|
||||
|
||||
tmp = cmd_print(cmd);
|
||||
log_debug("cmdq %p: %s", cmdq, tmp);
|
||||
free(tmp);
|
||||
|
||||
cmdq->time = time(NULL);
|
||||
|
8
server.c
8
server.c
@ -135,13 +135,13 @@ server_create_socket(void)
|
||||
static void tmate_set_editor_mode(void)
|
||||
{
|
||||
switch (options_get_number(global_s_options, "status-keys")) {
|
||||
case MODEKEY_EMACS: tmate_exec_cmd("set-option -g status-keys emacs"); break;
|
||||
case MODEKEY_VI: tmate_exec_cmd("set-option -g status-keys vi"); break;
|
||||
case MODEKEY_EMACS: tmate_exec_cmd_args(4, (const char *[]){"set-option", "-g", "status-keys", "emacs"}); break;
|
||||
case MODEKEY_VI: tmate_exec_cmd_args(4, (const char *[]){"set-option", "-g", "status-keys", "vi"}); break;
|
||||
}
|
||||
|
||||
switch (options_get_number(global_w_options, "mode-keys")) {
|
||||
case MODEKEY_EMACS: tmate_exec_cmd("set-window-option -g mode-keys emacs"); break;
|
||||
case MODEKEY_VI: tmate_exec_cmd("set-window-option -g mode-keys vi"); break;
|
||||
case MODEKEY_EMACS: tmate_exec_cmd_args(4, (const char *[]){"set-window-option", "-g", "status-keys", "emacs"}); break;
|
||||
case MODEKEY_VI: tmate_exec_cmd_args(4, (const char *[]){"set-window-option", "-g", "status-keys", "vi"}); break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -78,8 +78,8 @@ static void handle_resize(struct tmate_session *session,
|
||||
extern char **cfg_causes;
|
||||
extern u_int cfg_ncauses;
|
||||
|
||||
static void handle_exec_cmd(__unused struct tmate_session *session,
|
||||
struct tmate_unpacker *uk)
|
||||
static void handle_exec_cmd_str(__unused struct tmate_session *session,
|
||||
struct tmate_unpacker *uk)
|
||||
{
|
||||
struct cmd_q *cmd_q;
|
||||
struct cmd_list *cmdlist;
|
||||
@ -114,6 +114,55 @@ out:
|
||||
free(cmd_str);
|
||||
}
|
||||
|
||||
static void handle_exec_cmd(__unused struct tmate_session *session,
|
||||
struct tmate_unpacker *uk)
|
||||
{
|
||||
struct cmd_q *cmd_q;
|
||||
struct cmd_list *cmdlist;
|
||||
struct cmd *cmd;
|
||||
char *cause;
|
||||
u_int i;
|
||||
unsigned int argc;
|
||||
char **argv;
|
||||
|
||||
int client_id = unpack_int(uk);
|
||||
|
||||
argc = uk->argc;
|
||||
argv = xmalloc(sizeof(char *) * argc);
|
||||
for (i = 0; i < argc; i++)
|
||||
argv[i] = unpack_string(uk);
|
||||
|
||||
cmd = cmd_parse(argc, argv, NULL, 0, &cause);
|
||||
if (!cmd) {
|
||||
tmate_failed_cmd(client_id, cause);
|
||||
free(cause);
|
||||
goto out;
|
||||
}
|
||||
|
||||
cmdlist = xcalloc(1, sizeof *cmdlist);
|
||||
cmdlist->references = 1;
|
||||
TAILQ_INIT(&cmdlist->list);
|
||||
TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
|
||||
|
||||
cmd_q = cmdq_new(NULL);
|
||||
cmdq_run(cmd_q, cmdlist, NULL);
|
||||
cmd_list_free(cmdlist);
|
||||
cmdq_free(cmd_q);
|
||||
|
||||
/* error messages land in cfg_causes */
|
||||
for (i = 0; i < cfg_ncauses; i++) {
|
||||
tmate_failed_cmd(client_id, cfg_causes[i]);
|
||||
free(cfg_causes[i]);
|
||||
}
|
||||
|
||||
free(cfg_causes);
|
||||
cfg_causes = NULL;
|
||||
cfg_ncauses = 0;
|
||||
|
||||
out:
|
||||
cmd_free_argv(argc, argv);
|
||||
}
|
||||
|
||||
static void maybe_save_reconnection_data(struct tmate_session *session,
|
||||
const char *name, const char *value)
|
||||
{
|
||||
@ -152,10 +201,11 @@ void tmate_dispatch_slave_message(struct tmate_session *session,
|
||||
dispatch(TMATE_IN_NOTIFY, handle_notify);
|
||||
dispatch(TMATE_IN_LEGACY_PANE_KEY, handle_legacy_pane_key);
|
||||
dispatch(TMATE_IN_RESIZE, handle_resize);
|
||||
dispatch(TMATE_IN_EXEC_CMD, handle_exec_cmd);
|
||||
dispatch(TMATE_IN_EXEC_CMD_STR, handle_exec_cmd_str);
|
||||
dispatch(TMATE_IN_SET_ENV, handle_set_env);
|
||||
dispatch(TMATE_IN_READY, handle_ready);
|
||||
dispatch(TMATE_IN_PANE_KEY, handle_pane_key);
|
||||
dispatch(TMATE_IN_EXEC_CMD, handle_exec_cmd);
|
||||
default: tmate_info("Bad message type: %d", cmd);
|
||||
}
|
||||
}
|
||||
|
@ -152,44 +152,99 @@ int tmate_should_replicate_cmd(const struct cmd_entry *cmd)
|
||||
|
||||
#define sc (&session->saved_tmux_cmds)
|
||||
#define SAVED_TMUX_CMD_INITIAL_SIZE 256
|
||||
static void __tmate_exec_cmd(const char *cmd);
|
||||
static void __tmate_exec_cmd_args(int argc, const char **argv);
|
||||
|
||||
static void append_saved_cmd(struct tmate_session *session,
|
||||
const char *cmd)
|
||||
int argc, const char **argv)
|
||||
{
|
||||
if (!sc->cmds) {
|
||||
sc->capacity = SAVED_TMUX_CMD_INITIAL_SIZE;
|
||||
sc->cmds = xmalloc(sizeof(char *) * sc->capacity);
|
||||
sc->cmds = xmalloc(sizeof(*sc->cmds) * sc->capacity);
|
||||
sc->tail = 0;
|
||||
}
|
||||
|
||||
if (sc->tail == sc->capacity) {
|
||||
sc->capacity *= 2;
|
||||
sc->cmds = xrealloc(sc->cmds, sizeof(char *) * sc->capacity);
|
||||
sc->cmds = xrealloc(sc->cmds, sizeof(*sc->cmds) * sc->capacity);
|
||||
}
|
||||
|
||||
sc->cmds[sc->tail++] = xstrdup(cmd);
|
||||
sc->cmds[sc->tail].argc = argc;
|
||||
sc->cmds[sc->tail].argv = cmd_copy_argv(argc, (char **)argv);
|
||||
|
||||
sc->tail++;
|
||||
}
|
||||
|
||||
static void replay_saved_cmd(struct tmate_session *session)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < sc->tail; i++)
|
||||
__tmate_exec_cmd(sc->cmds[i]);
|
||||
__tmate_exec_cmd_args(sc->cmds[i].argc, (const char **)sc->cmds[i].argv);
|
||||
}
|
||||
#undef sc
|
||||
|
||||
static void __tmate_exec_cmd(const char *cmd)
|
||||
struct args_entry {
|
||||
u_char flag;
|
||||
char *value;
|
||||
RB_ENTRY(args_entry) entry;
|
||||
};
|
||||
|
||||
static void extract_cmd(struct cmd *cmd, int *_argc, char ***_argv)
|
||||
{
|
||||
pack(array, 2);
|
||||
pack(int, TMATE_OUT_EXEC_CMD);
|
||||
pack(string, cmd);
|
||||
struct args_entry *entry;
|
||||
struct args* args = cmd->args;
|
||||
int argc = 0;
|
||||
char **argv;
|
||||
int next = 0, i;
|
||||
|
||||
argc++; /* cmd name */
|
||||
RB_FOREACH(entry, args_tree, &args->tree) {
|
||||
argc++;
|
||||
if (entry->value != NULL)
|
||||
argc++;
|
||||
}
|
||||
argc += args->argc;
|
||||
argv = xmalloc(sizeof(char *) * argc);
|
||||
|
||||
argv[next++] = xstrdup(cmd->entry->name);
|
||||
|
||||
RB_FOREACH(entry, args_tree, &args->tree) {
|
||||
xasprintf(&argv[next++], "-%c", entry->flag);
|
||||
if (entry->value != NULL)
|
||||
argv[next++] = xstrdup(entry->value);
|
||||
}
|
||||
|
||||
for (i = 0; i < args->argc; i++)
|
||||
argv[next++] = xstrdup(args->argv[i]);
|
||||
|
||||
*_argc = argc;
|
||||
*_argv = argv;
|
||||
}
|
||||
|
||||
void tmate_exec_cmd(const char *cmd)
|
||||
static void __tmate_exec_cmd_args(int argc, const char **argv)
|
||||
{
|
||||
__tmate_exec_cmd(cmd);
|
||||
append_saved_cmd(&tmate_session, cmd);
|
||||
int i;
|
||||
|
||||
pack(array, argc + 1);
|
||||
pack(int, TMATE_OUT_EXEC_CMD);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
pack(string, argv[i]);
|
||||
}
|
||||
|
||||
void tmate_exec_cmd_args(int argc, const char **argv)
|
||||
{
|
||||
__tmate_exec_cmd_args(argc, argv);
|
||||
append_saved_cmd(&tmate_session, argc, argv);
|
||||
}
|
||||
|
||||
void tmate_exec_cmd(struct cmd *cmd)
|
||||
{
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
extract_cmd(cmd, &argc, &argv);
|
||||
tmate_exec_cmd_args(argc, (const char **)argv);
|
||||
cmd_free_argv(argc, argv);
|
||||
}
|
||||
|
||||
void tmate_failed_cmd(int client_id, const char *cause)
|
||||
|
@ -45,7 +45,7 @@ enum tmate_daemon_out_msg_types {
|
||||
TMATE_OUT_HEADER,
|
||||
TMATE_OUT_SYNC_LAYOUT,
|
||||
TMATE_OUT_PTY_DATA,
|
||||
TMATE_OUT_EXEC_CMD,
|
||||
TMATE_OUT_EXEC_CMD_STR,
|
||||
TMATE_OUT_FAILED_CMD,
|
||||
TMATE_OUT_STATUS,
|
||||
TMATE_OUT_SYNC_COPY_MODE,
|
||||
@ -54,6 +54,7 @@ enum tmate_daemon_out_msg_types {
|
||||
TMATE_OUT_READY,
|
||||
TMATE_OUT_RECONNECT,
|
||||
TMATE_OUT_SNAPSHOT,
|
||||
TMATE_OUT_EXEC_CMD,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -62,7 +63,7 @@ enum tmate_daemon_out_msg_types {
|
||||
[[int: pane_id, int: sx, int: sy, int: xoff, int: yoff], ...],
|
||||
int: active_pane_id], ...], int: active_win_id]
|
||||
[TMATE_OUT_PTY_DATA, int: pane_id, binary: buffer]
|
||||
[TMATE_OUT_EXEC_CMD, string: cmd]
|
||||
[TMATE_OUT_EXEC_CMD_STR, string: cmd]
|
||||
[TMATE_OUT_FAILED_CMD, int: client_id, string: cause]
|
||||
[TMATE_OUT_STATUS, string: left, string: right]
|
||||
[TMATE_OUT_SYNC_COPY_MODE, int: pane_id, [int: backing, int: oy, int: cx, int: cy,
|
||||
@ -72,26 +73,31 @@ enum tmate_daemon_out_msg_types {
|
||||
[TMATE_OUT_WRITE_COPY_MODE, int: pane_id, string: str]
|
||||
[TMATE_OUT_FIN]
|
||||
[TMATE_OUT_READY]
|
||||
[TMATE_OUT_RECONNECT, string: reconnection_data]
|
||||
[TMATE_OUT_SNAPSHOT, ...]
|
||||
[TMATE_OUT_EXEC_CMD, string: cmd_name, ...string: args]
|
||||
*/
|
||||
|
||||
enum tmate_daemon_in_msg_types {
|
||||
TMATE_IN_NOTIFY,
|
||||
TMATE_IN_LEGACY_PANE_KEY,
|
||||
TMATE_IN_RESIZE,
|
||||
TMATE_IN_EXEC_CMD,
|
||||
TMATE_IN_EXEC_CMD_STR,
|
||||
TMATE_IN_SET_ENV,
|
||||
TMATE_IN_READY,
|
||||
TMATE_IN_PANE_KEY,
|
||||
TMATE_IN_EXEC_CMD,
|
||||
};
|
||||
|
||||
/*
|
||||
[TMATE_IN_NOTIFY, string: msg]
|
||||
[TMATE_IN_PANE_KEY, int: key]
|
||||
[TMATE_IN_RESIZE, int: sx, int: sy] // sx == -1: no clients
|
||||
[TMATE_IN_EXEC_CMD, int: client_id, string: cmd]
|
||||
[TMATE_IN_EXEC_CMD_STR, int: client_id, string: cmd]
|
||||
[TMATE_IN_SET_ENV, string: name, string: value]
|
||||
[TMATE_IN_READY]
|
||||
[TMATE_IN_PANE_KEY, int: pane_id, uint64 keycode] // pane_id == -1: active pane
|
||||
[TMATE_IN_EXEC_CMD, int: client_id, ...string: args]
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
8
tmate.h
8
tmate.h
@ -84,7 +84,8 @@ extern void tmate_write_ready(void);
|
||||
extern void tmate_sync_layout(void);
|
||||
extern void tmate_pty_data(struct window_pane *wp, const char *buf, size_t len);
|
||||
extern int tmate_should_replicate_cmd(const struct cmd_entry *cmd);
|
||||
extern void tmate_exec_cmd(const char *cmd);
|
||||
extern void tmate_exec_cmd_args(int argc, const char **argv);
|
||||
extern void tmate_exec_cmd(struct cmd *cmd);
|
||||
extern void tmate_failed_cmd(int client_id, const char *cause);
|
||||
extern void tmate_status(const char *left, const char *right);
|
||||
extern void tmate_sync_copy_mode(struct window_pane *wp);
|
||||
@ -184,7 +185,10 @@ struct tmate_session {
|
||||
struct {
|
||||
unsigned int capacity;
|
||||
unsigned int tail;
|
||||
char **cmds;
|
||||
struct {
|
||||
int argc;
|
||||
char **argv;
|
||||
} *cmds;
|
||||
} saved_tmux_cmds;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user