aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Cunha <tcunha@gmx.com>2009-08-09 17:19:18 +0000
committerTiago Cunha <tcunha@gmx.com>2009-08-09 17:19:18 +0000
commit5b56ea181649793918779dd2684c671072ce4bc9 (patch)
tree1debbcde3af4260db40f82735e2cc968d8dec438
parent602aae783945d39450788de983318c0da5172315 (diff)
downloadrtmux-5b56ea181649793918779dd2684c671072ce4bc9.tar.gz
rtmux-5b56ea181649793918779dd2684c671072ce4bc9.tar.bz2
rtmux-5b56ea181649793918779dd2684c671072ce4bc9.zip
Sync OpenBSD patchset 225:
If there is an error in the configuration file, don't just exit(1) as this can cause the client to hang. Instead, send the error message, then mark the client as bad and start a normal shutdown so the server exits once the error is written. This also allows some code duplicating daemon(3) to be trimmed and logging to begin earlier. Prompted by Theo noticing the behaviour on error wasn't documented.
-rw-r--r--server-fn.c4
-rw-r--r--server.c87
-rw-r--r--tmux.16
-rw-r--r--tmux.h3
4 files changed, 57 insertions, 43 deletions
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 <nicm@users.sourceforge.net>
@@ -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 <nicm@users.sourceforge.net>
@@ -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 <nicm@users.sourceforge.net>
.\"
@@ -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 <nicm@users.sourceforge.net>
@@ -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;