Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: read timeouts



OK, I've retrieved the failure notification from the patch I sent from
home to the wrong address and extracted the patch.

I've had this lying around here for ages and have finally decided I'm
not doing anything else to it.

`read -t <num>' now specifies a timeout.  The <num> is optional and
defaults to 0 for compatiblity with the old code.  The timeout is in
seconds as in bash, but here can be a floating point number (like
$SECONDS now can).

This leaves zselect a bit out on a limb --- it takes 100ths of a
seconds, which was for compatibility with $KEYTMOUT, which came long
before there was floating point support.

Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.54
diff -u -r1.54 builtins.yo
--- Doc/Zsh/builtins.yo	20 Nov 2002 12:37:45 -0000	1.54
+++ Doc/Zsh/builtins.yo	5 Feb 2003 10:59:14 -0000
@@ -824,8 +824,8 @@
 alias(r)(fc -e -)
 findex(read)
 vindex(IFS, use of)
-ifzman(xitem(tt(read) [ tt(-rszpqAclneEt) ] [ tt(-k) [ var(num) ] ]))
-item(ifnzman(tt(read) [ tt(-rszpqAclneEt) ] [ tt(-k) [ var(num) ] ]) [ tt(-u)var(n) ] [ var(name)[tt(?)var(prompt)] ] [ var(name) ...  ])(
+ifzman(xitem(tt(read) [ tt(-rszpqAclneE) ] [ tt(-t) [ var(num) ] ] [ tt(-k) [ var(num) ] ]))
+item(ifnzman(tt(read) [ tt(-rszpqAclneE) ] [ tt(-t) [ var(num) ] ] [ tt(-k) [ var(num) ] ]) [ tt(-u)var(n) ] [ var(name)[tt(?)var(prompt)] ] [ var(name) ...  ])(
 vindex(REPLY, use of)
 vindex(reply, use of)
 Read one line and break it into fields using the characters
@@ -899,21 +899,28 @@
 item(tt(-p))(
 Input is read from the coprocess.
 )
-item(tt(-t))(
-Test if input is available before attempting to read; if none is, return
-status 1 and do not set any variables.  This is not available when reading
-from the editor buffer with tt(-z), when called from within completion
-with tt(-c) or tt(-l), with tt(-q) which clears the input queue before
-reading, or within zle where other mechanisms should be used to test for
-input.
+item(tt(-t) [ var(num) ])(
+Test if input is available before attempting to read.  If var(num)
+is present, it must begin with a digit and will be evaluated
+to give a number of seconds, which may be a floating point number;
+in this case the read times out if input is not available within this
+time.  If var(num) is not present, it is taken to be zero, so that
+tt(read) returns immediately if no input is available.
+If no input is available, return status 1 and do not set any variables.
+ifzman( )
+This option is not available when reading from the editor buffer with
+tt(-z), when called from within completion with tt(-c) or tt(-l), with
+tt(-q) which clears the input queue before reading, or within zle where
+other mechanisms should be used to test for input.
 ifzman( )
 Note that read does not attempt to alter the input processing mode.  The
 default mode is canonical input, in which an entire line is read at a time,
 so usually `tt(read -t)' will not read anything until an entire line has
 been typed.  However, when reading from the terminal with tt(-k)
-this is automatically handled; note that only availability of the first
-character is tested, so that e.g. `tt(read -t -k 2)' can still block on the
-second character.
+input is processed one key at a time; in this case, only availability of
+the first character is tested, so that e.g. `tt(read -t -k 2)' can still
+block on the second character.  Use two instances of `tt(read -t -k)' if
+this is not what is wanted.
 )
 enditem()
 If the first argument contains a `tt(?)', the remainder of this
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.93
diff -u -r1.93 builtin.c
--- Src/builtin.c	18 Dec 2002 16:57:02 -0000	1.93
+++ Src/builtin.c	5 Feb 2003 10:59:14 -0000
@@ -106,7 +106,7 @@
     BUILTIN("pushln", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"),
     BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
     BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "nrl", NULL),
-    BUILTIN("read", 0, bin_read, 0, -1, 0, "cek:%lnpqrstzu:AE", NULL),
+    BUILTIN("read", 0, bin_read, 0, -1, 0, "cek:%lnpqrst:%zu:AE", NULL),
     BUILTIN("readonly", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%lptux", "r"),
     BUILTIN("rehash", 0, bin_hash, 0, 0, 0, "df", "r"),
     BUILTIN("return", BINF_PSPECIAL, bin_break, 0, 1, BIN_RETURN, NULL, NULL),
@@ -4189,16 +4189,30 @@
     } else
 	readfd = izle = 0;
 
-    if (OPT_ISSET(ops,'t') && 
-	!read_poll(readfd, &readchar, keys && !zleactive)) {
-	if (OPT_ISSET(ops,'k') && !zleactive && !isem)
-	    settyinfo(&shttyinfo);
-	if (haso) {
-	    fclose(shout);
-	    shout = oshout;
-	    SHTTY = -1;
+    if (OPT_ISSET(ops,'t')) {
+	zlong timeout = 0;
+	if (OPT_HASARG(ops,'t')) {
+	    mnumber mn = zero_mnumber;
+	    mn = matheval(OPT_ARG(ops,'t'));
+	    if (errflag)
+		return 1;
+	    if (mn.type == MN_FLOAT) {
+		mn.u.d *= 1e6;
+		timeout = (zlong)mn.u.d;
+	    } else {
+		timeout = (zlong)mn.u.l * (zlong)1000000;
+	    }
+	}
+	if (!read_poll(readfd, &readchar, keys && !zleactive, timeout)) {
+	    if (OPT_ISSET(ops,'k') && !zleactive && !isem)
+		settyinfo(&shttyinfo);
+	    if (haso) {
+		fclose(shout);
+		shout = oshout;
+		SHTTY = -1;
+	    }
+	    return 1;
 	}
-	return 1;
     }
     if (OPT_ISSET(ops,'s') && SHTTY != -1) {
 	struct ttyinfo ti;
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.43
diff -u -r1.43 utils.c
--- Src/utils.c	5 Feb 2003 10:56:56 -0000	1.43
+++ Src/utils.c	5 Feb 2003 10:59:14 -0000
@@ -1332,7 +1332,7 @@
 
 /**/
 mod_export int
-read_poll(int fd, int *readchar, int polltty)
+read_poll(int fd, int *readchar, int polltty, zlong microseconds)
 {
     int ret = -1;
     long mode = -1;
@@ -1374,6 +1374,8 @@
 	gettyinfo(&ti);
 	if ((polltty = ti.tio.c_cc[VMIN])) {
 	    ti.tio.c_cc[VMIN] = 0;
+	    /* termios timeout is 10ths of a second */
+	    ti.tio.c_cc[VTIME] = (int) (microseconds / (zlong)100000);
 	    settyinfo(&ti);
 	}
     }
@@ -1381,7 +1383,8 @@
     polltty = 0;
 #endif
 #ifdef HAVE_SELECT
-    expire_tv.tv_sec = expire_tv.tv_usec = 0;
+    expire_tv.tv_sec = (int) (microseconds / (zlong)1000000);
+    expire_tv.tv_usec = microseconds % (zlong)10000000;
     FD_ZERO(&foofd);
     FD_SET(fd, &foofd);
     ret = select(fd+1, (SELECT_ARG_2_T) &foofd, NULL, NULL, &expire_tv);
@@ -1407,6 +1410,7 @@
 #ifdef HAS_TIO
     if (polltty) {
 	ti.tio.c_cc[VMIN] = 1;
+	ti.tio.c_cc[VTIME] = 0;
 	settyinfo(&ti);
     }
 #endif
Index: Src/Modules/zpty.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/zpty.c,v
retrieving revision 1.26
diff -u -r1.26 zpty.c
--- Src/Modules/zpty.c	27 Aug 2002 21:10:34 -0000	1.26
+++ Src/Modules/zpty.c	5 Feb 2003 10:59:14 -0000
@@ -632,7 +632,7 @@
 	if (p->fin)
 	    return 2;
 	if (OPT_ISSET(ops,'t') && p->read == -1 &&
-	    !read_poll(p->fd, &p->read, 0))
+	    !read_poll(p->fd, &p->read, 0, 0))
 	    return 1;
 
 	return (OPT_ISSET(ops,'r') ?

-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR Ltd., Science Park, Milton Road,
Cambridge, CB4 0WH, UK                          Tel: +44 (0)1223 692070


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************



Messages sorted by: Reverse Date, Date, Thread, Author