From 33aa9315414dca1218b3c88b0c5ffc89d4379974 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 28 Aug 2008 17:45:30 +0000 Subject: [PATCH] Support OS X by moving to gettimeofday(2) and adding poll compat from OpenSSH. --- CHANGES | 8 ++- GNUmakefile | 8 +-- NOTES | 5 +- TODO | 2 +- arg.c | 10 ++-- buffer-poll.c | 5 +- cmd-list-sessions.c | 6 ++- cmd.c | 10 ++-- compat/bsd-poll.c | 123 ++++++++++++++++++++++++++++++++++++++++++++ compat/bsd-poll.h | 61 ++++++++++++++++++++++ paste.c | 12 ++--- server-fn.c | 16 +++--- server.c | 19 +++---- session.c | 8 +-- status.c | 12 +++-- tmux.c | 3 +- tmux.h | 45 +++++++++------- tty-keys.c | 22 ++++---- 18 files changed, 287 insertions(+), 88 deletions(-) create mode 100644 compat/bsd-poll.c create mode 100644 compat/bsd-poll.h diff --git a/CHANGES b/CHANGES index 3e8c7c03..f0b26990 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +28 August 2008 + +* Support OS X/Darwin thanks to bsd-poll.c from OpenSSH. Also convert + from clock_gettime(2) to gettimeofday(2) as OS X doesn't support the + former; microsecond accuracy will have to be sufficient ;-). + 07 August 2008 * Lose some unused/useless wrapper functions. @@ -640,4 +646,4 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.156 2008-08-07 20:20:49 nicm Exp $ +$Id: CHANGES,v 1.157 2008-08-28 17:45:23 nicm Exp $ diff --git a/GNUmakefile b/GNUmakefile index 83e511dc..dcfc6b9f 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,4 @@ -# $Id: GNUmakefile,v 1.37 2008-07-01 05:43:00 nicm Exp $ +# $Id: GNUmakefile,v 1.38 2008-08-28 17:45:24 nicm Exp $ .PHONY: clean @@ -14,7 +14,7 @@ META?= \002 SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ xmalloc.c xmalloc-debug.c input.c input-keys.c screen.c screen-display.c \ window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \ - key-string.c key-bindings.c resize.c arg.c \ + key-string.c key-bindings.c resize.c arg.c mode-key.c \ cmd.c cmd-generic.c cmd-string.c \ cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \ cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \ @@ -78,9 +78,9 @@ endif ifeq ($(shell uname),Darwin) INCDIRS+= -Icompat -SRCS+= compat/strtonum.c +SRCS+= compat/strtonum.c compat/bsd-poll.c CFLAGS+= -DNO_STRTONUM -DNO_SETRESUID -DNO_SETRESGID -DNO_SETPROCTITLE \ - -DNO_TREE_H + -DNO_TREE_H -DBROKEN_POLL endif ifeq ($(shell uname),Linux) diff --git a/NOTES b/NOTES index fbc17dc7..2a447b9d 100644 --- a/NOTES +++ b/NOTES @@ -59,9 +59,6 @@ There are the following known issues: trivial and as most modern vt220-based software terminals support it currently I have better things to work one. Diffs or ideas how to cleanly emulate cs are welcome. -- Darwin/OS X's poll(2) is broken and doesn't support polling pty(4)s; as tmux - makes heavy use of this and there are no suitable alternatives on the - platform, Darwin and OS X are unfortunately not supported for the present. For debugging, running tmux with -v or -vv will generate server and client log files in the current directory. @@ -73,4 +70,4 @@ welcome. Please email: -- Nicholas Marriott -$Id: NOTES,v 1.35 2008-06-25 19:12:30 nicm Exp $ +$Id: NOTES,v 1.36 2008-08-28 17:45:24 nicm Exp $ diff --git a/TODO b/TODO index a2c29d7e..e681f214 100644 --- a/TODO +++ b/TODO @@ -34,11 +34,11 @@ or tailqs? what would be fastest per-char? - window splitting? - c/p is still borken in some ways -- poll(2) is broken on OS X/Darwin, a workaround for this would be nice - different screen model? layers perhaps? hmm - better mode features: search, back word, forward word, etc - flags to centre screen in window - better terminal emulation (identify, insert mode, some other bits) +- 256 colour terminal support -- For 0.5 -------------------------------------------------------------------- diff --git a/arg.c b/arg.c index d1bc06d6..a1508528 100644 --- a/arg.c +++ b/arg.c @@ -1,4 +1,4 @@ -/* $Id: arg.c,v 1.4 2008-07-23 22:18:06 nicm Exp $ */ +/* $Id: arg.c,v 1.5 2008-08-28 17:45:25 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -46,18 +46,18 @@ struct session * arg_lookup_session(const char *name) { struct session *s, *newest = NULL; - struct timespec *ts; + struct timeval *tv; u_int i; - ts = NULL; + tv = NULL; for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { s = ARRAY_ITEM(&sessions, i); if (s == NULL || fnmatch(name, s->name, 0) != 0) continue; - if (ts == NULL || timespeccmp(&s->ts, ts, >)) { + if (tv == NULL || timercmp(&s->tv, tv, >)) { newest = s; - ts = &s->ts; + tv = &s->tv; } } diff --git a/buffer-poll.c b/buffer-poll.c index d05c22f9..e4a8ae73 100644 --- a/buffer-poll.c +++ b/buffer-poll.c @@ -1,4 +1,4 @@ -/* $Id: buffer-poll.c,v 1.8 2008-07-01 20:35:16 nicm Exp $ */ +/* $Id: buffer-poll.c,v 1.9 2008-08-28 17:45:25 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -19,7 +19,6 @@ #include #include -#include #include #include "tmux.h" @@ -45,8 +44,10 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out) (long) getpid(), pfd->fd, pfd->revents, BUFFER_USED(out), BUFFER_USED(in)); +#ifndef BROKEN_POLL if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP)) return (-1); +#endif if (pfd->revents & POLLIN) { buffer_ensure(in, BUFSIZ); n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in)); diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c index 6b36460c..1b1b20d7 100644 --- a/cmd-list-sessions.c +++ b/cmd-list-sessions.c @@ -1,4 +1,4 @@ -/* $Id: cmd-list-sessions.c,v 1.15 2008-06-05 21:25:00 nicm Exp $ */ +/* $Id: cmd-list-sessions.c,v 1.16 2008-08-28 17:45:25 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -48,6 +48,7 @@ cmd_list_sessions_exec(unused struct cmd *self, struct cmd_ctx *ctx) struct winlink *wl; char *tim; u_int i, n; + time_t t; for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { s = ARRAY_ITEM(&sessions, i); @@ -57,7 +58,8 @@ cmd_list_sessions_exec(unused struct cmd *self, struct cmd_ctx *ctx) n = 0; RB_FOREACH(wl, winlinks, &s->windows) n++; - tim = ctime(&s->ts.tv_sec); + t = s->tv.tv_sec; + tim = ctime(&t); *strchr(tim, '\n') = '\0'; ctx->print(ctx, "%s: %u windows" diff --git a/cmd.c b/cmd.c index 481b3078..0b378e14 100644 --- a/cmd.c +++ b/cmd.c @@ -1,4 +1,4 @@ -/* $Id: cmd.c,v 1.62 2008-07-19 10:07:50 nicm Exp $ */ +/* $Id: cmd.c,v 1.63 2008-08-28 17:45:25 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -304,7 +304,7 @@ struct session * cmd_current_session(struct cmd_ctx *ctx) { struct msg_command_data *data = ctx->msgdata; - struct timespec *ts; + struct timeval *tv; struct session *s, *newest = NULL; u_int i; @@ -327,12 +327,12 @@ cmd_current_session(struct cmd_ctx *ctx) return (s); } - ts = NULL; + tv = NULL; for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { s = ARRAY_ITEM(&sessions, i); - if (s != NULL && (ts == NULL || timespeccmp(&s->ts, ts, >))) { + if (s != NULL && (tv == NULL || timercmp(&s->tv, tv, >))) { newest = ARRAY_ITEM(&sessions, i); - ts = &s->ts; + tv = &s->tv; } } return (newest); diff --git a/compat/bsd-poll.c b/compat/bsd-poll.c new file mode 100644 index 00000000..39da9d9a --- /dev/null +++ b/compat/bsd-poll.c @@ -0,0 +1,123 @@ +/* $Id: bsd-poll.c,v 1.1 2008-08-28 17:45:30 nicm Exp $ */ + +/* + * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* #include "includes.h" */ +#define HAVE_SYS_SELECT_H +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#include + +#if !defined(HAVE_POLL) + +#ifdef HAVE_SYS_SELECT_H +# include +#endif + +#include +#include +#include "bsd-poll.h" + +/* + * A minimal implementation of poll(2), built on top of select(2). + * + * Only supports POLLIN and POLLOUT flags in pfd.events, and POLLIN, POLLOUT + * and POLLERR flags in revents. + * + * Supports pfd.fd = -1 meaning "unused" although it's not standard. + */ + +int +poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + nfds_t i; + int saved_errno, ret, fd, maxfd = 0; + fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL; + size_t nmemb; + struct timeval tv, *tvp = NULL; + + for (i = 0; i < nfds; i++) { + fd = fds[i].fd; + if (fd >= FD_SETSIZE) { + errno = EINVAL; + return -1; + } + maxfd = MAX(maxfd, fd); + } + + nmemb = howmany(maxfd + 1 , NFDBITS); + if ((readfds = calloc(nmemb, sizeof(fd_mask))) == NULL || + (writefds = calloc(nmemb, sizeof(fd_mask))) == NULL || + (exceptfds = calloc(nmemb, sizeof(fd_mask))) == NULL) { + saved_errno = ENOMEM; + ret = -1; + goto out; + } + + /* populate event bit vectors for the events we're interested in */ + for (i = 0; i < nfds; i++) { + fd = fds[i].fd; + if (fd == -1) + continue; + if (fds[i].events & POLLIN) { + FD_SET(fd, readfds); + FD_SET(fd, exceptfds); + } + if (fds[i].events & POLLOUT) { + FD_SET(fd, writefds); + FD_SET(fd, exceptfds); + } + } + + /* poll timeout is msec, select is timeval (sec + usec) */ + if (timeout >= 0) { + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + tvp = &tv; + } + + ret = select(maxfd + 1, readfds, writefds, exceptfds, tvp); + saved_errno = errno; + + /* scan through select results and set poll() flags */ + for (i = 0; i < nfds; i++) { + fd = fds[i].fd; + fds[i].revents = 0; + if (fd == -1) + continue; + if (FD_ISSET(fd, readfds)) { + fds[i].revents |= POLLIN; + } + if (FD_ISSET(fd, writefds)) { + fds[i].revents |= POLLOUT; + } + if (FD_ISSET(fd, exceptfds)) { + fds[i].revents |= POLLERR; + } + } + +out: + if (readfds != NULL) + free(readfds); + if (writefds != NULL) + free(writefds); + if (exceptfds != NULL) + free(exceptfds); + if (ret == -1) + errno = saved_errno; + return ret; +} +#endif diff --git a/compat/bsd-poll.h b/compat/bsd-poll.h new file mode 100644 index 00000000..dcbb9ca4 --- /dev/null +++ b/compat/bsd-poll.h @@ -0,0 +1,61 @@ +/* $OpenBSD: poll.h,v 1.11 2003/12/10 23:10:08 millert Exp $ */ + +/* + * Copyright (c) 1996 Theo de Raadt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* OPENBSD ORIGINAL: sys/sys/poll.h */ + +#if !defined(HAVE_POLL) && !defined(HAVE_POLL_H) +#ifndef _COMPAT_POLL_H_ +#define _COMPAT_POLL_H_ + +typedef struct pollfd { + int fd; + short events; + short revents; +} pollfd_t; + +typedef unsigned int nfds_t; + +#define POLLIN 0x0001 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#if 0 +/* the following are currently not implemented */ +#define POLLPRI 0x0002 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 +#define POLLRDNORM 0x0040 +#define POLLNORM POLLRDNORM +#define POLLWRNORM POLLOUT +#define POLLRDBAND 0x0080 +#define POLLWRBAND 0x0100 +#endif + +#define INFTIM (-1) /* not standard */ + +int poll(struct pollfd *, nfds_t, int); +#endif /* !_COMPAT_POLL_H_ */ +#endif /* !HAVE_POLL_H */ diff --git a/paste.c b/paste.c index 3882a260..29f17b37 100644 --- a/paste.c +++ b/paste.c @@ -1,4 +1,4 @@ -/* $Id: paste.c,v 1.3 2008-06-20 18:45:35 nicm Exp $ */ +/* $Id: paste.c,v 1.4 2008-08-28 17:45:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -17,9 +17,9 @@ */ #include +#include #include -#include #include "tmux.h" @@ -108,8 +108,8 @@ paste_add(struct paste_stack *ps, const char *data, u_int limit) ARRAY_INSERT(ps, 0, pb); pb->data = xstrdup(data); - if (clock_gettime(CLOCK_REALTIME, &pb->ts) != 0) - fatal("clock_gettime"); + if (gettimeofday(&pb->tv, NULL) != 0) + fatal("gettimeofday"); } int @@ -124,8 +124,8 @@ paste_replace(struct paste_stack *ps, u_int idx, const char *data) xfree(pb->data); pb->data = xstrdup(data); - if (clock_gettime(CLOCK_REALTIME, &pb->ts) != 0) - fatal("clock_gettime"); + if (gettimeofday(&pb->tv, NULL) != 0) + fatal("gettimeofday"); return (0); } diff --git a/server-fn.c b/server-fn.c index f766ba38..ba3def83 100644 --- a/server-fn.c +++ b/server-fn.c @@ -1,4 +1,4 @@ -/* $Id: server-fn.c,v 1.49 2008-06-22 22:28:33 nicm Exp $ */ +/* $Id: server-fn.c,v 1.50 2008-08-28 17:45:27 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -17,9 +17,9 @@ */ #include +#include #include -#include #include #include "tmux.h" @@ -27,17 +27,17 @@ void server_set_client_message(struct client *c, const char *msg) { - struct timespec ts; + struct timeval tv; int delay; delay = options_get_number(&c->session->options, "display-time"); - ts.tv_sec = delay / 1000; - ts.tv_nsec = (delay % 1000) * 1000000L; + tv.tv_sec = delay / 1000; + tv.tv_usec = (delay % 1000) * 1000L; c->message_string = xstrdup(msg); - if (clock_gettime(CLOCK_REALTIME, &c->message_timer) != 0) - fatal("clock_gettime"); - timespecadd(&c->message_timer, &ts, &c->message_timer); + if (gettimeofday(&c->message_timer, NULL) != 0) + fatal("gettimeofday"); + timeradd(&c->message_timer, &tv, &c->message_timer); c->tty.flags |= (TTY_NOCURSOR|TTY_FREEZE); c->flags |= CLIENT_STATUS; diff --git a/server.c b/server.c index ca14803c..e9ea3130 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.77 2008-06-29 07:04:30 nicm Exp $ */ +/* $Id: server.c,v 1.78 2008-08-28 17:45:27 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -197,8 +196,10 @@ server_main(const char *srv_path, int srv_fd) log_debug("poll returned %d", nfds); /* Handle server socket. */ +#ifndef BROKEN_POLL if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP)) fatalx("lost server socket"); +#endif if (pfd->revents & POLLIN) { server_accept_client(srv_fd); continue; @@ -377,17 +378,17 @@ void server_check_timers(struct client *c) { struct session *s; - struct timespec ts, ts2; + struct timeval tv, tv2; u_int interval; if (c == NULL || c->session == NULL) return; s = c->session; - if (clock_gettime(CLOCK_REALTIME, &ts) != 0) - fatal("clock_gettime"); + if (gettimeofday(&tv, NULL) != 0) + fatal("gettimeofday"); - if (c->message_string != NULL && timespeccmp(&ts, &c->message_timer, >)) + if (c->message_string != NULL && timercmp(&tv, &c->message_timer, >)) server_clear_client_message(c); if (!options_get_number(&s->options, "status")) @@ -396,9 +397,9 @@ server_check_timers(struct client *c) if (interval == 0) return; - memcpy(&ts2, &ts, sizeof ts2); - ts2.tv_sec -= interval; - if (timespeccmp(&c->status_timer, &ts2, <)) + memcpy(&tv2, &tv, sizeof tv2); + tv2.tv_sec -= interval; + if (timercmp(&c->status_timer, &tv2, <)) c->flags |= CLIENT_STATUS; } diff --git a/session.c b/session.c index b16482e7..e39cd182 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $Id: session.c,v 1.41 2008-06-30 19:11:33 nicm Exp $ */ +/* $Id: session.c,v 1.42 2008-08-28 17:45:27 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -17,10 +17,10 @@ */ #include +#include #include #include -#include #include #include "tmux.h" @@ -115,8 +115,8 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy) u_int i; s = xmalloc(sizeof *s); - if (clock_gettime(CLOCK_REALTIME, &s->ts) != 0) - fatal("clock_gettime failed"); + if (gettimeofday(&s->tv, NULL) != 0) + fatal("gettimeofday"); s->curw = s->lastw = NULL; RB_INIT(&s->windows); TAILQ_INIT(&s->alerts); diff --git a/status.c b/status.c index 0c9fc658..7f2ed916 100644 --- a/status.c +++ b/status.c @@ -1,4 +1,4 @@ -/* $Id: status.c,v 1.42 2008-06-27 17:32:24 nicm Exp $ */ +/* $Id: status.c,v 1.43 2008-08-28 17:45:27 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -17,10 +17,10 @@ */ #include +#include #include #include -#include #include "tmux.h" @@ -40,14 +40,15 @@ status_redraw(struct client *c) size_t size, start, width; u_char attr, colr; struct tm *tm; + time_t t; int larrow, rarrow; if (c->sy == 0 || !options_get_number(&s->options, "status")) goto off; larrow = rarrow = 0; - if (clock_gettime(CLOCK_REALTIME, &c->status_timer) != 0) - fatal("clock_gettime failed"); + if (gettimeofday(&c->status_timer, NULL) != 0) + fatal("gettimeofday"); colr = options_get_number(&s->options, "status-bg") + (options_get_number(&s->options, "status-fg") << 4); @@ -55,7 +56,8 @@ status_redraw(struct client *c) if (yy == 0) goto blank; - tm = localtime(&(c->status_timer.tv_sec)); + t = c->status_timer.tv_sec; + tm = localtime(&t); left = options_get_string(&s->options, "status-left"); strftime(lbuf, sizeof lbuf, left, tm); llen = strlen(lbuf); diff --git a/tmux.c b/tmux.c index 48726d4b..605f6854 100644 --- a/tmux.c +++ b/tmux.c @@ -1,4 +1,4 @@ -/* $Id: tmux.c,v 1.73 2008-08-08 17:35:42 nicm Exp $ */ +/* $Id: tmux.c,v 1.74 2008-08-28 17:45:27 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/tmux.h b/tmux.h index c2d5c0c7..ac8d3734 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.181 2008-08-08 17:35:42 nicm Exp $ */ +/* $Id: tmux.h,v 1.182 2008-08-28 17:45:27 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -25,6 +25,7 @@ #define RB_AUGMENT(x) do {} while (0) #include +#include #ifndef NO_QUEUE_H #include @@ -38,9 +39,15 @@ #include "compat/tree.h" #endif +#ifndef BROKEN_POLL +#include +#else +#undef HAVE_POLL +#include "compat/bsd-poll.h" +#endif + #include #include -#include #include #include #include @@ -70,21 +77,21 @@ extern const char *__progname; #define __packed __attribute__ ((__packed__)) #endif -#ifndef timespeccmp -#define timespeccmp(tsp, usp, cmp) \ - (((tsp)->tv_sec == (usp)->tv_sec) ? \ - ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ - ((tsp)->tv_sec cmp (usp)->tv_sec)) +#ifndef timercmp +#define timercmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) #endif -#ifndef timespecadd -#define timespecadd(tsp, usp, vsp) \ +#ifndef timeradd +#define timeradd(tvp, uvp, vvp) \ do { \ - (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \ - (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \ - if ((vsp)->tv_nsec >= 1000000000L) { \ - (vsp)->tv_sec++; \ - (vsp)->tv_nsec -= 1000000000L; \ + (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ + if ((vvp)->tv_usec >= 1000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= 1000000; \ } \ } while (0) #endif @@ -616,7 +623,7 @@ struct options { /* Paste buffer. */ struct paste_buffer { char *data; - struct timespec ts; + struct timeval tv; }; ARRAY_DECL(paste_stack, struct paste_buffer *); @@ -630,7 +637,7 @@ struct session_alert { struct session { char *name; - struct timespec ts; + struct timeval tv; u_int sx; u_int sy; @@ -688,7 +695,7 @@ struct tty { #define TTY_ESCAPE 0x4 int flags; - struct timespec key_timer; + struct timeval key_timer; size_t ksize; /* maximum key size */ RB_HEAD(tty_keys, tty_key) ktree; @@ -703,7 +710,7 @@ struct client { char *title; struct tty tty; - struct timespec status_timer; + struct timeval status_timer; u_int sx; u_int sy; @@ -716,7 +723,7 @@ struct client { int flags; char *message_string; - struct timespec message_timer; + struct timeval message_timer; char *prompt_string; char *prompt_buffer; diff --git a/tty-keys.c b/tty-keys.c index 6ee4e935..69c52b95 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -1,4 +1,4 @@ -/* $Id: tty-keys.c,v 1.9 2008-07-24 21:42:40 nicm Exp $ */ +/* $Id: tty-keys.c,v 1.10 2008-08-28 17:45:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -17,9 +17,9 @@ */ #include +#include #include -#include #include "tmux.h" @@ -299,7 +299,7 @@ tty_keys_next(struct tty *tty, int *code) { struct tty_key *tk; size_t size; - struct timespec ts; + struct timeval tv; size = BUFFER_USED(tty->in); if (size == 0) @@ -324,20 +324,20 @@ tty_keys_next(struct tty *tty, int *code) /* Escape but no key string. If the timer isn't started, start it. */ if (!(tty->flags & TTY_ESCAPE)) { - ts.tv_sec = 0; - ts.tv_nsec = 500 * 1000000L; - if (clock_gettime(CLOCK_REALTIME, &tty->key_timer) != 0) - fatal("clock_gettime"); - timespecadd(&tty->key_timer, &ts, &tty->key_timer); + tv.tv_sec = 0; + tv.tv_usec = 500 * 1000L; + if (gettimeofday(&tty->key_timer, NULL) != 0) + fatal("gettimeofday"); + timeradd(&tty->key_timer, &tv, &tty->key_timer); tty->flags |= TTY_ESCAPE; return (1); } /* Otherwise, if the timer hasn't expired, wait. */ - if (clock_gettime(CLOCK_REALTIME, &ts) != 0) - fatal("clock_gettime"); - if (!timespeccmp(&tty->key_timer, &ts, >)) + if (gettimeofday(&tv, NULL) != 0) + fatal("gettimeofday"); + if (!timercmp(&tty->key_timer, &tv, >)) return (1); tty->flags &= ~TTY_ESCAPE;