diff options
author | Nicholas Marriott <nicm@openbsd.org> | 2009-08-11 17:18:35 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@openbsd.org> | 2009-08-11 17:18:35 +0000 |
commit | f0635717b3e840a72a962a2014b18d84fac4c83a (patch) | |
tree | 579ab8805cc7d6784fb6c567dad3322a7b2a976e /server.c | |
parent | 60db6e3df471142e4ee7773b9b4e9b0135d61dfc (diff) | |
download | rtmux-f0635717b3e840a72a962a2014b18d84fac4c83a.tar.gz rtmux-f0635717b3e840a72a962a2014b18d84fac4c83a.tar.bz2 rtmux-f0635717b3e840a72a962a2014b18d84fac4c83a.zip |
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.
Diffstat (limited to 'server.c')
-rw-r--r-- | server.c | 42 |
1 files changed, 27 insertions, 15 deletions
@@ -85,9 +85,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); @@ -672,10 +670,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)++; @@ -718,17 +716,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)++; @@ -910,9 +923,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(); |