Sync OpenBSD patchset 243:

Switch tmux to use imsg. This is the last major change to make the
client-server protocol more resilient and make the protocol versioning work
properly. In future, the only things requiring a protocol version bump will be
changes in the message structs, and (when both client and server have this
change) mixing different versions should nicely report an error message.

As a side effect this also makes the code tidier, fixes a problem with the way
errors reported during server startup were handled, and supports fd passing
(which will be used in future).

Looked over by eric@, thanks.

Please note that mixing a client with this change with an older server or vice
versa may cause tmux to crash or hang - tmux should be completely exited before
upgrading.
This commit is contained in:
Tiago Cunha
2009-08-14 21:04:04 +00:00
parent a604dfbb97
commit a9b6bfdddd
11 changed files with 880 additions and 149 deletions

View File

@ -1,4 +1,4 @@
/* $Id: server.c,v 1.166 2009-08-10 21:41:35 tcunha Exp $ */
/* $Id: server.c,v 1.167 2009-08-14 21:04:04 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -84,9 +84,7 @@ server_create_client(int fd)
fatal("fcntl failed");
c = xcalloc(1, sizeof *c);
c->fd = fd;
c->in = buffer_create(BUFSIZ);
c->out = buffer_create(BUFSIZ);
imsg_init(&c->ibuf, fd);
ARRAY_INIT(&c->prompt_hdata);
@ -677,10 +675,10 @@ server_fill_clients(struct pollfd **pfd)
if (c == NULL)
(*pfd)->fd = -1;
else {
(*pfd)->fd = c->fd;
(*pfd)->fd = c->ibuf.fd;
if (!(c->flags & CLIENT_BAD))
(*pfd)->events = POLLIN;
if (BUFFER_USED(c->out) > 0)
(*pfd)->events |= POLLIN;
if (c->ibuf.w.queued > 0)
(*pfd)->events |= POLLOUT;
}
(*pfd)++;
@ -723,17 +721,32 @@ server_handle_clients(struct pollfd **pfd)
c = ARRAY_ITEM(&clients, i);
if (c != NULL) {
if (buffer_poll(*pfd, c->in, c->out) != 0) {
if ((*pfd)->revents & (POLLERR|POLLNVAL|POLLHUP)) {
server_lost_client(c);
(*pfd) += 2;
continue;
} else if (c->flags & CLIENT_BAD) {
if (BUFFER_USED(c->out) == 0)
}
if ((*pfd)->revents & POLLOUT) {
if (msgbuf_write(&c->ibuf.w) < 0) {
server_lost_client(c);
(*pfd) += 2;
continue;
}
}
if (c->flags & CLIENT_BAD) {
if (c->ibuf.w.queued == 0)
server_lost_client(c);
(*pfd) += 2;
continue;
} else
server_msg_dispatch(c);
continue;
} else if ((*pfd)->revents & POLLIN) {
if (server_msg_dispatch(c) != 0) {
server_lost_client(c);
(*pfd) += 2;
continue;
}
}
}
(*pfd)++;
@ -915,9 +928,8 @@ server_lost_client(struct client *c)
if (c->cwd != NULL)
xfree(c->cwd);
close(c->fd);
buffer_destroy(c->in);
buffer_destroy(c->out);
close(c->ibuf.fd);
imsg_clear(&c->ibuf);
xfree(c);
recalculate_sizes();