diff --git a/server-fn.c b/server-fn.c index 0cef9656..30f9de4a 100644 --- a/server-fn.c +++ b/server-fn.c @@ -1,4 +1,4 @@ -/* $Id: server-fn.c,v 1.78 2009-07-30 20:21:55 tcunha Exp $ */ +/* $Id: server-fn.c,v 1.79 2009-08-09 17:19:18 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -62,6 +62,8 @@ server_write_client( { struct hdr hdr; + if (c->flags & CLIENT_BAD) + return; log_debug("writing %d to client %d", type, c->fd); hdr.type = type; diff --git a/server.c b/server.c index aa5a4292..98897316 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.164 2009-07-28 23:11:18 tcunha Exp $ */ +/* $Id: server.c,v 1.165 2009-08-09 17:19:18 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -130,10 +130,11 @@ server_client_index(struct client *c) int server_start(char *path) { - int pair[2], srv_fd, null_fd; - char *cause; + struct client *c; + int pair[2], srv_fd; + char *cause; #ifdef HAVE_SETPROCTITLE - char rpathbuf[MAXPATHLEN]; + char rpathbuf[MAXPATHLEN]; #endif /* The first client is special and gets a socketpair; create it. */ @@ -155,9 +156,12 @@ server_start(char *path) * Must daemonise before loading configuration as the PID changes so * $TMUX would be wrong for sessions created in the config file. */ - if (daemon(1, 1) != 0) + if (daemon(1, 0) != 0) fatal("daemon failed"); + logfile("server"); + log_debug("server started, pid %ld", (long) getpid()); + ARRAY_INIT(&windows); ARRAY_INIT(&clients); ARRAY_INIT(&sessions); @@ -172,47 +176,39 @@ server_start(char *path) start_time = time(NULL); socket_path = path; - if (access(SYSTEM_CFG, R_OK) != 0) { - if (errno != ENOENT) { - log_warn("%s", SYSTEM_CFG); - exit(1); - } - } else { - if (load_cfg(SYSTEM_CFG, &cause) != 0) { - log_warnx("%s", cause); - exit(1); - } - } - if (cfg_file != NULL && load_cfg(cfg_file, &cause) != 0) { - log_warnx("%s", cause); - exit(1); - } - logfile("server"); - - /* - * Close stdin/stdout/stderr. Can't let daemon() do this as they are - * needed until now to print configuration file errors. - */ - if ((null_fd = open(_PATH_DEVNULL, O_RDWR)) != -1) { - dup2(null_fd, STDIN_FILENO); - dup2(null_fd, STDOUT_FILENO); - dup2(null_fd, STDERR_FILENO); - if (null_fd > 2) - close(null_fd); - } - - log_debug("server started, pid %ld", (long) getpid()); - log_debug("socket path %s", socket_path); - #ifdef HAVE_SETPROCTITLE if (realpath(socket_path, rpathbuf) == NULL) strlcpy(rpathbuf, socket_path, sizeof rpathbuf); + log_debug("socket path %s", socket_path); setproctitle("server (%s)", rpathbuf); #endif srv_fd = server_create_socket(); server_create_client(pair[1]); + if (access(SYSTEM_CFG, R_OK) != 0) { + if (errno != ENOENT) { + xasprintf( + &cause, "%s: %s", strerror(errno), SYSTEM_CFG); + goto error; + } + } else if (load_cfg(SYSTEM_CFG, &cause) != 0) + goto error; + if (cfg_file != NULL && load_cfg(cfg_file, &cause) != 0) + goto error; + + exit(server_main(srv_fd)); + +error: + /* Write the error and shutdown the server. */ + c = ARRAY_FIRST(&clients); + + server_write_error(c, cause); + xfree(cause); + + server_shutdown(); + c->flags |= CLIENT_BAD; + exit(server_main(srv_fd)); } @@ -424,8 +420,13 @@ server_shutdown(void) for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); - if (c != NULL) - server_write_client(c, MSG_SHUTDOWN, NULL, 0); + if (c != NULL) { + if (c->flags & CLIENT_BAD) + server_lost_client(c); + else + server_write_client(c, MSG_SHUTDOWN, NULL, 0); + c->flags |= CLIENT_BAD; + } } } @@ -677,7 +678,8 @@ server_fill_clients(struct pollfd **pfd) (*pfd)->fd = -1; else { (*pfd)->fd = c->fd; - (*pfd)->events = POLLIN; + if (!(c->flags & CLIENT_BAD)) + (*pfd)->events = POLLIN; if (BUFFER_USED(c->out) > 0) (*pfd)->events |= POLLOUT; } @@ -725,6 +727,11 @@ server_handle_clients(struct pollfd **pfd) server_lost_client(c); (*pfd) += 2; continue; + } else if (c->flags & CLIENT_BAD) { + if (BUFFER_USED(c->out) == 0) + server_lost_client(c); + (*pfd) += 2; + continue; } else server_msg_dispatch(c); } diff --git a/tmux.1 b/tmux.1 index ac4ec273..89ce74cb 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $Id: tmux.1,v 1.142 2009-08-09 16:59:35 tcunha Exp $ +.\" $Id: tmux.1,v 1.143 2009-08-09 17:19:18 tcunha Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -120,6 +120,10 @@ if present, then looks for a user configuration file at The configuration file is a set of .Nm commands which are executed in sequence when the server is first started. +.Pp +If a command in the configuration file fails, +.Nm +will report an error and exit without executing further commands. .It Fl L Ar socket-name .Nm stores the server socket in a directory under diff --git a/tmux.h b/tmux.h index 25b60acc..5dbd06f8 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.404 2009-08-09 16:57:49 tcunha Exp $ */ +/* $Id: tmux.h,v 1.405 2009-08-09 17:19:18 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -899,6 +899,7 @@ struct client { #define CLIENT_STATUS 0x10 #define CLIENT_REPEAT 0x20 /* allow command to repeat within repeat time */ #define CLIENT_SUSPENDED 0x40 +#define CLIENT_BAD 0x80 int flags; char *message_string;