aboutsummaryrefslogtreecommitdiff
path: root/tmux.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmux.c')
-rw-r--r--tmux.c104
1 files changed, 69 insertions, 35 deletions
diff --git a/tmux.c b/tmux.c
index fcdb187e..902c240f 100644
--- a/tmux.c
+++ b/tmux.c
@@ -1,4 +1,4 @@
-/* $Id: tmux.c,v 1.159 2009-08-10 21:43:34 tcunha Exp $ */
+/* $Id: tmux.c,v 1.160 2009-08-14 21:04:04 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -65,6 +65,7 @@ __dead void usage(void);
char *makesockpath(const char *);
int prepare_unlock(enum msgtype *, void **, size_t *, int);
int prepare_cmd(enum msgtype *, void **, size_t *, int, char **);
+int dispatch_imsg(struct client_ctx *, int *);
#ifndef HAVE_PROGNAME
char *__progname = (char *) "tmux";
@@ -269,14 +270,13 @@ main(int argc, char **argv)
struct cmd *cmd;
struct pollfd pfd;
enum msgtype msg;
- struct hdr hdr;
struct passwd *pw;
- struct msg_print_data printdata;
char *s, *path, *label, *home, *cause, **var;
char cwd[MAXPATHLEN];
void *buf;
size_t len;
int retcode, opt, flags, unlock, cmdflags = 0;
+ int nfds;
unlock = flags = 0;
label = path = NULL;
@@ -502,58 +502,92 @@ main(int argc, char **argv)
retcode = 0;
for (;;) {
- pfd.fd = cctx.srv_fd;
+ pfd.fd = cctx.ibuf.fd;
pfd.events = POLLIN;
- if (BUFFER_USED(cctx.srv_out) > 0)
+ if (cctx.ibuf.w.queued != 0)
pfd.events |= POLLOUT;
- if (poll(&pfd, 1, INFTIM) == -1) {
+ if ((nfds = poll(&pfd, 1, INFTIM)) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
fatal("poll failed");
}
+ if (nfds == 0)
+ continue;
- if (buffer_poll(&pfd, cctx.srv_in, cctx.srv_out) != 0)
- goto out;
+ if (pfd.revents & (POLLERR|POLLHUP|POLLNVAL))
+ fatalx("socket error");
- restart:
- if (BUFFER_USED(cctx.srv_in) < sizeof hdr)
- continue;
- memcpy(&hdr, BUFFER_OUT(cctx.srv_in), sizeof hdr);
- if (BUFFER_USED(cctx.srv_in) < (sizeof hdr) + hdr.size)
- continue;
- buffer_remove(cctx.srv_in, sizeof hdr);
+ if (pfd.revents & POLLIN) {
+ if (dispatch_imsg(&cctx, &retcode) != 0)
+ break;
+ }
+
+ if (pfd.revents & POLLOUT) {
+ if (msgbuf_write(&cctx.ibuf.w) < 0)
+ fatalx("msgbuf_write failed");
+ }
+ }
+
+ options_free(&global_s_options);
+ options_free(&global_w_options);
+
+ return (retcode);
+}
+
+int
+dispatch_imsg(struct client_ctx *cctx, int *retcode)
+{
+ struct imsg imsg;
+ ssize_t n, datalen;
+ struct msg_print_data printdata;
+
+ if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0)
+ fatalx("imsg_read failed");
+
+ for (;;) {
+ if ((n = imsg_get(&cctx->ibuf, &imsg)) == -1)
+ fatalx("imsg_get failed");
+ if (n == 0)
+ return (0);
+ datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
- switch (hdr.type) {
+ switch (imsg.hdr.type) {
case MSG_EXIT:
case MSG_SHUTDOWN:
- goto out;
+ if (datalen != 0)
+ fatalx("bad MSG_EXIT size");
+
+ return (-1);
case MSG_ERROR:
- retcode = 1;
+ *retcode = 1;
/* FALLTHROUGH */
case MSG_PRINT:
- if (hdr.size < sizeof printdata)
+ if (datalen != sizeof printdata)
fatalx("bad MSG_PRINT size");
- buffer_read(cctx.srv_in, &printdata, sizeof printdata);
-
+ memcpy(&printdata, imsg.data, sizeof printdata);
printdata.msg[(sizeof printdata.msg) - 1] = '\0';
+
log_info("%s", printdata.msg);
- goto restart;
+ break;
case MSG_READY:
- retcode = client_main(&cctx);
- goto out;
+ if (datalen != 0)
+ fatalx("bad MSG_READY size");
+
+ *retcode = client_main(cctx);
+ return (-1);
+ case MSG_VERSION:
+ if (datalen != 0)
+ fatalx("bad MSG_VERSION size");
+
+ log_warnx("protocol version mismatch (client %u, "
+ "server %u)", PROTOCOL_VERSION, imsg.hdr.peerid);
+ *retcode = 1;
+ return (-1);
default:
- fatalx("unexpected command");
+ fatalx("unexpected message");
}
- }
-
-out:
- options_free(&global_s_options);
- options_free(&global_w_options);
- close(cctx.srv_fd);
- buffer_destroy(cctx.srv_in);
- buffer_destroy(cctx.srv_out);
-
- return (retcode);
+ imsg_free(&imsg);
+ }
}