Date: Sun, 28 Sep 1997 18:47:53 +0930 From: Mike Smith <mike@smith.net.au> To: joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch) Cc: hackers@FreeBSD.ORG Subject: Re: Timeout for sh(1) 'read' ?? Message-ID: <199709280917.SAA05469@word.smith.net.au> In-Reply-To: Your message of "Sun, 28 Sep 1997 08:36:19 %2B0200." <19970928083619.EN11505@uriah.heep.sax.de>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --]
> As Mike Smith wrote:
>
> > > $foo=${foo:-default}
> >
> > Hmm. Actually, you would get the desired behaviour with
> >
> > val=${default}
>
> Well, sure. I didn't see this. :) You need to assign a value in the
> first place anyway.
I think you are misreading me; I was agreeing that the "default value"
option was the wrong way to go, and that an equivalent behaviour could
be achieved by setting the variable before calling read.
> j@uriah 66% ksh93
> $ read -t 5 foo # and just wait
> $ echo $?
> 1
> $ read -t 5 foo
> babble
> $ echo $?
> 0
> $ exit
This is identical to the enclosed patch, which is good. Comments anyone?
mike
[-- Attachment #2 --]
*** /usr/src/bin/sh/miscbltin.c Mon Aug 4 18:54:31 1997
--- miscbltin.c Sun Sep 28 18:44:03 1997
***************
*** 52,57 ****
--- 52,58 ----
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
+ #include <termios.h>
#include "shell.h"
#include "options.h"
***************
*** 88,101 ****
int startword;
int status;
int i;
eflag = 0;
prompt = NULL;
! while ((i = nextopt("ep:")) != '\0') {
! if (i == 'p')
prompt = optarg;
! else
eflag = 1;
}
if (prompt && isatty(0)) {
out2str(prompt);
--- 89,131 ----
int startword;
int status;
int i;
+ struct timeval tv;
+ char *tvptr;
+ fd_set ifds;
+ struct termios told, tnew;
+ int tsaved;
eflag = 0;
prompt = NULL;
! tv.tv_sec = -1;
! tv.tv_usec = 0;
! while ((i = nextopt("d:ep:t:")) != '\0') {
! switch(i) {
! case 'p':
prompt = optarg;
! break;
! case 'e':
eflag = 1;
+ break;
+ case 't':
+ tv.tv_sec = strtol(optarg, &tvptr, 0);
+ if (tvptr == optarg)
+ error("timeout value");
+ switch(*tvptr) {
+ case 0:
+ case 's':
+ break;
+ case 'h':
+ tv.tv_sec *= 60;
+ /* FALLTHROUGH */
+ case 'm':
+ tv.tv_sec *= 60;
+ break;
+ default:
+ error("timeout unit");
+ }
+ break;
+ }
}
if (prompt && isatty(0)) {
out2str(prompt);
***************
*** 105,110 ****
--- 135,169 ----
error("arg count");
if ((ifs = bltinlookup("IFS", 1)) == NULL)
ifs = nullstr;
+
+ if (tv.tv_sec >= 0) {
+ /*
+ * See if we can disable input processing; this will
+ * not give the desired result if we are in a pipeline
+ * and someone upstream is still in line-by-line mode.
+ */
+ tsaved = 0;
+ if (tcgetattr(0, &told) == 0) {
+ memcpy(&tnew, &told, sizeof(told));
+ cfmakeraw(&tnew);
+ tcsetattr(0, TCSANOW, &tnew);
+ tsaved = 1;
+ }
+ /*
+ * Wait for something to become available.
+ */
+ FD_ZERO(&ifds);
+ FD_SET(0, &ifds);
+ status = select(1, &ifds, NULL, NULL, &tv);
+ if (tsaved)
+ tcsetattr(0, TCSANOW, &told);
+ /*
+ * If there's nothing ready, return an error.
+ */
+ if (status <= 0)
+ return(1);
+ }
+
status = 0;
startword = 1;
backslash = 0;
*** /usr/src/bin/sh/sh.1 Mon Sep 15 01:01:24 1997
--- sh.1 Sun Sep 28 15:40:37 1997
***************
*** 1123,1129 ****
it faster. However, if the current directory is
renamed, the builtin version of pwd will continue to
print the old name for the directory.
! .It read [ -p prompt ] [ -e ] variable ...
The prompt is printed if the -p option is specified
and the standard input is a terminal. Then a line is
read from the standard input. The trailing newline
--- 1123,1129 ----
it faster. However, if the current directory is
renamed, the builtin version of pwd will continue to
print the old name for the directory.
! .It read [ -p prompt ] [-t timeout ] [ -e ] variable ...
The prompt is printed if the -p option is specified
and the standard input is a terminal. Then a line is
read from the standard input. The trailing newline
***************
*** 1135,1140 ****
--- 1135,1143 ----
separated them) are assigned to the last variable.
If there are more variables than pieces, the remaining
variables are assigned the null string.
+ If the -t option is specified and timeout seconds elapse
+ before any input is supplied, the read command will
+ return without assigning any values.
.Pp
The -e option causes any backslashes in the input to
be treated specially. If a backslash is followed by
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199709280917.SAA05469>
