Skip site navigation (1)Skip section navigation (2)
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> 

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multipart MIME message.

--==_Exmh_17929333040
Content-Type: text/plain; charset=us-ascii

> 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

--==_Exmh_17929333040
Content-Type: text/plain ; name="sh.diff"; charset=us-ascii
Content-Description: sh.diff
Content-Disposition: attachment; filename="sh.diff"

*** /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

--==_Exmh_17929333040--





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199709280917.SAA05469>