about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2003-02-14 19:03:08 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2003-02-14 19:03:08 +0000
commit06d25a35b0ee33b6cabe740321310ae0de61144d (patch)
tree25fe0e885fbd2ea6749477940b92c6b2b0dbfd44
parenta7e6deb69e0da03d7f4f050ed2eb172c80df0144 (diff)
downloadzsh-06d25a35b0ee33b6cabe740321310ae0de61144d.tar.gz
zsh-06d25a35b0ee33b6cabe740321310ae0de61144d.tar.xz
zsh-06d25a35b0ee33b6cabe740321310ae0de61144d.zip
18243: Nasty tty poll fix for Solaris
-rw-r--r--ChangeLog3
-rw-r--r--Src/Zle/zle_main.c47
2 files changed, 41 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index b1b3f9b8e..331fceba5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2003-02-14  Peter Stephenson  <pws@csr.com>
 
+	* 18243: Src/Zle/zle_main.c: On Solaris, poll the tty for
+	typeahead before selecting.
+
 	* modified from 18236: zshconfig.ac, Etc/MACHINES: Attempt to fix
 	HP-UX problem with curses, which apparently failed; however, it is
 	documented in MACHINES.
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 0e63bf5b1..d73d63eed 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -348,13 +348,12 @@ raw_getkey(int keytmout, char *cptr)
 {
     long exp100ths;
     int ret;
+#ifdef HAS_TIO
+    struct ttyinfo ti;
+#endif
 #ifndef HAVE_POLL
 # ifdef HAVE_SELECT
     fd_set foofd;
-# else
-#  ifdef HAS_TIO
-    struct ttyinfo ti;
-#  endif
 # endif
 #endif
 
@@ -379,9 +378,40 @@ raw_getkey(int keytmout, char *cptr)
 	    int i, errtry = 0, selret;
 # ifdef HAVE_POLL
 	    int poll_timeout;
-	    int nfds = keytmout ? 1 : 1 + nwatch;
+	    int nfds;
+	    struct pollfd *fds;
+# else
+	    int fdmax;
+	    struct timeval *tvptr;
+	    struct timeval expire_tv;
+# endif
+# if defined(HAS_TIO) && defined(sun)
+	    /*
+	     * Yes, I know this is complicated.  Yes, I know we
+	     * already have three bits of code to poll the terminal
+	     * down below.  No, I don't want to do this either.
+	     * However, it turns out on certain OSes, specifically
+	     * Solaris, that you can't poll typeahead for love nor
+	     * money without actually trying to read it.  But
+	     * if we are trying to select (and we need to if we
+	     * are watching other fd's) we won't pick that up.
+	     * So we just try and read it without blocking in
+	     * the time-honoured (i.e. absurdly baroque) termios
+	     * fashion.
+	     */
+	    gettyinfo(&ti);
+	    ti.tio.c_cc[VMIN] = 0;
+	    settyinfo(&ti);
+	    ret = read(SHTTY, cptr, 1);
+	    ti.tio.c_cc[VMIN] = 1;
+	    settyinfo(&ti);
+	    if (ret > 0)
+		return 1;
+# endif
+# ifdef HAVE_POLL
+	    nfds = keytmout ? 1 : 1 + nwatch;
 	    /* First pollfd is SHTTY, following are the nwatch fds */
-	    struct pollfd *fds = zalloc(sizeof(struct pollfd) * nfds);
+	    fds = zalloc(sizeof(struct pollfd) * nfds);
 	    if (exp100ths)
 		poll_timeout = exp100ths * 10;
 	    else
@@ -400,9 +430,8 @@ raw_getkey(int keytmout, char *cptr)
 		}
 	    }
 # else
-	    int fdmax = SHTTY;
-	    struct timeval *tvptr = NULL;
-	    struct timeval expire_tv;
+	    fdmax = SHTTY;
+	    tvptr = NULL;
 	    if (exp100ths) {
 		expire_tv.tv_sec = exp100ths / 100;
 		expire_tv.tv_usec = (exp100ths % 100) * 10000L;