Sync OpenBSD patchset 635:

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.
This commit is contained in:
Tiago Cunha 2010-02-08 18:10:07 +00:00
parent 676d0809d2
commit a32d095c97
8 changed files with 120 additions and 70 deletions

59
cfg.c
View File

@ -1,4 +1,4 @@
/* $Id: cfg.c,v 1.24 2009-11-28 14:50:36 tcunha Exp $ */ /* $Id: cfg.c,v 1.25 2010-02-08 18:10:07 tcunha Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -34,6 +34,9 @@ void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...); void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
char *cfg_cause; char *cfg_cause;
int cfg_finished;
char **cfg_causes;
u_int cfg_ncauses;
/* ARGSUSED */ /* ARGSUSED */
void printflike2 void printflike2
@ -52,19 +55,38 @@ cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
va_end(ap); 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 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; FILE *f;
u_int n; u_int n;
char *buf, *line, *ptr; char *buf, *line, *cause;
size_t len; size_t len;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
struct cmd_ctx ctx; struct cmd_ctx ctx;
if ((f = fopen(path, "rb")) == NULL) { if ((f = fopen(path, "rb")) == NULL) {
xasprintf(cause, "%s: %s", path, strerror(errno)); cfg_add_cause(ncauses, causes, "%s: %s", path, strerror(errno));
return (1); return (-1);
} }
n = 0; n = 0;
@ -80,10 +102,13 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
} }
n++; n++;
if (cmd_string_parse(buf, &cmdlist, cause) != 0) { if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
if (*cause == NULL) if (cause == NULL)
continue; continue;
goto error; cfg_add_cause(
ncauses, causes, "%s: %u: %s", path, n, cause);
xfree(cause);
continue;
} }
if (cmdlist == NULL) if (cmdlist == NULL)
continue; continue;
@ -107,23 +132,17 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
cmd_list_exec(cmdlist, &ctx); cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist); cmd_list_free(cmdlist);
if (cfg_cause != NULL) { if (cfg_cause != NULL) {
*cause = cfg_cause; cfg_add_cause(
goto error; ncauses, causes, "%s: %d: %s", path, n, cfg_cause);
xfree(cfg_cause);
continue;
} }
} }
if (line != NULL) if (line != NULL)
xfree(line); xfree(line);
fclose(f); fclose(f);
if (*ncauses != 0)
return (-1);
return (0); 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);
} }

View File

@ -1,4 +1,4 @@
/* $Id: cmd-new-session.c,v 1.73 2009-12-04 22:14:47 tcunha Exp $ */ /* $Id: cmd-new-session.c,v 1.74 2010-02-08 18:10:07 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -122,12 +122,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_new_session_data *data = self->data; struct cmd_new_session_data *data = self->data;
struct session *s, *groupwith; struct session *s, *groupwith;
struct window *w; struct window *w;
struct window_pane *wp;
struct environ env; struct environ env;
struct termios tio, *tiop; struct termios tio, *tiop;
const char *update; const char *update;
char *overrides, *cmd, *cwd, *cause; char *overrides, *cmd, *cwd, *cause;
int detached, idx; int detached, idx;
u_int sx, sy; u_int sx, sy, i;
if (data->newname != NULL && session_find(data->newname) != NULL) { if (data->newname != NULL && session_find(data->newname) != NULL) {
ctx->error(ctx, "duplicate session: %s", data->newname); 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(); recalculate_sizes();
server_update_socket(); 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 */ return (!detached); /* 1 means don't tell command client to exit */
} }

View File

@ -1,4 +1,4 @@
/* $Id: cmd-source-file.c,v 1.11 2009-11-28 14:50:36 tcunha Exp $ */ /* $Id: cmd-source-file.c,v 1.12 2010-02-08 18:10:07 tcunha Exp $ */
/* /*
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
@ -89,12 +89,18 @@ int
cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_source_file_data *data = self->data; struct cmd_source_file_data *data = self->data;
char *cause; char **causes;
u_int i, ncauses;
if (load_cfg(data->path, ctx, &cause) != 0) { causes = NULL;
ctx->error(ctx, "%s", cause); ncauses = 0;
xfree(cause);
return (-1); 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); return (0);

View File

@ -1,4 +1,4 @@
/* $Id: server.c,v 1.233 2010-02-02 23:50:01 tcunha Exp $ */ /* $Id: server.c,v 1.234 2010-02-08 18:10:07 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -112,12 +112,12 @@ server_create_socket(void)
int int
server_start(char *path) server_start(char *path)
{ {
struct client *c; struct window_pane *wp;
int pair[2]; int pair[2], retval;
char *cause; struct timeval tv;
struct timeval tv; u_int i;
#ifdef HAVE_SETPROCTITLE #ifdef HAVE_SETPROCTITLE
char rpathbuf[MAXPATHLEN]; char rpathbuf[MAXPATHLEN];
#endif #endif
/* The first client is special and gets a socketpair; create it. */ /* The first client is special and gets a socketpair; create it. */
@ -184,15 +184,31 @@ server_start(char *path)
server_fd = server_create_socket(); server_fd = server_create_socket();
server_client_create(pair[1]); server_client_create(pair[1]);
if (access(SYSTEM_CFG, R_OK) == 0) { retval = 0;
if (load_cfg(SYSTEM_CFG, NULL, &cause) != 0) if (access(SYSTEM_CFG, R_OK) == 0)
goto error; load_cfg(SYSTEM_CFG, NULL, &cfg_ncauses, &cfg_causes);
} else if (errno != ENOENT) { else if (errno != ENOENT) {
xasprintf(&cause, "%s: %s", strerror(errno), SYSTEM_CFG); cfg_add_cause(&cfg_ncauses, &cfg_causes,
goto error; "%s: %s", strerror(errno), SYSTEM_CFG);
} }
if (cfg_file != NULL && load_cfg(cfg_file, NULL, &cause) != 0) if (cfg_file != NULL)
goto error; 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, event_set(&server_ev_accept,
server_fd, EV_READ|EV_PERSIST, server_accept_callback, NULL); server_fd, EV_READ|EV_PERSIST, server_accept_callback, NULL);
@ -206,20 +222,6 @@ server_start(char *path)
server_signal_set(); server_signal_set();
server_loop(); server_loop();
exit(0); 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. */ /* Main server loop. */

9
tmux.c
View File

@ -1,4 +1,4 @@
/* $Id: tmux.c,v 1.199 2010-02-05 01:32:10 tcunha Exp $ */ /* $Id: tmux.c,v 1.200 2010-02-08 18:10:07 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -435,15 +435,10 @@ main(int argc, char **argv)
home = pw->pw_dir; home = pw->pw_dir;
} }
xasprintf(&cfg_file, "%s/%s", home, DEFAULT_CFG); 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); xfree(cfg_file);
cfg_file = NULL; cfg_file = NULL;
} }
} else {
if (access(cfg_file, R_OK) != 0) {
log_warn("%s", cfg_file);
exit(1);
}
} }
/* /*

9
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.540 2010-02-05 01:34:08 tcunha Exp $ */ /* $Id: tmux.h,v 1.541 2010-02-08 18:10:07 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -1256,7 +1256,11 @@ int checkshell(const char *);
int areshell(const char *); int areshell(const char *);
/* cfg.c */ /* 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 */ /* mode-key.c */
extern const struct mode_key_table mode_key_tables[]; extern const struct mode_key_table mode_key_tables[];
@ -1866,6 +1870,7 @@ void window_copy_pageup(struct window_pane *);
/* window-more.c */ /* window-more.c */
extern const struct window_mode window_more_mode; 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); void window_more_vadd(struct window_pane *, const char *, va_list);
/* window-choose.c */ /* window-choose.c */

View File

@ -1,4 +1,4 @@
/* $Id: window-more.c,v 1.41 2010-02-02 23:55:21 tcunha Exp $ */ /* $Id: window-more.c,v 1.42 2010-02-08 18:10:07 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -52,6 +52,16 @@ struct window_more_mode_data {
u_int top; 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 void
window_more_vadd(struct window_pane *wp, const char *fmt, va_list ap) window_more_vadd(struct window_pane *wp, const char *fmt, va_list ap)
{ {

View File

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.125 2009-12-04 22:14:47 tcunha Exp $ */ /* $Id: window.c,v 1.126 2010-02-08 18:10:07 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -664,9 +664,6 @@ window_pane_parse(struct window_pane *wp)
char *data; char *data;
size_t new_size; size_t new_size;
if (wp->mode != NULL)
return;
new_size = EVBUFFER_LENGTH(wp->event->input) - wp->pipe_off; new_size = EVBUFFER_LENGTH(wp->event->input) - wp->pipe_off;
if (wp->pipe_fd != -1 && new_size > 0) { if (wp->pipe_fd != -1 && new_size > 0) {
data = EVBUFFER_DATA(wp->event->input); data = EVBUFFER_DATA(wp->event->input);