diff options
author | H. Peter Anvin <hpa@zytor.com> | 2007-02-28 09:06:28 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2007-02-28 09:06:28 -0800 |
commit | 870c6a7e1e07b1ebef7584dea6de238de075928e (patch) | |
tree | d396dd07527388f73fa01e00861a7f7e79914d21 /usr | |
parent | 20720dcd78c8530e86a340a5b6aa8894fefdba88 (diff) | |
download | linux-2.6-klibc-870c6a7e1e07b1ebef7584dea6de238de075928e.tar.gz |
[klibc] dash: support -t option to read (read with timeout)
Add the -t option to read (read with timeout).
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'usr')
-rw-r--r-- | usr/dash/miscbltin.c | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/usr/dash/miscbltin.c b/usr/dash/miscbltin.c index 3f91bc3940597d..811cd1f63085e9 100644 --- a/usr/dash/miscbltin.c +++ b/usr/dash/miscbltin.c @@ -45,6 +45,7 @@ #include <stdlib.h> #include <ctype.h> #include <stdint.h> +#include <time.h> /* strtotimeval() */ #include "shell.h" #include "options.h" @@ -79,15 +80,33 @@ readcmd(int argc, char **argv) char *p; int startword; int status; + int timeout; int i; + fd_set set; + struct timeval ts, t0, t1, to; + + ts.tv_sec = ts.tv_usec = 0; rflag = 0; + timeout = 0; prompt = NULL; - while ((i = nextopt("p:r")) != '\0') { - if (i == 'p') + while ((i = nextopt("p:rt:")) != '\0') { + switch(i) { + case 'p': prompt = optionarg; - else + break; + case 't': + p = strtotimeval(optionarg, &ts); + if (*p || (!ts.tv_sec && !ts.tv_usec)) + sh_error("invalid timeout"); + timeout = 1; + break; + case 'r': rflag = 1; + break; + default: + break; + } } if (prompt && isatty(0)) { out2str(prompt); @@ -102,8 +121,44 @@ readcmd(int argc, char **argv) status = 0; startword = 1; backslash = 0; + if (timeout) { + gettimeofday(&t0, NULL); + + /* ts += t0; */ + ts.tv_usec += t0.tv_usec; + while (ts.tv_usec >= 1000000) { + ts.tv_sec++; + ts.tv_usec -= 1000000; + } + ts.tv_sec += t0.tv_sec; + } STARTSTACKSTR(p); for (;;) { + if (timeout) { + gettimeofday(&t1, NULL); + if (t1.tv_sec > ts.tv_sec || + (t1.tv_sec == ts.tv_sec && + t1.tv_usec >= ts.tv_usec)) { + status = 1; + break; /* Timeout! */ + } + + /* to = ts - t1; */ + if (ts.tv_usec >= t1.tv_usec) { + to.tv_usec = ts.tv_usec - t1.tv_usec; + to.tv_sec = ts.tv_sec - t1.tv_sec; + } else { + to.tv_usec = ts.tv_usec - t1.tv_usec + 1000000; + to.tv_sec = ts.tv_sec - t1.tv_sec - 1; + } + + FD_ZERO(&set); + FD_SET(0, &set); + if (select(1, &set, NULL, NULL, &to) != 1) { + status = 1; + break; /* Timeout! */ + } + } if (read(0, &c, 1) != 1) { status = 1; break; |