Add the '-t timeout' option to the 'read' builtin. This allows the
'read' command to return an error if the user fails to supply any input withink a given time period. The behaviour of this option is similar to that of the like-named option in ksh93. Reviewed by: joerg
This commit is contained in:
parent
b71ec8cc29
commit
afa53c8df7
@ -33,7 +33,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: miscbltin.c,v 1.12 1997/04/28 03:06:36 steve Exp $
|
||||
* $Id: miscbltin.c,v 1.13 1997/05/19 00:18:43 steve Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
@ -52,6 +52,7 @@ static char const sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95";
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "shell.h"
|
||||
#include "options.h"
|
||||
@ -88,14 +89,43 @@ readcmd(argc, argv)
|
||||
int startword;
|
||||
int status;
|
||||
int i;
|
||||
struct timeval tv;
|
||||
char *tvptr;
|
||||
fd_set ifds;
|
||||
struct termios told, tnew;
|
||||
int tsaved;
|
||||
|
||||
eflag = 0;
|
||||
prompt = NULL;
|
||||
while ((i = nextopt("ep:")) != '\0') {
|
||||
if (i == 'p')
|
||||
tv.tv_sec = -1;
|
||||
tv.tv_usec = 0;
|
||||
while ((i = nextopt("ep:t:")) != '\0') {
|
||||
switch(i) {
|
||||
case 'p':
|
||||
prompt = optarg;
|
||||
else
|
||||
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,6 +135,35 @@ readcmd(argc, argv)
|
||||
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;
|
||||
|
11
bin/sh/sh.1
11
bin/sh/sh.1
@ -33,7 +33,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
|
||||
.\" $Id: sh.1,v 1.14 1997/05/07 11:42:00 steve Exp $
|
||||
.\" $Id: sh.1,v 1.15 1997/09/13 17:40:00 wosch Exp $
|
||||
.\"
|
||||
.Dd May 5, 1995
|
||||
.Dt SH 1
|
||||
@ -1123,7 +1123,7 @@ is rather than recomputing it each time. This makes
|
||||
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 ...
|
||||
.It Li "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
|
||||
@ -1136,6 +1136,13 @@ separated them) are assigned to the last variable.
|
||||
If there are more variables than pieces, the remaining
|
||||
variables are assigned the null string.
|
||||
.Pp
|
||||
If the -t option is specified the timeout elapses
|
||||
before any input is supplied, the read command will
|
||||
return without assigning any values. The timeout value
|
||||
may optionally be followed by one of 's', 'm' or 'h' to
|
||||
explicitly specify seconds, minutes or or hours. If none
|
||||
is supplied, 's' is assumed.
|
||||
.Pp
|
||||
The -e option causes any backslashes in the input to
|
||||
be treated specially. If a backslash is followed by
|
||||
a newline, the backslash and the newline will be
|
||||
|
Loading…
x
Reference in New Issue
Block a user