summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2013-10-20 17:28:43 +0000
committernicm <nicm>2013-10-20 17:28:43 +0000
commitbf35441608b05d52627215aa70bd52d9460812d4 (patch)
treebfca70f3b3a04d09511654a960fa5389cde22d37
parentf52eac62259c431daac84ddb6c2a5b7ebd528c2c (diff)
Do not run any command line command from the client which starts the
server until after the configuration file completes. This prevents it racing against run-shell or if-shell in .tmux.conf that run in the background.
-rw-r--r--cfg.c15
-rw-r--r--server-client.c9
-rw-r--r--server.c3
-rw-r--r--tmux.h1
4 files changed, 25 insertions, 3 deletions
diff --git a/cfg.c b/cfg.c
index c625a2fb..35192dc0 100644
--- a/cfg.c
+++ b/cfg.c
@@ -31,6 +31,7 @@ struct cmd_q *cfg_cmd_q;
int cfg_finished;
int cfg_references;
struct causelist cfg_causes;
+struct client *cfg_client;
int
load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
@@ -127,6 +128,20 @@ cfg_default_done(unused struct cmd_q *cmdq)
cmdq_free(cfg_cmd_q);
cfg_cmd_q = NULL;
+
+ if (cfg_client != NULL) {
+ /*
+ * The client command queue starts with client_exit set to 1 so
+ * only continue if not empty (that is, we have been delayed
+ * during configuration parsing for long enough that the
+ * MSG_COMMAND has arrived), else the client will exit before
+ * the MSG_COMMAND which might tell it not to.
+ */
+ if (!TAILQ_EMPTY(&cfg_client->cmdq->queue))
+ cmdq_continue(cfg_client->cmdq);
+ cfg_client->references--;
+ cfg_client = NULL;
+ }
}
void
diff --git a/server-client.c b/server-client.c
index b6d4870d..82d840a0 100644
--- a/server-client.c
+++ b/server-client.c
@@ -155,8 +155,8 @@ server_client_lost(struct client *c)
free(c->ttyname);
free(c->term);
- evbuffer_free (c->stdin_data);
- evbuffer_free (c->stdout_data);
+ evbuffer_free(c->stdin_data);
+ evbuffer_free(c->stdout_data);
if (c->stderr_data != c->stdout_data)
evbuffer_free (c->stderr_data);
@@ -932,7 +932,10 @@ server_client_msg_command(struct client *c, struct imsg *imsg)
}
cmd_free_argv(argc, argv);
- cmdq_run(c->cmdq, cmdlist);
+ if (c != cfg_client || cfg_finished)
+ cmdq_run(c->cmdq, cmdlist);
+ else
+ cmdq_append(c->cmdq, cmdlist);
cmd_list_free(cmdlist);
return;
diff --git a/server.c b/server.c
index ffc25db0..8ac9321e 100644
--- a/server.c
+++ b/server.c
@@ -168,6 +168,9 @@ server_start(int lockfd, char *lockfile)
cfg_finished = 0;
cfg_references = 1;
ARRAY_INIT(&cfg_causes);
+ cfg_client = ARRAY_FIRST(&clients);
+ if (cfg_client != NULL)
+ cfg_client->references++;
if (access(TMUX_CONF, R_OK) == 0) {
if (load_cfg(TMUX_CONF, cfg_cmd_q, &cause) == -1) {
diff --git a/tmux.h b/tmux.h
index 67192740..ddee0730 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1510,6 +1510,7 @@ extern struct cmd_q *cfg_cmd_q;
extern int cfg_finished;
extern int cfg_references;
extern struct causelist cfg_causes;
+extern struct client *cfg_client;
int load_cfg(const char *, struct cmd_q *, char **);
void cfg_default_done(struct cmd_q *);
void cfg_show_causes(struct session *);