From 2c2389fe3097f441464402e7c8b07fb6178f0caa Mon Sep 17 00:00:00 2001 From: "zodiac@gmail.com" Date: Sat, 2 Oct 2010 01:54:29 +0000 Subject: [PATCH] Some more research on the web suggests the Apple ships their operating systems with an implementation of poll() that isn't completely POSIX compliant. We now fall back on calling select() instead. That's not our first choice, but it is presumably the best that MacOS X can do. git-svn-id: https://shellinabox.googlecode.com/svn/trunk@236 0da03de8-d603-11dd-86c2-0f8696b7b6f9 --- config.h | 2 +- configure | 2 +- configure.ac | 2 +- demo/vt100.js | 2 +- libhttp/server.c | 63 ++++++++++++++++++++++++++++++++++- shellinabox/shell_in_a_box.js | 2 +- shellinabox/vt100.js | 2 +- 7 files changed, 68 insertions(+), 7 deletions(-) diff --git a/config.h b/config.h index 2d28122..8e63c44 100644 --- a/config.h +++ b/config.h @@ -174,7 +174,7 @@ #define STDC_HEADERS 1 /* Most recent revision number in the version control system */ -#define VCS_REVISION "235" +#define VCS_REVISION "236" /* Version number of package */ #define VERSION "2.10" diff --git a/configure b/configure index 9329b65..27505ad 100755 --- a/configure +++ b/configure @@ -2328,7 +2328,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -VCS_REVISION=235 +VCS_REVISION=236 cat >>confdefs.h <<_ACEOF diff --git a/configure.ac b/configure.ac index 72590df..ae02914 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.57) dnl This is the one location where the authoritative version number is stored AC_INIT(shellinabox, 2.10, markus@shellinabox.com) -VCS_REVISION=235 +VCS_REVISION=236 AC_SUBST(VCS_REVISION) AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}", [Most recent revision number in the version control system]) diff --git a/demo/vt100.js b/demo/vt100.js index 74607e5..cd02a14 100644 --- a/demo/vt100.js +++ b/demo/vt100.js @@ -2402,7 +2402,7 @@ VT100.prototype.toggleCursorBlinking = function() { }; VT100.prototype.about = function() { - alert("VT100 Terminal Emulator " + "2.10 (revision 235)" + + alert("VT100 Terminal Emulator " + "2.10 (revision 236)" + "\nCopyright 2008-2010 by Markus Gutschke\n" + "For more information check http://shellinabox.com"); }; diff --git a/libhttp/server.c b/libhttp/server.c index d0ab1c7..b7e2d03 100644 --- a/libhttp/server.c +++ b/libhttp/server.c @@ -76,6 +76,67 @@ // API should be used, instead. #define MAX_PAYLOAD_LENGTH (64<<10) + +#if defined(__APPLE__) && defined(__MACH__) +// While MacOS X does ship with an implementation of poll(), this +// implementation is apparently known to be broken and does not comply +// with POSIX standards. Fortunately, the operating system is not entirely +// unable to check for input events. We can fall back on calling select() +// instead. This is generally not desirable, as it is less efficient and +// has a compile-time restriction on the maximum number of file +// descriptors. But on MacOS X, that's the best we can do. + +int x_poll(struct pollfd *fds, nfds_t nfds, int timeout) { + fd_set r, w, x; + FD_ZERO(&r); + FD_ZERO(&w); + FD_ZERO(&x); + int maxFd = -1; + for (int i = 0; i < nfds; ++i) { + if (fds[i].fd > maxFd) { + maxFd = fds[i].fd; + } else if (fds[i].fd < 0) { + continue; + } + if (fds[i].events & POLLIN) { + FD_SET(fds[i].fd, &r); + } + if (fds[i].events & POLLOUT) { + FD_SET(fds[i].fd, &w); + } + if (fds[i].events & POLLPRI) { + FD_SET(fds[i].fd, &x); + } + } + struct timeval tmoVal = { 0 }, *tmo; + if (timeout < 0) { + tmo = NULL; + } else { + tmoVal.tv_sec = timeout / 1000; + tmoVal.tv_usec = (timeout % 1000) * 1000; + tmo = &tmoVal; + } + int numRet = select(maxFd + 1, &r, &w, &x, tmo); + for (int i = 0, n = numRet; i < nfds && n > 0; ++i) { + if (fds[i].fd < 0) { + continue; + } + if (FD_ISSET(fds[i].fd, &x)) { + fds[i].revents = POLLPRI; + } else if (FD_ISSET(fds[i].fd, &r)) { + fds[i].revents = POLLIN; + } else { + fds[i].revents = 0; + } + if (FD_ISSET(fds[i].fd, &w)) { + fds[i].revents |= POLLOUT; + } + } + return numRet; +} +#define poll x_poll +#endif + time_t currentTime; struct PayLoad { @@ -477,7 +538,7 @@ void serverLoop(struct Server *server) { currentTime = time(&lastTime); int isTimeout = timeout >= 0 && timeout/1000 <= lastTime; - if (server->pollFds[0].revents) { + if (eventCount > 0 && server->pollFds[0].revents) { eventCount--; if (server->pollFds[0].revents && POLLIN) { struct sockaddr_in clientAddr; diff --git a/shellinabox/shell_in_a_box.js b/shellinabox/shell_in_a_box.js index c7acd3a..7a6e93e 100644 --- a/shellinabox/shell_in_a_box.js +++ b/shellinabox/shell_in_a_box.js @@ -358,7 +358,7 @@ ShellInABox.prototype.extendContextMenu = function(entries, actions) { }; ShellInABox.prototype.about = function() { - alert("Shell In A Box version " + "2.10 (revision 235)" + + alert("Shell In A Box version " + "2.10 (revision 236)" + "\nCopyright 2008-2010 by Markus Gutschke\n" + "For more information check http://shellinabox.com" + (typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ? diff --git a/shellinabox/vt100.js b/shellinabox/vt100.js index 74607e5..cd02a14 100644 --- a/shellinabox/vt100.js +++ b/shellinabox/vt100.js @@ -2402,7 +2402,7 @@ VT100.prototype.toggleCursorBlinking = function() { }; VT100.prototype.about = function() { - alert("VT100 Terminal Emulator " + "2.10 (revision 235)" + + alert("VT100 Terminal Emulator " + "2.10 (revision 236)" + "\nCopyright 2008-2010 by Markus Gutschke\n" + "For more information check http://shellinabox.com"); };