mirror of https://github.com/tmux/tmux.git
Instead of bailing out on the first configuration file error, carry on,
collecting all the errors, then start with the active window in more mode displaying them.pull/1/head
parent
5e6a7c85cc
commit
8aba77b7be
57
cfg.c
57
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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
55
server.c
55
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. */
|
||||
|
|
7
tmux.c
7
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
7
tmux.h
7
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 */
|
||||
|
|
|
@ -52,6 +52,16 @@ struct window_more_mode_data {
|
|||
u_int top;
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue