summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Src/Zle/zle_keymap.c2
-rw-r--r--Src/Zle/zle_main.c27
-rw-r--r--Src/Zle/zle_misc.c2
-rw-r--r--Src/Zle/zle_vi.c2
-rw-r--r--Src/builtin.c51
-rw-r--r--Src/init.c2
7 files changed, 62 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 691ff3740..7b7e3b913 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2008-04-03  Peter Stephenson  <pws@csr.com>
 
+	* 24786: Src/builtin.c, Src/init.c, Src/zle/zle_keymap.c,
+	Src/Zle/zle_main.c, Src/Zle/zle_misc.c, Src/Zle/zle_vi.c:
+	handle read -t properly in zle by passing down timeout
+	to getbyte().
+
 	* 24782, plus a couple of fixes: Doc/Zsh/zle.yo,
 	Functions/Zle/read-from-minibuffer,
 	Functions/Zle/replace-string-again, Src/zsh.h, Src/Zle/zle.h,
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 454e26f16..3c8cc4d9d 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -1363,7 +1363,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
 static int
 getkeybuf(int w)
 {
-    int c = getbyte(w, NULL);
+    int c = getbyte((long)w, NULL);
 
     if(c < 0)
 	return EOF;
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 5c36f4557..430c4345a 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -451,13 +451,22 @@ struct ztmout {
 /*
  * See if we need a timeout either for a key press or for a
  * timed function.
+ *
+ * do_keytmout is passed down from getbyte() here.  If it is positive,
+ * we the keytimeout value, which is in 100ths of a second (directly set
+ * from the parameter).  If it is negative, we use -(do_keytmout+1)
+ * (i.e. the one's complement, to allow a zero value to be set).  This
+ * is only used when calling into zle from outside to specify an
+ * explicit timeout.  This is also in 100ths of a second.
  */
 
 static void
-calc_timeout(struct ztmout *tmoutp, int do_keytmout)
+calc_timeout(struct ztmout *tmoutp, long do_keytmout)
 {
-    if (do_keytmout && keytimeout > 0) {
-	if (keytimeout > ZMAXTIMEOUT * 100 /* 24 days for a keypress???? */)
+    if (do_keytmout && (keytimeout > 0 || do_keytmout < 0)) {
+	if (do_keytmout < 0)
+	    tmoutp->exp100ths = (time_t)-do_keytmout;
+	else if (keytimeout > ZMAXTIMEOUT * 100 /* 24 days for a keypress???? */)
 	    tmoutp->exp100ths = ZMAXTIMEOUT * 100;
 	else
 	    tmoutp->exp100ths = keytimeout;
@@ -501,8 +510,10 @@ calc_timeout(struct ztmout *tmoutp, int do_keytmout)
     }
 }
 
+/* see calc_timeout for use of do_keytmout */
+
 static int
-raw_getbyte(int do_keytmout, char *cptr)
+raw_getbyte(long do_keytmout, char *cptr)
 {
     int ret;
     struct ztmout tmout;
@@ -785,9 +796,11 @@ raw_getbyte(int do_keytmout, char *cptr)
     return ret;
 }
 
+/* see calc_timeout for use of do_keytmout */
+
 /**/
 mod_export int
-getbyte(int do_keytmout, int *timeout)
+getbyte(long do_keytmout, int *timeout)
 {
     char cc;
     unsigned int ret;
@@ -899,7 +912,7 @@ getbyte(int do_keytmout, int *timeout)
 mod_export ZLE_INT_T
 getfullchar(int do_keytmout)
 {
-    int inchar = getbyte(do_keytmout, NULL);
+    int inchar = getbyte((long)do_keytmout, NULL);
 
 #ifdef MULTIBYTE_SUPPORT
     return getrestchar(inchar);
@@ -962,7 +975,7 @@ getrestchar(int inchar)
 	 * arrive together.  If we don't do this the input can
 	 * get stuck if an invalid byte sequence arrives.
 	 */
-	inchar = getbyte(1, &timeout);
+	inchar = getbyte(1L, &timeout);
 	/* getbyte deliberately resets lastchar_wide_valid */
 	lastchar_wide_valid = 1;
 	if (inchar == EOF) {
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index f4c32e454..6a42f157e 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -619,7 +619,7 @@ universalargument(char **args)
      *
      * Hence for now this remains byte-by-byte.
      */
-    while ((gotk = getbyte(0, NULL)) != EOF) {
+    while ((gotk = getbyte(0L, NULL)) != EOF) {
 	if (gotk == '-' && !digcnt) {
 	    minus = -1;
 	    digcnt++;
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index 2549af80c..3e8e5ccec 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -108,7 +108,7 @@ vigetkey(void)
     char m[3], *str;
     Thingy cmd;
 
-    if (getbyte(0, NULL) == EOF)
+    if (getbyte(0L, NULL) == EOF)
 	return ZLEEOF;
 
     m[0] = lastchar;
diff --git a/Src/builtin.c b/Src/builtin.c
index c70d4de69..75dd19d54 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -4739,6 +4739,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
     int readchar = -1, val, resettty = 0;
     struct ttyinfo saveti;
     char d;
+    long izle_timeout = 0;
 #ifdef MULTIBYTE_SUPPORT
     wchar_t delim = L'\n', wc;
     mbstate_t mbs;
@@ -4900,18 +4901,32 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
 		timeout = (zlong)mn.u.l * (zlong)1000000;
 	    }
 	}
-	if (readfd == -1 ||
-	    !read_poll(readfd, &readchar, keys && !zleactive, timeout)) {
-	    if (OPT_ISSET(ops,'k') && !zleactive && !isem)
-		settyinfo(&shttyinfo);
-	    else if (resettty && SHTTY != -1)
-	      settyinfo(&saveti);
-	    if (haso) {
-		fclose(shout);
-		shout = oshout;
-		SHTTY = -1;
+	if (izle) {
+	    /*
+	     * Timeout is in 100ths of a second rather than us.
+	     * See calc_timeout() in zle_main for format of this.
+	     */
+	    timeout = -(timeout/(zlong)10000 + 1L);
+	    izle_timeout = (long)timeout;
+#ifdef LONG_MAX
+	    /* saturate if range exceeded */
+	    if ((zlong)izle_timeout != timeout)
+		izle_timeout = LONG_MAX;
+#endif
+	} else {
+	    if (readfd == -1 ||
+		!read_poll(readfd, &readchar, keys && !zleactive, timeout)) {
+		if (OPT_ISSET(ops,'k') && !zleactive && !isem)
+		    settyinfo(&shttyinfo);
+		else if (resettty && SHTTY != -1)
+		    settyinfo(&saveti);
+		if (haso) {
+		    fclose(shout);
+		    shout = oshout;
+		    SHTTY = -1;
+		}
+		return 1;
 	    }
-	    return 1;
 	}
     }
 
@@ -4927,7 +4942,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
 
 	do {
 	    if (izle) {
-		if ((val = getkeyptr(0, NULL)) < 0) {
+		if ((val = getkeyptr(izle_timeout, NULL)) < 0) {
 		    eof = 1;
 		    break;
 		}
@@ -5033,7 +5048,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
 #ifdef MULTIBYTE_SUPPORT
 	    int key;
 
-	    while ((key = getkeyptr(0, NULL)) >= 0) {
+	    while ((key = getkeyptr(izle_timeout, NULL)) >= 0) {
 		char c = (char)key;
 		/*
 		 * If multibyte, it can't be y, so we don't care
@@ -5044,7 +5059,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
 		    break;
 	    }
 #else
-	    int key = getkeyptr(0, NULL);
+	    int key = getkeyptr(izle_timeout, NULL);
 #endif
 
 	    readbuf[0] = (key == 'y' ? 'y' : 'n');
@@ -5087,7 +5102,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
 #endif
 	/* get input, a character at a time */
 	while (!gotnl) {
-	    c = zread(izle, &readchar);
+	    c = zread(izle, &readchar, izle_timeout);
 	    /* \ at the end of a line indicates a continuation *
 	     * line, except in raw mode (-r option)            */
 #ifdef MULTIBYTE_SUPPORT
@@ -5277,7 +5292,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
     if (!gotnl) {
 	sigset_t s = child_unblock();
 	for (;;) {
-	    c = zread(izle, &readchar);
+	    c = zread(izle, &readchar, izle_timeout);
 #ifdef MULTIBYTE_SUPPORT
 	    if (c == EOF) {
 		/* not waiting to be completed any more */
@@ -5418,13 +5433,13 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
 
 /**/
 static int
-zread(int izle, int *readchar)
+zread(int izle, int *readchar, long izle_timeout)
 {
     char cc, retry = 0;
     int ret;
 
     if (izle) {
-	int c = getkeyptr(0, NULL);
+	int c = getkeyptr(izle_timeout, NULL);
 
 	return (c < 0 ? EOF : c);
     }
diff --git a/Src/init.c b/Src/init.c
index a653de7de..d83e6175b 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -82,7 +82,7 @@ mod_export int hasam, hasxn;
 /* Pointer to read-key function from zle */
 
 /**/
-mod_export int (*getkeyptr) _((int, int *));
+mod_export int (*getkeyptr) _((long, int *));
 
 /* SIGCHLD mask */