diff options
author | Ned Ludd <solar@gentoo.org> | 2005-02-09 21:07:23 +0000 |
---|---|---|
committer | Ned Ludd <solar@gentoo.org> | 2005-02-09 21:07:23 +0000 |
commit | 2123b7cded4d28173b8a9e5bd40c565cbb1a75b1 (patch) | |
tree | f99c5b31b74ed26400a67a073f8eef788b8f793e | |
parent | 8063d5ca256d7194f39ace521c31621b4dd611e4 (diff) | |
download | busybox-w32-2123b7cded4d28173b8a9e5bd40c565cbb1a75b1.tar.gz busybox-w32-2123b7cded4d28173b8a9e5bd40c565cbb1a75b1.tar.bz2 busybox-w32-2123b7cded4d28173b8a9e5bd40c565cbb1a75b1.zip |
- add ash read -t timeout support. initial code provided by Tim Yamin on Oct/21/2004 on the busybox mailing list. Edited his code a little to keep syntax highlighers happy and make it optional when CONFIG_ASH_TIMEOUT is defined
-rw-r--r-- | shell/Config.in | 11 | ||||
-rw-r--r-- | shell/ash.c | 66 |
2 files changed, 74 insertions, 3 deletions
diff --git a/shell/Config.in b/shell/Config.in index bdba40d3b..1a3c388a4 100644 --- a/shell/Config.in +++ b/shell/Config.in | |||
@@ -53,6 +53,17 @@ config CONFIG_ASH_JOB_CONTROL | |||
53 | help | 53 | help |
54 | Enable job control in the ash shell. | 54 | Enable job control in the ash shell. |
55 | 55 | ||
56 | config CONFIG_ASH_TIMEOUT | ||
57 | bool " Enable read timeout support." | ||
58 | default n | ||
59 | depends on CONFIG_ASH_JOB_CONTROL | ||
60 | help | ||
61 | This option provides read -t <seconds> support. | ||
62 | |||
63 | read builtin which allows the function to pass control back | ||
64 | if no character input is read from the terminal within a set | ||
65 | number of seconds. | ||
66 | |||
56 | config CONFIG_ASH_ALIAS | 67 | config CONFIG_ASH_ALIAS |
57 | bool " Enable alias support" | 68 | bool " Enable alias support" |
58 | default y | 69 | default y |
diff --git a/shell/ash.c b/shell/ash.c index d9ea2b0f3..5bcda749f 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -12583,17 +12583,34 @@ readcmd(int argc, char **argv) | |||
12583 | char *prompt; | 12583 | char *prompt; |
12584 | const char *ifs; | 12584 | const char *ifs; |
12585 | char *p; | 12585 | char *p; |
12586 | #if defined(CONFIG_ASH_TIMEOUT) && JOBS | ||
12587 | fd_set set; | ||
12588 | int timeout; | ||
12589 | struct timeval timeout_struct; | ||
12590 | struct termios tty, old_tty; | ||
12591 | #endif | ||
12586 | int startword; | 12592 | int startword; |
12587 | int status; | 12593 | int status; |
12588 | int i; | 12594 | int i; |
12589 | 12595 | ||
12590 | rflag = 0; | 12596 | rflag = 0; |
12591 | prompt = NULL; | 12597 | prompt = NULL; |
12592 | while ((i = nextopt("p:r")) != '\0') { | 12598 | #if defined(CONFIG_ASH_TIMEOUT) && JOBS |
12599 | timeout = 0; | ||
12600 | |||
12601 | while ((i = nextopt("p:rt:")) != '\0') | ||
12602 | #else | ||
12603 | while ((i = nextopt("p:r")) != '\0') | ||
12604 | #endif | ||
12605 | { | ||
12593 | if (i == 'p') | 12606 | if (i == 'p') |
12594 | prompt = optionarg; | 12607 | prompt = optionarg; |
12595 | else | 12608 | else if (i == 'r') |
12596 | rflag = 1; | 12609 | rflag = 1; |
12610 | #if defined(CONFIG_ASH_TIMEOUT) && JOBS | ||
12611 | else | ||
12612 | timeout = atoi(optionarg); | ||
12613 | #endif | ||
12597 | } | 12614 | } |
12598 | if (prompt && isatty(0)) { | 12615 | if (prompt && isatty(0)) { |
12599 | out2str(prompt); | 12616 | out2str(prompt); |
@@ -12602,11 +12619,54 @@ readcmd(int argc, char **argv) | |||
12602 | error("arg count"); | 12619 | error("arg count"); |
12603 | if ((ifs = bltinlookup("IFS")) == NULL) | 12620 | if ((ifs = bltinlookup("IFS")) == NULL) |
12604 | ifs = defifs; | 12621 | ifs = defifs; |
12622 | #if defined(CONFIG_ASH_TIMEOUT) && JOBS | ||
12623 | c = 0; | ||
12624 | #endif | ||
12605 | status = 0; | 12625 | status = 0; |
12606 | startword = 1; | 12626 | startword = 1; |
12607 | backslash = 0; | 12627 | backslash = 0; |
12628 | |||
12608 | STARTSTACKSTR(p); | 12629 | STARTSTACKSTR(p); |
12609 | for (;;) { | 12630 | #if defined(CONFIG_ASH_TIMEOUT) && JOBS |
12631 | if (timeout > 0) { | ||
12632 | tcgetattr(0, &tty); | ||
12633 | old_tty = tty; | ||
12634 | |||
12635 | /* cfmakeraw(...) disables too much; we just do this instead. */ | ||
12636 | tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); | ||
12637 | tcsetattr(0, TCSANOW, &tty); | ||
12638 | |||
12639 | FD_ZERO (&set); | ||
12640 | FD_SET (0, &set); | ||
12641 | |||
12642 | timeout_struct.tv_sec = timeout; | ||
12643 | timeout_struct.tv_usec = 0; | ||
12644 | |||
12645 | i = select (FD_SETSIZE, &set, NULL, NULL, &timeout_struct); | ||
12646 | if(i == 1) | ||
12647 | { | ||
12648 | read(0, &c, 1); | ||
12649 | if(c == '\n' || c == 4) /* Handle newlines and EOF */ | ||
12650 | i = 0; /* Don't read further... */ | ||
12651 | else | ||
12652 | STPUTC(c, p); /* Keep reading... */ | ||
12653 | } | ||
12654 | tcsetattr(0, TCSANOW, &old_tty); | ||
12655 | |||
12656 | /* Echo the character so the user knows it was read... | ||
12657 | Yes, this can be done by setting the ECHO flag, but that | ||
12658 | echoes ^D and other control characters at this state */ | ||
12659 | if(c != 0) | ||
12660 | write(1, &c, 1); | ||
12661 | |||
12662 | } else | ||
12663 | i = 1; | ||
12664 | |||
12665 | for (;i == 1;) | ||
12666 | #else | ||
12667 | for (;;) | ||
12668 | #endif | ||
12669 | { | ||
12610 | if (read(0, &c, 1) != 1) { | 12670 | if (read(0, &c, 1) != 1) { |
12611 | status = 1; | 12671 | status = 1; |
12612 | break; | 12672 | break; |