diff --git a/TODO b/TODO index 5c98405d..844cdb3f 100644 --- a/TODO +++ b/TODO @@ -44,6 +44,8 @@ -- For 0.1 -------------------------------------------------------------------- - man page +- sort out bell: passing through should be optional, and toolbar should change + window colour or something - commands: refresh client rename sessions @@ -56,4 +58,3 @@ set shell - handle tmux in tmux (check $TMUX and abort) - check for some reqd terminfo caps on startup -- sort out the pause mess diff --git a/client-msg.c b/client-msg.c index bea15246..7942d994 100644 --- a/client-msg.c +++ b/client-msg.c @@ -1,4 +1,4 @@ -/* $Id: client-msg.c,v 1.7 2007-10-04 11:52:02 nicm Exp $ */ +/* $Id: client-msg.c,v 1.8 2007-10-05 14:23:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -51,27 +51,24 @@ client_msg_dispatch(struct client_ctx *cctx, char **error) struct hdr hdr; struct client_msg *msg; u_int i; - int n; - for (;;) { - if (BUFFER_USED(cctx->srv_in) < sizeof hdr) + if (BUFFER_USED(cctx->srv_in) < sizeof hdr) + return (1); + memcpy(&hdr, BUFFER_OUT(cctx->srv_in), sizeof hdr); + if (BUFFER_USED(cctx->srv_in) < (sizeof hdr) + hdr.size) + return (1); + buffer_remove(cctx->srv_in, sizeof hdr); + + for (i = 0; i < NCLIENTMSG; i++) { + msg = client_msg_table + i; + if (msg->type == hdr.type) { + if (msg->fn(&hdr, cctx, error) != 0) + return (-1); return (0); - memcpy(&hdr, BUFFER_OUT(cctx->srv_in), sizeof hdr); - if (BUFFER_USED(cctx->srv_in) < (sizeof hdr) + hdr.size) - return (0); - buffer_remove(cctx->srv_in, sizeof hdr); - - for (i = 0; i < NCLIENTMSG; i++) { - msg = client_msg_table + i; - if (msg->type == hdr.type) { - if ((n = msg->fn(&hdr, cctx, error)) != 0) - return (n); - break; - } } - if (i == NCLIENTMSG) - fatalx("unexpected message"); } + if (i == NCLIENTMSG) + fatalx("unexpected message"); } int @@ -88,7 +85,10 @@ client_msg_fn_pause( { if (hdr->size != 0) fatalx("bad MSG_PAUSE size"); - return (1); + + cctx->flags |= CCTX_PAUSE; + + return (0); } int @@ -106,24 +106,24 @@ client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error) int client_msg_fn_exit( - struct hdr *hdr, unused struct client_ctx *cctx, char **error) + struct hdr *hdr, unused struct client_ctx *cctx, unused char **error) { if (hdr->size != 0) fatalx("bad MSG_EXIT size"); - *error = xstrdup(""); + cctx->flags |= CCTX_EXIT; return (-1); } int client_msg_fn_detach( - struct hdr *hdr, unused struct client_ctx *cctx, char **error) + struct hdr *hdr, unused struct client_ctx *cctx, unused char **error) { if (hdr->size != 0) fatalx("bad MSG_DETACH size"); - *error = NULL; + cctx->flags |= CCTX_DETACH; return (-1); } diff --git a/client.c b/client.c index 889ebf20..c51df390 100644 --- a/client.c +++ b/client.c @@ -1,4 +1,4 @@ -/* $Id: client.c,v 1.13 2007-10-04 19:03:51 nicm Exp $ */ +/* $Id: client.c,v 1.14 2007-10-05 14:23:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -126,7 +126,7 @@ client_main(struct client_ctx *cctx) { struct pollfd pfds[2]; char *error; - int n; + int timeout; logfile("client"); setproctitle("client"); @@ -135,8 +135,8 @@ client_main(struct client_ctx *cctx) if ((cctx->loc_fd = local_init(&cctx->loc_in, &cctx->loc_out)) == -1) return (1); - n = 0; error = NULL; + timeout = INFTIM; while (!sigterm) { if (sigwinch) client_handle_winch(cctx); @@ -150,7 +150,7 @@ client_main(struct client_ctx *cctx) if (BUFFER_USED(cctx->loc_out) > 0) pfds[1].events |= POLLOUT; - if (poll(pfds, 2, INFTIM) == -1) { + if (poll(pfds, 2, timeout) == -1) { if (errno == EAGAIN || errno == EINTR) continue; fatal("poll failed"); @@ -161,32 +161,48 @@ client_main(struct client_ctx *cctx) if (buffer_poll(&pfds[1], cctx->loc_in, cctx->loc_out) != 0) goto local_dead; - /* XXX Output flushed; pause if required. */ - if (n) - usleep(750000); - /* XXX XXX special return code for pause? or flag in cctx? */ - if ((n = client_process_local(cctx, &error)) == -1) - break; - if ((n = client_msg_dispatch(cctx, &error)) == -1) - break; - } - - local_done(); - - if (error != NULL) { - if (*error == '\0') { - printf("[exited]\n"); - return (0); + if (cctx->flags & CCTX_PAUSE) { + usleep(750000); + cctx->flags = 0; + } + + if (client_process_local(cctx, &error) == -1) + goto out; + + switch (client_msg_dispatch(cctx, &error)) { + case -1: + goto out; + case 0: + /* May be more in buffer, don't let poll block. */ + timeout = 0; + break; + default: + /* Out of data, poll may block. */ + timeout = INFTIM; + break; } - printf("[error: %s]\n", error); - return (1); } - if (sigterm) { - printf("[terminated]\n"); - return (1); + +out: + local_done(); + + if (sigterm) { + printf("[terminated]\n"); + return (1); + } + + if (cctx->flags & CCTX_EXIT) { + printf("[exited]\n"); + return (0); } - printf("[detached]\n"); - return (0); + + if (cctx->flags & CCTX_DETACH) { + printf("[detached]\n"); + return (0); + } + + printf("[error: %s]\n", error); + return (1); server_dead: local_done(); diff --git a/tmux.h b/tmux.h index 0100f042..147be57b 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.50 2007-10-04 22:04:01 nicm Exp $ */ +/* $Id: tmux.h,v 1.51 2007-10-05 14:23:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -453,6 +453,11 @@ struct client_ctx { int loc_fd; struct buffer *loc_in; struct buffer *loc_out; + +#define CCTX_PAUSE 0x1 +#define CCTX_DETACH 0x2 +#define CCTX_EXIT 0x4 + int flags; }; /* Key/command line command. */