diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-21 19:19:46 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-21 19:19:46 +0000 |
| commit | 5592fac30812f3ca908961cd75a08a009baa7bb6 (patch) | |
| tree | f9d2ab7fcb1188d0e0d387914ab025afcee2c433 /shell | |
| parent | 47bdb3ac482e8ccfa073b1c17fdf52d3721952b6 (diff) | |
| download | busybox-w32-5592fac30812f3ca908961cd75a08a009baa7bb6.tar.gz busybox-w32-5592fac30812f3ca908961cd75a08a009baa7bb6.tar.bz2 busybox-w32-5592fac30812f3ca908961cd75a08a009baa7bb6.zip | |
cmdedit: more optimizations
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/cmdedit.c | 246 |
1 files changed, 109 insertions, 137 deletions
diff --git a/shell/cmdedit.c b/shell/cmdedit.c index 1143ded77..39cab19a0 100644 --- a/shell/cmdedit.c +++ b/shell/cmdedit.c | |||
| @@ -119,14 +119,6 @@ static struct termios initial_settings, new_settings; | |||
| 119 | 119 | ||
| 120 | static | 120 | static |
| 121 | volatile unsigned cmdedit_termw = 80; /* actual terminal width */ | 121 | volatile unsigned cmdedit_termw = 80; /* actual terminal width */ |
| 122 | static | ||
| 123 | volatile int handlers_sets = 0; /* Set next bits: */ | ||
| 124 | enum { | ||
| 125 | SET_ATEXIT = 1, /* when atexit() has been called | ||
| 126 | and get euid,uid,gid to fast compare */ | ||
| 127 | SET_WCHG_HANDLERS = 2, /* winchg signal handler */ | ||
| 128 | SET_RESET_TERM = 4, /* if the terminal needs to be reset upon exit */ | ||
| 129 | }; | ||
| 130 | 122 | ||
| 131 | 123 | ||
| 132 | static int cmdedit_x; /* real x terminal position */ | 124 | static int cmdedit_x; /* real x terminal position */ |
| @@ -148,10 +140,6 @@ static char *user_buf = ""; | |||
| 148 | static char *home_pwd_buf = ""; | 140 | static char *home_pwd_buf = ""; |
| 149 | #endif | 141 | #endif |
| 150 | 142 | ||
| 151 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR || ENABLE_FEATURE_COMMAND_TAB_COMPLETION | ||
| 152 | static int my_euid; | ||
| 153 | #endif | ||
| 154 | |||
| 155 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION | 143 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION |
| 156 | static int my_uid; | 144 | static int my_uid; |
| 157 | static int my_gid; | 145 | static int my_gid; |
| @@ -339,7 +327,6 @@ static void input_backspace(void) | |||
| 339 | } | 327 | } |
| 340 | } | 328 | } |
| 341 | 329 | ||
| 342 | |||
| 343 | /* Move forward one character */ | 330 | /* Move forward one character */ |
| 344 | static void input_forward(void) | 331 | static void input_forward(void) |
| 345 | { | 332 | { |
| @@ -347,10 +334,21 @@ static void input_forward(void) | |||
| 347 | cmdedit_set_out_char(command_ps[cursor + 1]); | 334 | cmdedit_set_out_char(command_ps[cursor + 1]); |
| 348 | } | 335 | } |
| 349 | 336 | ||
| 337 | |||
| 350 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION | 338 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION |
| 351 | 339 | ||
| 352 | static char **matches; | 340 | static char **matches; |
| 353 | static int num_matches; | 341 | static unsigned num_matches; |
| 342 | |||
| 343 | static void free_tab_completion_data(void) | ||
| 344 | { | ||
| 345 | if (matches) { | ||
| 346 | while (num_matches) | ||
| 347 | free(matches[--num_matches]); | ||
| 348 | free(matches); | ||
| 349 | matches = NULL; | ||
| 350 | } | ||
| 351 | } | ||
| 354 | 352 | ||
| 355 | static void add_match(char *matched) | 353 | static void add_match(char *matched) |
| 356 | { | 354 | { |
| @@ -363,7 +361,6 @@ static void add_match(char *matched) | |||
| 363 | } | 361 | } |
| 364 | 362 | ||
| 365 | #if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION | 363 | #if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION |
| 366 | |||
| 367 | static void username_tab_completion(char *ud, char *with_shash_flg) | 364 | static void username_tab_completion(char *ud, char *with_shash_flg) |
| 368 | { | 365 | { |
| 369 | struct passwd *entry; | 366 | struct passwd *entry; |
| @@ -504,7 +501,6 @@ static void exe_n_cwd_tab_completion(char *command, int type) | |||
| 504 | } | 501 | } |
| 505 | 502 | ||
| 506 | for (i = 0; i < npaths; i++) { | 503 | for (i = 0; i < npaths; i++) { |
| 507 | |||
| 508 | dir = opendir(paths[i]); | 504 | dir = opendir(paths[i]); |
| 509 | if (!dir) /* Don't print an error */ | 505 | if (!dir) /* Don't print an error */ |
| 510 | continue; | 506 | continue; |
| @@ -559,7 +555,6 @@ static void exe_n_cwd_tab_completion(char *command, int type) | |||
| 559 | } | 555 | } |
| 560 | } | 556 | } |
| 561 | 557 | ||
| 562 | |||
| 563 | #define QUOT (UCHAR_MAX+1) | 558 | #define QUOT (UCHAR_MAX+1) |
| 564 | 559 | ||
| 565 | #define collapse_pos(is, in) { \ | 560 | #define collapse_pos(is, in) { \ |
| @@ -580,8 +575,8 @@ static int find_match(char *matchBuf, int *len_with_quotes) | |||
| 580 | if (int_buf[i] == 0) { | 575 | if (int_buf[i] == 0) { |
| 581 | pos_buf[i] = -1; /* indicator end line */ | 576 | pos_buf[i] = -1; /* indicator end line */ |
| 582 | break; | 577 | break; |
| 583 | } else | 578 | } |
| 584 | pos_buf[i] = i; | 579 | pos_buf[i] = i; |
| 585 | } | 580 | } |
| 586 | 581 | ||
| 587 | /* mask \+symbol and convert '\t' to ' ' */ | 582 | /* mask \+symbol and convert '\t' to ' ' */ |
| @@ -731,9 +726,9 @@ static int find_match(char *matchBuf, int *len_with_quotes) | |||
| 731 | } | 726 | } |
| 732 | 727 | ||
| 733 | /* | 728 | /* |
| 734 | display by column original ideas from ls applet, | 729 | * display by column (original idea from ls applet, |
| 735 | very optimize by my :) | 730 | * very optimized by me :) |
| 736 | */ | 731 | */ |
| 737 | static void showfiles(void) | 732 | static void showfiles(void) |
| 738 | { | 733 | { |
| 739 | int ncols, row; | 734 | int ncols, row; |
| @@ -770,11 +765,6 @@ static void showfiles(void) | |||
| 770 | } | 765 | } |
| 771 | } | 766 | } |
| 772 | 767 | ||
| 773 | static int match_compare(const void *a, const void *b) | ||
| 774 | { | ||
| 775 | return strcmp(*(char**)a, *(char**)b); | ||
| 776 | } | ||
| 777 | |||
| 778 | static char *add_quote_for_spec_chars(char *found) | 768 | static char *add_quote_for_spec_chars(char *found) |
| 779 | { | 769 | { |
| 780 | int l = 0; | 770 | int l = 0; |
| @@ -789,18 +779,14 @@ static char *add_quote_for_spec_chars(char *found) | |||
| 789 | return s; | 779 | return s; |
| 790 | } | 780 | } |
| 791 | 781 | ||
| 782 | static int match_compare(const void *a, const void *b) | ||
| 783 | { | ||
| 784 | return strcmp(*(char**)a, *(char**)b); | ||
| 785 | } | ||
| 786 | |||
| 787 | /* Do TAB completion */ | ||
| 792 | static void input_tab(int *lastWasTab) | 788 | static void input_tab(int *lastWasTab) |
| 793 | { | 789 | { |
| 794 | /* Do TAB completion */ | ||
| 795 | if (lastWasTab == 0) { /* free all memory */ | ||
| 796 | if (matches) { | ||
| 797 | while (num_matches > 0) | ||
| 798 | free(matches[--num_matches]); | ||
| 799 | free(matches); | ||
| 800 | matches = (char **) NULL; | ||
| 801 | } | ||
| 802 | return; | ||
| 803 | } | ||
| 804 | if (!*lastWasTab) { | 790 | if (!*lastWasTab) { |
| 805 | char *tmp, *tmp1; | 791 | char *tmp, *tmp1; |
| 806 | int len_found; | 792 | int len_found; |
| @@ -813,12 +799,12 @@ static void input_tab(int *lastWasTab) | |||
| 813 | /* Make a local copy of the string -- up | 799 | /* Make a local copy of the string -- up |
| 814 | * to the position of the cursor */ | 800 | * to the position of the cursor */ |
| 815 | tmp = strncpy(matchBuf, command_ps, cursor); | 801 | tmp = strncpy(matchBuf, command_ps, cursor); |
| 816 | tmp[cursor] = 0; | 802 | tmp[cursor] = '\0'; |
| 817 | 803 | ||
| 818 | find_type = find_match(matchBuf, &recalc_pos); | 804 | find_type = find_match(matchBuf, &recalc_pos); |
| 819 | 805 | ||
| 820 | /* Free up any memory already allocated */ | 806 | /* Free up any memory already allocated */ |
| 821 | input_tab(0); | 807 | free_tab_completion_data(); |
| 822 | 808 | ||
| 823 | #if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION | 809 | #if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION |
| 824 | /* If the word starts with `~' and there is no slash in the word, | 810 | /* If the word starts with `~' and there is no slash in the word, |
| @@ -829,24 +815,24 @@ static void input_tab(int *lastWasTab) | |||
| 829 | if (!matches) | 815 | if (!matches) |
| 830 | #endif | 816 | #endif |
| 831 | /* Try to match any executable in our path and everything | 817 | /* Try to match any executable in our path and everything |
| 832 | * in the current working directory that matches. */ | 818 | * in the current working directory */ |
| 833 | exe_n_cwd_tab_completion(matchBuf, find_type); | 819 | exe_n_cwd_tab_completion(matchBuf, find_type); |
| 834 | /* Sort, then remove any duplicates found */ | 820 | /* Sort, then remove any duplicates found */ |
| 835 | if (matches) { | 821 | if (matches) { |
| 836 | int i, n = 0; | 822 | int i, n = 0; |
| 837 | qsort(matches, num_matches, sizeof(char*), match_compare); | 823 | qsort(matches, num_matches, sizeof(char*), match_compare); |
| 838 | for (i = 0; i < num_matches - 1; ++i) { | 824 | for (i = 0; i < num_matches - 1; ++i) { |
| 839 | if (matches[i] && matches[i+1]) { | 825 | if (matches[i] && matches[i+1]) { /* paranoia */ |
| 840 | if (strcmp(matches[i], matches[i+1]) == 0) { | 826 | if (strcmp(matches[i], matches[i+1]) == 0) { |
| 841 | free(matches[i]); | 827 | free(matches[i]); |
| 842 | matches[i] = 0; | 828 | matches[i] = NULL; /* paranoia */ |
| 843 | } else { | 829 | } else { |
| 844 | matches[n++] = matches[i]; | 830 | matches[n++] = matches[i]; |
| 845 | } | 831 | } |
| 846 | } | 832 | } |
| 847 | } | 833 | } |
| 848 | matches[n++] = matches[num_matches-1]; | 834 | matches[n] = matches[i]; |
| 849 | num_matches = n; | 835 | num_matches = n + 1; |
| 850 | } | 836 | } |
| 851 | /* Did we find exactly one match? */ | 837 | /* Did we find exactly one match? */ |
| 852 | if (!matches || num_matches > 1) { | 838 | if (!matches || num_matches > 1) { |
| @@ -858,10 +844,10 @@ static void input_tab(int *lastWasTab) | |||
| 858 | for (tmp = tmp1; *tmp; tmp++) | 844 | for (tmp = tmp1; *tmp; tmp++) |
| 859 | for (len_found = 1; len_found < num_matches; len_found++) | 845 | for (len_found = 1; len_found < num_matches; len_found++) |
| 860 | if (matches[len_found][(tmp - tmp1)] != *tmp) { | 846 | if (matches[len_found][(tmp - tmp1)] != *tmp) { |
| 861 | *tmp = 0; | 847 | *tmp = '\0'; |
| 862 | break; | 848 | break; |
| 863 | } | 849 | } |
| 864 | if (*tmp1 == 0) { /* have unique */ | 850 | if (*tmp1 == '\0') { /* have unique */ |
| 865 | free(tmp1); | 851 | free(tmp1); |
| 866 | return; | 852 | return; |
| 867 | } | 853 | } |
| @@ -881,7 +867,6 @@ static void input_tab(int *lastWasTab) | |||
| 881 | len_found = strlen(tmp); | 867 | len_found = strlen(tmp); |
| 882 | /* have space to placed match? */ | 868 | /* have space to placed match? */ |
| 883 | if ((len_found - strlen(matchBuf) + len) < BUFSIZ) { | 869 | if ((len_found - strlen(matchBuf) + len) < BUFSIZ) { |
| 884 | |||
| 885 | /* before word for match */ | 870 | /* before word for match */ |
| 886 | command_ps[cursor - recalc_pos] = 0; | 871 | command_ps[cursor - recalc_pos] = 0; |
| 887 | /* save tail line */ | 872 | /* save tail line */ |
| @@ -914,6 +899,7 @@ static void input_tab(int *lastWasTab) | |||
| 914 | } | 899 | } |
| 915 | } | 900 | } |
| 916 | } | 901 | } |
| 902 | |||
| 917 | #endif /* FEATURE_COMMAND_TAB_COMPLETION */ | 903 | #endif /* FEATURE_COMMAND_TAB_COMPLETION */ |
| 918 | 904 | ||
| 919 | 905 | ||
| @@ -927,7 +913,7 @@ static int cur_history; | |||
| 927 | 913 | ||
| 928 | static void get_previous_history(void) | 914 | static void get_previous_history(void) |
| 929 | { | 915 | { |
| 930 | if (command_ps[0] != 0 || history[cur_history] == 0) { | 916 | if (command_ps[0] != '\0' || history[cur_history] == NULL) { |
| 931 | free(history[cur_history]); | 917 | free(history[cur_history]); |
| 932 | history[cur_history] = xstrdup(command_ps); | 918 | history[cur_history] = xstrdup(command_ps); |
| 933 | } | 919 | } |
| @@ -1126,81 +1112,6 @@ enum { vi_mode = 0 }; | |||
| 1126 | * cmdedit_read_input and its helpers | 1112 | * cmdedit_read_input and its helpers |
| 1127 | */ | 1113 | */ |
| 1128 | 1114 | ||
| 1129 | #define setTermSettings(fd, argp) tcsetattr(fd, TCSANOW, argp) | ||
| 1130 | #define getTermSettings(fd, argp) tcgetattr(fd, argp); | ||
| 1131 | |||
| 1132 | static sighandler_t previous_SIGWINCH_handler; | ||
| 1133 | |||
| 1134 | static void cmdedit_reset_term(void) | ||
| 1135 | { | ||
| 1136 | if (handlers_sets & SET_RESET_TERM) { | ||
| 1137 | setTermSettings(STDIN_FILENO, (void *) &initial_settings); | ||
| 1138 | handlers_sets &= ~SET_RESET_TERM; | ||
| 1139 | } | ||
| 1140 | if (handlers_sets & SET_WCHG_HANDLERS) { | ||
| 1141 | /* restore SIGWINCH handler */ | ||
| 1142 | signal(SIGWINCH, previous_SIGWINCH_handler); | ||
| 1143 | handlers_sets &= ~SET_WCHG_HANDLERS; | ||
| 1144 | } | ||
| 1145 | fflush(stdout); | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | static void cmdedit_setwidth(unsigned w, int redraw_flg) | ||
| 1149 | { | ||
| 1150 | cmdedit_termw = w; | ||
| 1151 | if (redraw_flg) { | ||
| 1152 | /* new y for current cursor */ | ||
| 1153 | int new_y = (cursor + cmdedit_prmt_len) / w; | ||
| 1154 | /* redraw */ | ||
| 1155 | redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor); | ||
| 1156 | fflush(stdout); | ||
| 1157 | } | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | static void win_changed(int nsig) | ||
| 1161 | { | ||
| 1162 | int width; | ||
| 1163 | get_terminal_width_height(0, &width, NULL); | ||
| 1164 | cmdedit_setwidth(width, nsig /* - just a yes/no flag */); | ||
| 1165 | if (nsig == SIGWINCH) | ||
| 1166 | signal(SIGWINCH, win_changed); /* rearm ourself */ | ||
| 1167 | } | ||
| 1168 | |||
| 1169 | static void cmdedit_init(void) | ||
| 1170 | { | ||
| 1171 | cmdedit_prmt_len = 0; | ||
| 1172 | if (!(handlers_sets & SET_WCHG_HANDLERS)) { | ||
| 1173 | previous_SIGWINCH_handler = signal(SIGWINCH, win_changed); | ||
| 1174 | win_changed(0); /* do initial resizing */ | ||
| 1175 | handlers_sets |= SET_WCHG_HANDLERS; | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | if (!(handlers_sets & SET_ATEXIT)) { | ||
| 1179 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR | ||
| 1180 | struct passwd *entry; | ||
| 1181 | |||
| 1182 | my_euid = geteuid(); | ||
| 1183 | entry = getpwuid(my_euid); | ||
| 1184 | if (entry) { | ||
| 1185 | user_buf = xstrdup(entry->pw_name); | ||
| 1186 | home_pwd_buf = xstrdup(entry->pw_dir); | ||
| 1187 | } | ||
| 1188 | #endif | ||
| 1189 | |||
| 1190 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION | ||
| 1191 | |||
| 1192 | #if !ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR | ||
| 1193 | my_euid = geteuid(); | ||
| 1194 | #endif | ||
| 1195 | my_uid = getuid(); | ||
| 1196 | my_gid = getgid(); | ||
| 1197 | #endif /* FEATURE_COMMAND_TAB_COMPLETION */ | ||
| 1198 | handlers_sets |= SET_ATEXIT; | ||
| 1199 | // Crap. We should be able to do it without atexit. | ||
| 1200 | atexit(cmdedit_reset_term); /* be sure to do this only once */ | ||
| 1201 | } | ||
| 1202 | } | ||
| 1203 | |||
| 1204 | #if !ENABLE_FEATURE_SH_FANCY_PROMPT | 1115 | #if !ENABLE_FEATURE_SH_FANCY_PROMPT |
| 1205 | static void parse_prompt(const char *prmt_ptr) | 1116 | static void parse_prompt(const char *prmt_ptr) |
| 1206 | { | 1117 | { |
| @@ -1259,7 +1170,7 @@ static void parse_prompt(const char *prmt_ptr) | |||
| 1259 | } | 1170 | } |
| 1260 | break; | 1171 | break; |
| 1261 | case '$': | 1172 | case '$': |
| 1262 | c = (my_euid == 0 ? '#' : '$'); | 1173 | c = (geteuid() == 0 ? '#' : '$'); |
| 1263 | break; | 1174 | break; |
| 1264 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR | 1175 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR |
| 1265 | case 'w': | 1176 | case 'w': |
| @@ -1283,7 +1194,8 @@ static void parse_prompt(const char *prmt_ptr) | |||
| 1283 | pbuf += (cp-pbuf) + 1; | 1194 | pbuf += (cp-pbuf) + 1; |
| 1284 | break; | 1195 | break; |
| 1285 | case '!': | 1196 | case '!': |
| 1286 | snprintf(pbuf = buf2, sizeof(buf2), "%d", num_ok_lines); | 1197 | pbuf = buf2; |
| 1198 | snprintf(buf2, sizeof(buf2), "%d", num_ok_lines); | ||
| 1287 | break; | 1199 | break; |
| 1288 | case 'e': case 'E': /* \e \E = \033 */ | 1200 | case 'e': case 'E': /* \e \E = \033 */ |
| 1289 | c = '\033'; | 1201 | c = '\033'; |
| @@ -1330,11 +1242,71 @@ static void parse_prompt(const char *prmt_ptr) | |||
| 1330 | } | 1242 | } |
| 1331 | #endif | 1243 | #endif |
| 1332 | 1244 | ||
| 1245 | #define setTermSettings(fd, argp) tcsetattr(fd, TCSANOW, argp) | ||
| 1246 | #define getTermSettings(fd, argp) tcgetattr(fd, argp); | ||
| 1247 | |||
| 1248 | static sighandler_t previous_SIGWINCH_handler; | ||
| 1249 | |||
| 1250 | static void cmdedit_reset_term(void) | ||
| 1251 | { | ||
| 1252 | setTermSettings(STDIN_FILENO, (void *) &initial_settings); | ||
| 1253 | /* restore SIGWINCH handler */ | ||
| 1254 | signal(SIGWINCH, previous_SIGWINCH_handler); | ||
| 1255 | fflush(stdout); | ||
| 1256 | } | ||
| 1257 | |||
| 1258 | static void cmdedit_setwidth(unsigned w, int redraw_flg) | ||
| 1259 | { | ||
| 1260 | cmdedit_termw = w; | ||
| 1261 | if (redraw_flg) { | ||
| 1262 | /* new y for current cursor */ | ||
| 1263 | int new_y = (cursor + cmdedit_prmt_len) / w; | ||
| 1264 | /* redraw */ | ||
| 1265 | redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor); | ||
| 1266 | fflush(stdout); | ||
| 1267 | } | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | static void win_changed(int nsig) | ||
| 1271 | { | ||
| 1272 | int width; | ||
| 1273 | get_terminal_width_height(0, &width, NULL); | ||
| 1274 | cmdedit_setwidth(width, nsig /* - just a yes/no flag */); | ||
| 1275 | if (nsig == SIGWINCH) | ||
| 1276 | signal(SIGWINCH, win_changed); /* rearm ourself */ | ||
| 1277 | } | ||
| 1278 | |||
| 1279 | static void cmdedit_init(void) | ||
| 1280 | { | ||
| 1281 | cmdedit_prmt_len = 0; | ||
| 1282 | previous_SIGWINCH_handler = signal(SIGWINCH, win_changed); | ||
| 1283 | win_changed(0); /* do initial resizing */ | ||
| 1284 | |||
| 1285 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR | ||
| 1286 | { | ||
| 1287 | struct passwd *entry; | ||
| 1288 | |||
| 1289 | entry = getpwuid(geteuid()); | ||
| 1290 | if (entry) { | ||
| 1291 | user_buf = xstrdup(entry->pw_name); | ||
| 1292 | home_pwd_buf = xstrdup(entry->pw_dir); | ||
| 1293 | } | ||
| 1294 | } | ||
| 1295 | #endif | ||
| 1296 | |||
| 1297 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION | ||
| 1298 | my_uid = getuid(); | ||
| 1299 | my_gid = getgid(); | ||
| 1300 | #endif | ||
| 1301 | // Crap. We should be able to do it without atexit. | ||
| 1302 | atexit(cmdedit_reset_term); /* be sure to do this only once */ | ||
| 1303 | } | ||
| 1304 | |||
| 1333 | /* | 1305 | /* |
| 1334 | * the emacs and vi modes share much of the code in the big | 1306 | * The emacs and vi modes share much of the code in the big |
| 1335 | * command loop. commands entered when in vi's command mode (aka | 1307 | * command loop. Commands entered when in vi's command mode (aka |
| 1336 | * "escape mode") get an extra bit added to distinguish them -- | 1308 | * "escape mode") get an extra bit added to distinguish them -- |
| 1337 | * this keeps them from being self-inserted. this clutters the | 1309 | * this keeps them from being self-inserted. This clutters the |
| 1338 | * big switch a bit, but keeps all the code in one place. | 1310 | * big switch a bit, but keeps all the code in one place. |
| 1339 | */ | 1311 | */ |
| 1340 | 1312 | ||
| @@ -1379,7 +1351,6 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
| 1379 | #endif | 1351 | #endif |
| 1380 | new_settings.c_cc[VINTR] = _POSIX_VDISABLE; | 1352 | new_settings.c_cc[VINTR] = _POSIX_VDISABLE; |
| 1381 | setTermSettings(0, (void *) &new_settings); | 1353 | setTermSettings(0, (void *) &new_settings); |
| 1382 | handlers_sets |= SET_RESET_TERM; | ||
| 1383 | 1354 | ||
| 1384 | /* Now initialize things */ | 1355 | /* Now initialize things */ |
| 1385 | cmdedit_init(); | 1356 | cmdedit_init(); |
| @@ -1387,11 +1358,12 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
| 1387 | parse_prompt(prompt); | 1358 | parse_prompt(prompt); |
| 1388 | 1359 | ||
| 1389 | while (1) { | 1360 | while (1) { |
| 1390 | fflush(stdout); /* buffered out to fast */ | 1361 | fflush(stdout); |
| 1391 | 1362 | ||
| 1392 | if (safe_read(0, &c, 1) < 1) | 1363 | if (safe_read(0, &c, 1) < 1) { |
| 1393 | /* if we can't read input then exit */ | 1364 | /* if we can't read input then exit */ |
| 1394 | goto prepare_to_die; | 1365 | goto prepare_to_die; |
| 1366 | } | ||
| 1395 | 1367 | ||
| 1396 | ic = c; | 1368 | ic = c; |
| 1397 | 1369 | ||
| @@ -1789,23 +1761,22 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
| 1789 | lastWasTab = FALSE; | 1761 | lastWasTab = FALSE; |
| 1790 | } | 1762 | } |
| 1791 | 1763 | ||
| 1792 | setTermSettings(0, (void *) &initial_settings); | ||
| 1793 | handlers_sets &= ~SET_RESET_TERM; | ||
| 1794 | |||
| 1795 | #if MAX_HISTORY > 0 | 1764 | #if MAX_HISTORY > 0 |
| 1796 | /* Handle command history log */ | 1765 | /* Handle command history log */ |
| 1797 | /* cleanup may be saved current command line */ | 1766 | /* cleanup may be saved current command line */ |
| 1798 | if (len > 0) { /* no put empty line */ | 1767 | if (len > 0) { |
| 1799 | int i = n_history; | 1768 | int i = n_history; |
| 1800 | 1769 | ||
| 1801 | free(history[MAX_HISTORY]); | 1770 | free(history[MAX_HISTORY]); |
| 1802 | history[MAX_HISTORY] = 0; | 1771 | history[MAX_HISTORY] = NULL; |
| 1803 | /* After max history, remove the oldest command */ | 1772 | /* After max history, remove the oldest command */ |
| 1804 | if (i >= MAX_HISTORY) { | 1773 | if (i >= MAX_HISTORY) { |
| 1805 | free(history[0]); | 1774 | free(history[0]); |
| 1806 | for (i = 0; i < MAX_HISTORY-1; i++) | 1775 | for (i = 0; i < MAX_HISTORY-1; i++) |
| 1807 | history[i] = history[i+1]; | 1776 | history[i] = history[i+1]; |
| 1808 | } | 1777 | } |
| 1778 | // Maybe "if (!i || strcmp(history[i-1], command) != 0) ..." | ||
| 1779 | // (i.e. do not save dups?) | ||
| 1809 | history[i++] = xstrdup(command); | 1780 | history[i++] = xstrdup(command); |
| 1810 | cur_history = i; | 1781 | cur_history = i; |
| 1811 | n_history = i; | 1782 | n_history = i; |
| @@ -1822,12 +1793,13 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
| 1822 | } | 1793 | } |
| 1823 | 1794 | ||
| 1824 | #if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_COMMAND_TAB_COMPLETION | 1795 | #if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_COMMAND_TAB_COMPLETION |
| 1825 | input_tab(0); | 1796 | free_tab_completion_data(); |
| 1826 | #endif | 1797 | #endif |
| 1827 | 1798 | ||
| 1828 | #if ENABLE_FEATURE_SH_FANCY_PROMPT | 1799 | #if ENABLE_FEATURE_SH_FANCY_PROMPT |
| 1829 | free(cmdedit_prompt); | 1800 | free(cmdedit_prompt); |
| 1830 | #endif | 1801 | #endif |
| 1802 | /* restore initial_settings and SIGWINCH handler */ | ||
| 1831 | cmdedit_reset_term(); | 1803 | cmdedit_reset_term(); |
| 1832 | return len; | 1804 | return len; |
| 1833 | } | 1805 | } |
