diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-10-20 18:30:38 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-10-20 18:30:38 +0000 |
commit | 037576d77b62186551ad07b10eb46a73144b9f84 (patch) | |
tree | e862c15849181373d5ea3a0820d75393d3054240 | |
parent | 99014e89656594ce9beec06f2605f6f7126907b9 (diff) | |
download | busybox-w32-037576d77b62186551ad07b10eb46a73144b9f84.tar.gz busybox-w32-037576d77b62186551ad07b10eb46a73144b9f84.tar.bz2 busybox-w32-037576d77b62186551ad07b10eb46a73144b9f84.zip |
read_line_input: fix it to not do any fancy editing if echoing is disabled.
ash: make read handling both more correct and smaller
read_line_input 4037 4101 +64
input_backward 140 139 -1
readcmd 1079 1070 -9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/2 up/down: 65/-10) Total: 54 bytes
text data bss dec hex filename
777575 1000 9532 788107 c068b busybox_old
777629 1000 9532 788161 c06c1 busybox_unstripped
-rw-r--r-- | libbb/lineedit.c | 12 | ||||
-rw-r--r-- | shell/ash.c | 45 |
2 files changed, 34 insertions, 23 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index c44a22843..f65e852b1 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -1259,7 +1259,7 @@ static void win_changed(int nsig) | |||
1259 | * 0 on ctrl-C, | 1259 | * 0 on ctrl-C, |
1260 | * >0 length of input string, including terminating '\n' | 1260 | * >0 length of input string, including terminating '\n' |
1261 | */ | 1261 | */ |
1262 | int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *st) | 1262 | int read_line_input(const char *prompt, char *command, int maxsize, line_input_t *st) |
1263 | { | 1263 | { |
1264 | int lastWasTab = FALSE; | 1264 | int lastWasTab = FALSE; |
1265 | unsigned int ic; | 1265 | unsigned int ic; |
@@ -1270,6 +1270,15 @@ int read_line_input(const char* prompt, char* command, int maxsize, line_input_t | |||
1270 | smalluint prevc; | 1270 | smalluint prevc; |
1271 | #endif | 1271 | #endif |
1272 | 1272 | ||
1273 | getTermSettings(0, (void *) &initial_settings); | ||
1274 | /* Happens when e.g. stty -echo was run before */ | ||
1275 | if (!(initial_settings.c_lflag & ECHO)) { | ||
1276 | parse_prompt(prompt); | ||
1277 | fflush(stdout); | ||
1278 | fgets(command, maxsize, stdin); | ||
1279 | return strlen(command); | ||
1280 | } | ||
1281 | |||
1273 | // FIXME: audit & improve this | 1282 | // FIXME: audit & improve this |
1274 | if (maxsize > MAX_LINELEN) | 1283 | if (maxsize > MAX_LINELEN) |
1275 | maxsize = MAX_LINELEN; | 1284 | maxsize = MAX_LINELEN; |
@@ -1287,7 +1296,6 @@ int read_line_input(const char* prompt, char* command, int maxsize, line_input_t | |||
1287 | command_ps = command; | 1296 | command_ps = command; |
1288 | command[0] = '\0'; | 1297 | command[0] = '\0'; |
1289 | 1298 | ||
1290 | getTermSettings(0, (void *) &initial_settings); | ||
1291 | memcpy(&new_settings, &initial_settings, sizeof(new_settings)); | 1299 | memcpy(&new_settings, &initial_settings, sizeof(new_settings)); |
1292 | new_settings.c_lflag &= ~ICANON; /* unbuffered input */ | 1300 | new_settings.c_lflag &= ~ICANON; /* unbuffered input */ |
1293 | /* Turn off echoing and CTRL-C, so we can trap it */ | 1301 | /* Turn off echoing and CTRL-C, so we can trap it */ |
diff --git a/shell/ash.c b/shell/ash.c index 52cf41ab5..58527bf9b 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -11491,7 +11491,7 @@ readcmd(int argc, char **argv) | |||
11491 | int status; | 11491 | int status; |
11492 | int i; | 11492 | int i; |
11493 | #if ENABLE_ASH_READ_NCHARS | 11493 | #if ENABLE_ASH_READ_NCHARS |
11494 | int nch_flag = 0; | 11494 | int n_flag = 0; |
11495 | int nchars = 0; | 11495 | int nchars = 0; |
11496 | int silent = 0; | 11496 | int silent = 0; |
11497 | struct termios tty, old_tty; | 11497 | struct termios tty, old_tty; |
@@ -11521,10 +11521,10 @@ readcmd(int argc, char **argv) | |||
11521 | break; | 11521 | break; |
11522 | #if ENABLE_ASH_READ_NCHARS | 11522 | #if ENABLE_ASH_READ_NCHARS |
11523 | case 'n': | 11523 | case 'n': |
11524 | nchars = strtol(optionarg, &p, 10); | 11524 | nchars = bb_strtou(optionarg, NULL, 10); |
11525 | if (*p) | 11525 | if (nchars < 0 || errno) |
11526 | ash_msg_and_raise_error("invalid count"); | 11526 | ash_msg_and_raise_error("invalid count"); |
11527 | nch_flag = (nchars > 0); | 11527 | n_flag = nchars; /* just a flag "nchars is nonzero" */ |
11528 | break; | 11528 | break; |
11529 | case 's': | 11529 | case 's': |
11530 | silent = 1; | 11530 | silent = 1; |
@@ -11532,14 +11532,15 @@ readcmd(int argc, char **argv) | |||
11532 | #endif | 11532 | #endif |
11533 | #if ENABLE_ASH_READ_TIMEOUT | 11533 | #if ENABLE_ASH_READ_TIMEOUT |
11534 | case 't': | 11534 | case 't': |
11535 | ts.tv_sec = strtol(optionarg, &p, 10); | 11535 | ts.tv_sec = bb_strtou(optionarg, &p, 10); |
11536 | ts.tv_usec = 0; | 11536 | ts.tv_usec = 0; |
11537 | if (*p == '.') { | 11537 | /* EINVAL means number is ok, but not terminated by NUL */ |
11538 | if (*p == '.' && errno == EINVAL) { | ||
11538 | char *p2; | 11539 | char *p2; |
11539 | if (*++p) { | 11540 | if (*++p) { |
11540 | int scale; | 11541 | int scale; |
11541 | ts.tv_usec = strtol(p, &p2, 10); | 11542 | ts.tv_usec = bb_strtou(p, &p2, 10); |
11542 | if (*p2) | 11543 | if (errno) |
11543 | ash_msg_and_raise_error("invalid timeout"); | 11544 | ash_msg_and_raise_error("invalid timeout"); |
11544 | scale = p2 - p; | 11545 | scale = p2 - p; |
11545 | /* normalize to usec */ | 11546 | /* normalize to usec */ |
@@ -11548,11 +11549,12 @@ readcmd(int argc, char **argv) | |||
11548 | while (scale++ < 6) | 11549 | while (scale++ < 6) |
11549 | ts.tv_usec *= 10; | 11550 | ts.tv_usec *= 10; |
11550 | } | 11551 | } |
11551 | } else if (*p) { | 11552 | } else if (ts.tv_sec < 0 || errno) { |
11552 | ash_msg_and_raise_error("invalid timeout"); | 11553 | ash_msg_and_raise_error("invalid timeout"); |
11553 | } | 11554 | } |
11554 | if ( ! ts.tv_sec && ! ts.tv_usec) | 11555 | if (!(ts.tv_sec | ts.tv_usec)) { /* both are 0? */ |
11555 | ash_msg_and_raise_error("invalid timeout"); | 11556 | ash_msg_and_raise_error("invalid timeout"); |
11557 | } | ||
11556 | break; | 11558 | break; |
11557 | #endif | 11559 | #endif |
11558 | case 'r': | 11560 | case 'r': |
@@ -11572,16 +11574,15 @@ readcmd(int argc, char **argv) | |||
11572 | if (ifs == NULL) | 11574 | if (ifs == NULL) |
11573 | ifs = defifs; | 11575 | ifs = defifs; |
11574 | #if ENABLE_ASH_READ_NCHARS | 11576 | #if ENABLE_ASH_READ_NCHARS |
11575 | if (nch_flag || silent) { | 11577 | if (n_flag || silent) { |
11576 | tcgetattr(0, &tty); | 11578 | tcgetattr(0, &tty); |
11577 | old_tty = tty; | 11579 | old_tty = tty; |
11578 | if (nch_flag) { | 11580 | if (n_flag) { |
11579 | tty.c_lflag &= ~ICANON; | 11581 | tty.c_lflag &= ~ICANON; |
11580 | tty.c_cc[VMIN] = nchars; | 11582 | tty.c_cc[VMIN] = nchars; |
11581 | } | 11583 | } |
11582 | if (silent) { | 11584 | if (silent) { |
11583 | tty.c_lflag &= ~(ECHO|ECHOK|ECHONL); | 11585 | tty.c_lflag &= ~(ECHO|ECHOK|ECHONL); |
11584 | |||
11585 | } | 11586 | } |
11586 | tcsetattr(0, TCSANOW, &tty); | 11587 | tcsetattr(0, TCSANOW, &tty); |
11587 | } | 11588 | } |
@@ -11595,7 +11596,7 @@ readcmd(int argc, char **argv) | |||
11595 | i = select(FD_SETSIZE, &set, NULL, NULL, &ts); | 11596 | i = select(FD_SETSIZE, &set, NULL, NULL, &ts); |
11596 | if (!i) { | 11597 | if (!i) { |
11597 | #if ENABLE_ASH_READ_NCHARS | 11598 | #if ENABLE_ASH_READ_NCHARS |
11598 | if (nch_flag) | 11599 | if (n_flag) |
11599 | tcsetattr(0, TCSANOW, &old_tty); | 11600 | tcsetattr(0, TCSANOW, &old_tty); |
11600 | #endif | 11601 | #endif |
11601 | return 1; | 11602 | return 1; |
@@ -11606,12 +11607,7 @@ readcmd(int argc, char **argv) | |||
11606 | startword = 1; | 11607 | startword = 1; |
11607 | backslash = 0; | 11608 | backslash = 0; |
11608 | STARTSTACKSTR(p); | 11609 | STARTSTACKSTR(p); |
11609 | #if ENABLE_ASH_READ_NCHARS | 11610 | do { |
11610 | while (!nch_flag || nchars--) | ||
11611 | #else | ||
11612 | for (;;) | ||
11613 | #endif | ||
11614 | { | ||
11615 | if (read(0, &c, 1) != 1) { | 11611 | if (read(0, &c, 1) != 1) { |
11616 | status = 1; | 11612 | status = 1; |
11617 | break; | 11613 | break; |
@@ -11645,8 +11641,15 @@ readcmd(int argc, char **argv) | |||
11645 | STPUTC(c, p); | 11641 | STPUTC(c, p); |
11646 | } | 11642 | } |
11647 | } | 11643 | } |
11644 | /* end of do {} while: */ | ||
11645 | #if ENABLE_ASH_READ_NCHARS | ||
11646 | while (!n_flag || --nchars); | ||
11647 | #else | ||
11648 | while (1); | ||
11649 | #endif | ||
11650 | |||
11648 | #if ENABLE_ASH_READ_NCHARS | 11651 | #if ENABLE_ASH_READ_NCHARS |
11649 | if (nch_flag || silent) | 11652 | if (n_flag || silent) |
11650 | tcsetattr(0, TCSANOW, &old_tty); | 11653 | tcsetattr(0, TCSANOW, &old_tty); |
11651 | #endif | 11654 | #endif |
11652 | 11655 | ||