summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cfg.c57
-rw-r--r--cmd-new-session.c18
-rw-r--r--cmd-source-file.c16
-rw-r--r--server.c55
-rw-r--r--tmux.c7
-rw-r--r--tmux.h7
-rw-r--r--window-more.c10
-rw-r--r--window.c3
8 files changed, 112 insertions, 61 deletions
diff --git a/cfg.c b/cfg.c
index 05588336..074f5f8b 100644
--- a/cfg.c
+++ b/cfg.c
@@ -34,6 +34,9 @@ void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
char *cfg_cause;
+int cfg_finished;
+char **cfg_causes;
+u_int cfg_ncauses;
/* ARGSUSED */
void printflike2
@@ -52,19 +55,38 @@ cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
va_end(ap);
}
+void printflike3
+cfg_add_cause(u_int *ncauses, char ***causes, const char *fmt, ...)
+{
+ char *cause;
+ va_list ap;
+
+ va_start(ap, fmt);
+ xvasprintf(&cause, fmt, ap);
+ va_end(ap);
+
+ *causes = xrealloc(*causes, *ncauses + 1, sizeof **causes);
+ (*causes)[(*ncauses)++] = cause;
+}
+
+/*
+ * Load configuration file. Returns -1 for an error with a list of messages in
+ * causes. Note that causes and ncauses must be initialised by the caller!
+ */
int
-load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
+load_cfg(
+ const char *path, struct cmd_ctx *ctxin, u_int *ncauses, char ***causes)
{
FILE *f;
u_int n;
- char *buf, *line, *ptr;
+ char *buf, *line, *cause;
size_t len;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
if ((f = fopen(path, "rb")) == NULL) {
- xasprintf(cause, "%s: %s", path, strerror(errno));
- return (1);
+ cfg_add_cause(ncauses, causes, "%s: %s", path, strerror(errno));
+ return (-1);
}
n = 0;
@@ -80,10 +102,13 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
}
n++;
- if (cmd_string_parse(buf, &cmdlist, cause) != 0) {
- if (*cause == NULL)
+ if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
+ if (cause == NULL)
continue;
- goto error;
+ cfg_add_cause(
+ ncauses, causes, "%s: %u: %s", path, n, cause);
+ xfree(cause);
+ continue;
}
if (cmdlist == NULL)
continue;
@@ -107,23 +132,17 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
if (cfg_cause != NULL) {
- *cause = cfg_cause;
- goto error;
+ cfg_add_cause(
+ ncauses, causes, "%s: %d: %s", path, n, cfg_cause);
+ xfree(cfg_cause);
+ continue;
}
}
if (line != NULL)
xfree(line);
fclose(f);
+ if (*ncauses != 0)
+ return (-1);
return (0);
-
-error:
- if (line != NULL)
- xfree(line);
- fclose(f);
-
- xasprintf(&ptr, "%s: %s at line %u", path, *cause, n);
- xfree(*cause);
- *cause = ptr;
- return (1);
}
diff --git a/cmd-new-session.c b/cmd-new-session.c
index 461e0391..20ef8d65 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -122,12 +122,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_new_session_data *data = self->data;
struct session *s, *groupwith;
struct window *w;
+ struct window_pane *wp;
struct environ env;
struct termios tio, *tiop;
const char *update;
char *overrides, *cmd, *cwd, *cause;
int detached, idx;
- u_int sx, sy;
+ u_int sx, sy, i;
if (data->newname != NULL && session_find(data->newname) != NULL) {
ctx->error(ctx, "duplicate session: %s", data->newname);
@@ -280,6 +281,21 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
recalculate_sizes();
server_update_socket();
+ /*
+ * If there are still configuration file errors to display, put the new
+ * session's current window into more mode and display them now.
+ */
+ if (cfg_finished && cfg_ncauses != 0) {
+ wp = s->curw->window->active;
+ window_pane_set_mode(wp, &window_more_mode);
+ for (i = 0; i < cfg_ncauses; i++) {
+ window_more_add(wp, "%s", cfg_causes[i]);
+ xfree(cfg_causes[i]);
+ }
+ xfree(cfg_causes);
+ cfg_ncauses = 0;
+ }
+
return (!detached); /* 1 means don't tell command client to exit */
}
diff --git a/cmd-source-file.c b/cmd-source-file.c
index f9ca9993..69a27e88 100644
--- a/cmd-source-file.c
+++ b/cmd-source-file.c
@@ -89,12 +89,18 @@ int
cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_source_file_data *data = self->data;
- char *cause;
+ char **causes;
+ u_int i, ncauses;
- if (load_cfg(data->path, ctx, &cause) != 0) {
- ctx->error(ctx, "%s", cause);
- xfree(cause);
- return (-1);
+ causes = NULL;
+ ncauses = 0;
+
+ if (load_cfg(data->path, ctx, &ncauses, &causes) != 0) {
+ for (i = 0; i < ncauses; i++) {
+ ctx->print(ctx, "%s", causes[i]);
+ xfree(causes[i]);
+ }
+ xfree(causes);
}
return (0);
diff --git a/server.c b/server.c
index ef8fa755..999389cc 100644
--- a/server.c
+++ b/server.c
@@ -113,10 +113,11 @@ server_create_socket(void)
int
server_start(char *path)
{
- struct client *c;
- int pair[2];
- char *cause, rpathbuf[MAXPATHLEN];
- struct timeval tv;
+ struct window_pane *wp;
+ int pair[2], retval;
+ char rpathbuf[MAXPATHLEN];
+ struct timeval tv;
+ u_int i;
/* The first client is special and gets a socketpair; create it. */
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
@@ -166,15 +167,31 @@ server_start(char *path)
server_fd = server_create_socket();
server_client_create(pair[1]);
- if (access(SYSTEM_CFG, R_OK) == 0) {
- if (load_cfg(SYSTEM_CFG, NULL, &cause) != 0)
- goto error;
- } else if (errno != ENOENT) {
- xasprintf(&cause, "%s: %s", strerror(errno), SYSTEM_CFG);
- goto error;
+ retval = 0;
+ if (access(SYSTEM_CFG, R_OK) == 0)
+ load_cfg(SYSTEM_CFG, NULL, &cfg_ncauses, &cfg_causes);
+ else if (errno != ENOENT) {
+ cfg_add_cause(&cfg_ncauses, &cfg_causes,
+ "%s: %s", strerror(errno), SYSTEM_CFG);
}
- if (cfg_file != NULL && load_cfg(cfg_file, NULL, &cause) != 0)
- goto error;
+ if (cfg_file != NULL)
+ load_cfg(cfg_file, NULL, &cfg_ncauses, &cfg_causes);
+
+ /*
+ * If there is a session already, put the current window and pane into
+ * more mode.
+ */
+ if (!ARRAY_EMPTY(&sessions) && cfg_ncauses != 0) {
+ wp = ARRAY_FIRST(&sessions)->curw->window->active;
+ window_pane_set_mode(wp, &window_more_mode);
+ for (i = 0; i < cfg_ncauses; i++) {
+ window_more_add(wp, "%s", cfg_causes[i]);
+ xfree(cfg_causes[i]);
+ }
+ xfree(cfg_causes);
+ cfg_ncauses = 0;
+ }
+ cfg_finished = 1;
event_set(&server_ev_accept,
server_fd, EV_READ|EV_PERSIST, server_accept_callback, NULL);
@@ -188,20 +205,6 @@ server_start(char *path)
server_signal_set();
server_loop();
exit(0);
-
-error:
- /* Write the error and shutdown the server. */
- c = ARRAY_FIRST(&clients);
-
- server_write_error(c, cause);
- server_write_client(c, MSG_EXIT, NULL, 0);
- xfree(cause);
-
- server_shutdown = 1;
-
- server_signal_set();
- server_loop();
- exit(1);
}
/* Main server loop. */
diff --git a/tmux.c b/tmux.c
index 758ad842..b59dd176 100644
--- a/tmux.c
+++ b/tmux.c
@@ -432,15 +432,10 @@ main(int argc, char **argv)
home = pw->pw_dir;
}
xasprintf(&cfg_file, "%s/%s", home, DEFAULT_CFG);
- if (access(cfg_file, R_OK) != 0) {
+ if (access(cfg_file, R_OK) != 0 && errno == ENOENT) {
xfree(cfg_file);
cfg_file = NULL;
}
- } else {
- if (access(cfg_file, R_OK) != 0) {
- log_warn("%s", cfg_file);
- exit(1);
- }
}
/*
diff --git a/tmux.h b/tmux.h
index c6bb8457..42a5301d 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1257,7 +1257,11 @@ int checkshell(const char *);
int areshell(const char *);
/* cfg.c */
-int load_cfg(const char *, struct cmd_ctx *, char **);
+extern int cfg_finished;
+extern char **cfg_causes;
+extern u_int cfg_ncauses;
+void printflike3 cfg_add_cause(u_int *, char ***, const char *, ...);
+int load_cfg(const char *, struct cmd_ctx *, u_int *, char ***);
/* mode-key.c */
extern const struct mode_key_table mode_key_tables[];
@@ -1867,6 +1871,7 @@ void window_copy_pageup(struct window_pane *);
/* window-more.c */
extern const struct window_mode window_more_mode;
+void window_more_add(struct window_pane *, const char *, ...);
void window_more_vadd(struct window_pane *, const char *, va_list);
/* window-choose.c */
diff --git a/window-more.c b/window-more.c
index 28423e1a..84f37d53 100644
--- a/window-more.c
+++ b/window-more.c
@@ -53,6 +53,16 @@ struct window_more_mode_data {
};
void
+window_more_add(struct window_pane *wp, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ window_more_vadd(wp, fmt, ap);
+ va_end(ap);
+}
+
+void
window_more_vadd(struct window_pane *wp, const char *fmt, va_list ap)
{
struct window_more_mode_data *data = wp->modedata;
diff --git a/window.c b/window.c
index 5494142e..a990fa57 100644
--- a/window.c
+++ b/window.c
@@ -657,9 +657,6 @@ window_pane_parse(struct window_pane *wp)
char *data;
size_t new_size;
- if (wp->mode != NULL)
- return;
-
new_size = EVBUFFER_LENGTH(wp->event->input) - wp->pipe_off;
if (wp->pipe_fd != -1 && new_size > 0) {
data = EVBUFFER_DATA(wp->event->input);