summaryrefslogtreecommitdiffstats
path: root/bin/sh/miscbltin.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1997-09-29 15:15:16 +0000
committermsmith <msmith@FreeBSD.org>1997-09-29 15:15:16 +0000
commitc0121f12cfec5efa37c08ce747099a0d8601eb02 (patch)
treea586a524fe27ee81e6e8215a1cf379c6991ffe4d /bin/sh/miscbltin.c
parentecd56b1d7395ab62a31ffcd8fbfcd7950a51941a (diff)
downloadFreeBSD-src-c0121f12cfec5efa37c08ce747099a0d8601eb02.zip
FreeBSD-src-c0121f12cfec5efa37c08ce747099a0d8601eb02.tar.gz
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
Diffstat (limited to 'bin/sh/miscbltin.c')
-rw-r--r--bin/sh/miscbltin.c67
1 files changed, 63 insertions, 4 deletions
diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c
index c05e017..7fbb339 100644
--- a/bin/sh/miscbltin.c
+++ b/bin/sh/miscbltin.c
@@ -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;
OpenPOWER on IntegriCloud