diff --git a/cfg.c b/cfg.c index fd6d54b7..917abfcb 100644 --- a/cfg.c +++ b/cfg.c @@ -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 @@ -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 5d12b267..e416a15a 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -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 @@ -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 9c3a5641..c97eff63 100644 --- a/cmd-source-file.c +++ b/cmd-source-file.c @@ -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 @@ -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 4277bbd0..d924a6c9 100644 --- a/server.c +++ b/server.c @@ -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 @@ -112,12 +112,12 @@ server_create_socket(void) int server_start(char *path) { - struct client *c; - int pair[2]; - char *cause; - struct timeval tv; + struct window_pane *wp; + int pair[2], retval; + struct timeval tv; + u_int i; #ifdef HAVE_SETPROCTITLE - char rpathbuf[MAXPATHLEN]; + char rpathbuf[MAXPATHLEN]; #endif /* 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_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); @@ -206,20 +222,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 ba6072e6..81a94116 100644 --- a/tmux.c +++ b/tmux.c @@ -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 @@ -435,15 +435,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 0e63cfdb..21de4b8e 100644 --- a/tmux.h +++ b/tmux.h @@ -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 @@ -1256,7 +1256,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[]; @@ -1866,6 +1870,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 d1cc4c0f..3c452267 100644 --- a/window-more.c +++ b/window-more.c @@ -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 @@ -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) { diff --git a/window.c b/window.c index 10f9f167..c48dc798 100644 --- a/window.c +++ b/window.c @@ -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 @@ -664,9 +664,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);