diff options
author | Ron Yorston <rmy@pobox.com> | 2021-01-14 13:28:49 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-01-14 13:28:49 +0000 |
commit | 89963b524d211e1aec12b72b3725be05ee95c8cf (patch) | |
tree | 48590aef62b7ee7686b7898256f29def8d9c50b9 /libbb/lineedit.c | |
parent | 9aa5a829070392c2ac6494d0c4e674c0c2bc7dab (diff) | |
parent | 2b7c1aa92c68524559a2067609d09309d5c09adc (diff) | |
download | busybox-w32-89963b524d211e1aec12b72b3725be05ee95c8cf.tar.gz busybox-w32-89963b524d211e1aec12b72b3725be05ee95c8cf.tar.bz2 busybox-w32-89963b524d211e1aec12b72b3725be05ee95c8cf.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb/lineedit.c')
-rw-r--r-- | libbb/lineedit.c | 129 |
1 files changed, 81 insertions, 48 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index b35da1874..f3cbc512c 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -57,12 +57,23 @@ | |||
57 | #if ENABLE_FEATURE_EDITING | 57 | #if ENABLE_FEATURE_EDITING |
58 | 58 | ||
59 | 59 | ||
60 | #if !ENABLE_SHELL_ASH && !ENABLE_SHELL_HUSH | ||
61 | /* so far only shells use these features */ | ||
62 | # undef ENABLE_FEATURE_EDITING_FANCY_PROMPT | ||
63 | # undef ENABLE_FEATURE_TAB_COMPLETION | ||
64 | # undef ENABLE_FEATURE_USERNAME_COMPLETION | ||
65 | # define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0 | ||
66 | # define ENABLE_FEATURE_TAB_COMPLETION 0 | ||
67 | # define ENABLE_FEATURE_USERNAME_COMPLETION 0 | ||
68 | #endif | ||
69 | |||
70 | |||
60 | #define ENABLE_USERNAME_OR_HOMEDIR \ | 71 | #define ENABLE_USERNAME_OR_HOMEDIR \ |
61 | (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) | 72 | (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) |
62 | #define IF_USERNAME_OR_HOMEDIR(...) | ||
63 | #if ENABLE_USERNAME_OR_HOMEDIR | 73 | #if ENABLE_USERNAME_OR_HOMEDIR |
64 | # undef IF_USERNAME_OR_HOMEDIR | ||
65 | # define IF_USERNAME_OR_HOMEDIR(...) __VA_ARGS__ | 74 | # define IF_USERNAME_OR_HOMEDIR(...) __VA_ARGS__ |
75 | #else | ||
76 | # define IF_USERNAME_OR_HOMEDIR(...) /*nothing*/ | ||
66 | #endif | 77 | #endif |
67 | 78 | ||
68 | 79 | ||
@@ -205,9 +216,6 @@ extern struct lineedit_statics *const lineedit_ptr_to_statics; | |||
205 | #define INIT_S() do { \ | 216 | #define INIT_S() do { \ |
206 | (*(struct lineedit_statics**)not_const_pp(&lineedit_ptr_to_statics)) = xzalloc(sizeof(S)); \ | 217 | (*(struct lineedit_statics**)not_const_pp(&lineedit_ptr_to_statics)) = xzalloc(sizeof(S)); \ |
207 | barrier(); \ | 218 | barrier(); \ |
208 | cmdedit_termw = 80; \ | ||
209 | IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) \ | ||
210 | IF_FEATURE_EDITING_VI(delptr = delbuf;) \ | ||
211 | } while (0) | 219 | } while (0) |
212 | 220 | ||
213 | static void deinit_S(void) | 221 | static void deinit_S(void) |
@@ -796,16 +804,18 @@ enum { | |||
796 | FIND_FILE_ONLY = 2, | 804 | FIND_FILE_ONLY = 2, |
797 | }; | 805 | }; |
798 | 806 | ||
799 | static int path_parse(char ***p) | 807 | static unsigned path_parse(char ***p) |
800 | { | 808 | { |
801 | int npth; | 809 | unsigned npth; |
802 | const char *pth; | 810 | const char *pth; |
803 | char *tmp; | 811 | char *tmp; |
804 | char **res; | 812 | char **res; |
805 | 813 | ||
814 | # if EDITING_HAS_path_lookup | ||
806 | if (state->flags & WITH_PATH_LOOKUP) | 815 | if (state->flags & WITH_PATH_LOOKUP) |
807 | pth = state->path_lookup; | 816 | pth = state->path_lookup; |
808 | else | 817 | else |
818 | # endif | ||
809 | pth = getenv("PATH"); | 819 | pth = getenv("PATH"); |
810 | 820 | ||
811 | /* PATH="" or PATH=":"? */ | 821 | /* PATH="" or PATH=":"? */ |
@@ -824,7 +834,7 @@ static int path_parse(char ***p) | |||
824 | npth++; | 834 | npth++; |
825 | } | 835 | } |
826 | 836 | ||
827 | *p = res = xmalloc(npth * sizeof(res[0])); | 837 | *p = res = xzalloc((npth + 1) * sizeof(res[0])); |
828 | res[0] = tmp = xstrdup(pth); | 838 | res[0] = tmp = xstrdup(pth); |
829 | npth = 1; | 839 | npth = 1; |
830 | while (1) { | 840 | while (1) { |
@@ -836,6 +846,8 @@ static int path_parse(char ***p) | |||
836 | break; /* :<empty> */ | 846 | break; /* :<empty> */ |
837 | res[npth++] = tmp; | 847 | res[npth++] = tmp; |
838 | } | 848 | } |
849 | /* special case: "match subdirectories of the current directory" */ | ||
850 | /*res[npth++] = NULL; - filled by xzalloc() */ | ||
839 | return npth; | 851 | return npth; |
840 | } | 852 | } |
841 | 853 | ||
@@ -846,49 +858,49 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
846 | { | 858 | { |
847 | char *path1[1]; | 859 | char *path1[1]; |
848 | char **paths = path1; | 860 | char **paths = path1; |
849 | int npaths; | 861 | unsigned npaths; |
850 | int i; | 862 | unsigned i; |
851 | unsigned pf_len; | 863 | unsigned baselen; |
852 | const char *pfind; | 864 | const char *basecmd; |
853 | char *dirbuf = NULL; | 865 | char *dirbuf = NULL; |
854 | 866 | ||
855 | npaths = 1; | 867 | npaths = 1; |
856 | path1[0] = (char*)"."; | 868 | path1[0] = (char*)"."; |
857 | 869 | ||
858 | pfind = strrchr(command, '/'); | 870 | basecmd = strrchr(command, '/'); |
859 | #if ENABLE_PLATFORM_MINGW32 | 871 | #if ENABLE_PLATFORM_MINGW32 |
860 | if (!pfind && has_dos_drive_prefix(command) && command[2] != '\0') { | 872 | if (!basecmd && has_dos_drive_prefix(command) && command[2] != '\0') { |
861 | char buffer[PATH_MAX]; | 873 | char buffer[PATH_MAX]; |
862 | 874 | ||
863 | /* path is of form c:path with no '/' */ | 875 | /* path is of form c:path with no '/' */ |
864 | if (get_drive_cwd(command, buffer, PATH_MAX)) { | 876 | if (get_drive_cwd(command, buffer, PATH_MAX)) { |
865 | pfind = command + 2; | 877 | basecmd = command + 2; |
866 | path1[0] = dirbuf = xstrdup(buffer); | 878 | path1[0] = dirbuf = xstrdup(buffer); |
867 | } | 879 | } |
868 | } else | 880 | } else |
869 | #endif | 881 | #endif |
870 | if (!pfind) { | 882 | if (!basecmd) { |
871 | if (type == FIND_EXE_ONLY) | 883 | if (type == FIND_EXE_ONLY) |
872 | npaths = path_parse(&paths); | 884 | npaths = path_parse(&paths); |
873 | pfind = command; | 885 | basecmd = command; |
874 | } else { | 886 | } else { |
875 | /* point to 'l' in "..../last_component" */ | 887 | /* point to 'l' in "..../last_component" */ |
876 | pfind++; | 888 | basecmd++; |
877 | /* dirbuf = ".../.../.../" */ | 889 | /* dirbuf = ".../.../.../" */ |
878 | dirbuf = xstrndup(command, pfind - command); | 890 | dirbuf = xstrndup(command, basecmd - command); |
879 | # if ENABLE_FEATURE_USERNAME_COMPLETION | 891 | # if ENABLE_FEATURE_USERNAME_COMPLETION |
880 | if (dirbuf[0] == '~') /* ~/... or ~user/... */ | 892 | if (dirbuf[0] == '~') /* ~/... or ~user/... */ |
881 | dirbuf = username_path_completion(dirbuf); | 893 | dirbuf = username_path_completion(dirbuf); |
882 | # endif | 894 | # endif |
883 | path1[0] = dirbuf; | 895 | path1[0] = dirbuf; |
884 | } | 896 | } |
885 | pf_len = strlen(pfind); | 897 | baselen = strlen(basecmd); |
886 | 898 | ||
887 | if (type == FIND_EXE_ONLY && !dirbuf) { | 899 | if (type == FIND_EXE_ONLY && !dirbuf) { |
888 | # if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1 | 900 | # if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1 |
889 | const char *p = applet_names; | 901 | const char *p = applet_names; |
890 | while (*p) { | 902 | while (*p) { |
891 | if (strncmp(pfind, p, pf_len) == 0) | 903 | if (strncmp(basecmd, p, baselen) == 0) |
892 | add_match(xstrdup(p)); | 904 | add_match(xstrdup(p)); |
893 | while (*p++ != '\0') | 905 | while (*p++ != '\0') |
894 | continue; | 906 | continue; |
@@ -901,7 +913,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
901 | const char *b = state->get_exe_name(i++); | 913 | const char *b = state->get_exe_name(i++); |
902 | if (!b) | 914 | if (!b) |
903 | break; | 915 | break; |
904 | if (strncmp(pfind, b, pf_len) == 0) | 916 | if (strncmp(basecmd, b, baselen) == 0) |
905 | add_match(xstrdup(b)); | 917 | add_match(xstrdup(b)); |
906 | } | 918 | } |
907 | } | 919 | } |
@@ -913,9 +925,20 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
913 | struct dirent *next; | 925 | struct dirent *next; |
914 | struct stat st; | 926 | struct stat st; |
915 | char *found; | 927 | char *found; |
928 | #if ENABLE_PLATFORM_MINGW32 | ||
929 | char *lpath; | ||
930 | #endif | ||
931 | |||
932 | if (paths[i] == NULL) { /* path_parse()'s last component? */ | ||
933 | /* in PATH completion, current dir's subdir names | ||
934 | * can be completions (but only subdirs, not files). | ||
935 | */ | ||
936 | type = FIND_DIR_ONLY; | ||
937 | paths[i] = (char *)"."; | ||
938 | } | ||
916 | 939 | ||
917 | #if ENABLE_PLATFORM_MINGW32 | 940 | #if ENABLE_PLATFORM_MINGW32 |
918 | char *lpath = auto_string(alloc_system_drive(paths[i])); | 941 | lpath = auto_string(alloc_system_drive(paths[i])); |
919 | dir = opendir(lpath); | 942 | dir = opendir(lpath); |
920 | #else | 943 | #else |
921 | dir = opendir(paths[i]); | 944 | dir = opendir(paths[i]); |
@@ -928,10 +951,10 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
928 | const char *name_found = next->d_name; | 951 | const char *name_found = next->d_name; |
929 | 952 | ||
930 | /* .../<tab>: bash 3.2.0 shows dotfiles, but not . and .. */ | 953 | /* .../<tab>: bash 3.2.0 shows dotfiles, but not . and .. */ |
931 | if (!pfind[0] && DOT_OR_DOTDOT(name_found)) | 954 | if (!basecmd[0] && DOT_OR_DOTDOT(name_found)) |
932 | continue; | 955 | continue; |
933 | /* match? */ | 956 | /* match? */ |
934 | if (!is_prefixed_with(name_found, pfind)) | 957 | if (strncmp(basecmd, name_found, baselen) != 0) |
935 | continue; /* no */ | 958 | continue; /* no */ |
936 | 959 | ||
937 | #if ENABLE_PLATFORM_MINGW32 | 960 | #if ENABLE_PLATFORM_MINGW32 |
@@ -957,6 +980,9 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
957 | strcpy(found, name_found); | 980 | strcpy(found, name_found); |
958 | 981 | ||
959 | if (S_ISDIR(st.st_mode)) { | 982 | if (S_ISDIR(st.st_mode)) { |
983 | /* skip directories if searching PATH */ | ||
984 | if (type == FIND_EXE_ONLY && !dirbuf) | ||
985 | goto cont; | ||
960 | /* name is a directory, add slash */ | 986 | /* name is a directory, add slash */ |
961 | found[len] = '/'; | 987 | found[len] = '/'; |
962 | found[len + 1] = '\0'; | 988 | found[len + 1] = '\0'; |
@@ -980,7 +1006,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
980 | } | 1006 | } |
981 | free(dirbuf); | 1007 | free(dirbuf); |
982 | 1008 | ||
983 | return pf_len; | 1009 | return baselen; |
984 | } | 1010 | } |
985 | 1011 | ||
986 | /* build_match_prefix: | 1012 | /* build_match_prefix: |
@@ -1492,15 +1518,19 @@ void FAST_FUNC show_history(const line_input_t *st) | |||
1492 | printf("%4d %s\n", i, st->history[i]); | 1518 | printf("%4d %s\n", i, st->history[i]); |
1493 | } | 1519 | } |
1494 | 1520 | ||
1521 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY | ||
1495 | void FAST_FUNC free_line_input_t(line_input_t *n) | 1522 | void FAST_FUNC free_line_input_t(line_input_t *n) |
1496 | { | 1523 | { |
1497 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY | 1524 | if (n) { |
1498 | int i = n->cnt_history; | 1525 | int i = n->cnt_history; |
1499 | while (i > 0) | 1526 | while (i > 0) |
1500 | free(n->history[--i]); | 1527 | free(n->history[--i]); |
1501 | #endif | 1528 | free(n); |
1502 | free(n); | 1529 | } |
1503 | } | 1530 | } |
1531 | # else | ||
1532 | /* #defined to free() in libbb.h */ | ||
1533 | # endif | ||
1504 | 1534 | ||
1505 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY | 1535 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY |
1506 | /* We try to ensure that concurrent additions to the history | 1536 | /* We try to ensure that concurrent additions to the history |
@@ -1581,7 +1611,7 @@ void save_history(line_input_t *st) | |||
1581 | { | 1611 | { |
1582 | FILE *fp; | 1612 | FILE *fp; |
1583 | 1613 | ||
1584 | if (!st->hist_file) | 1614 | if (!st || !st->hist_file) |
1585 | return; | 1615 | return; |
1586 | if (st->cnt_history <= st->cnt_history_in_file) | 1616 | if (st->cnt_history <= st->cnt_history_in_file) |
1587 | return; | 1617 | return; |
@@ -1971,9 +2001,7 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
1971 | { | 2001 | { |
1972 | int prmt_size = 0; | 2002 | int prmt_size = 0; |
1973 | char *prmt_mem_ptr = xzalloc(1); | 2003 | char *prmt_mem_ptr = xzalloc(1); |
1974 | # if ENABLE_USERNAME_OR_HOMEDIR | ||
1975 | char *cwd_buf = NULL; | 2004 | char *cwd_buf = NULL; |
1976 | # endif | ||
1977 | char flg_not_length = '['; | 2005 | char flg_not_length = '['; |
1978 | char cbuf[2]; | 2006 | char cbuf[2]; |
1979 | 2007 | ||
@@ -2040,11 +2068,9 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
2040 | c = *prmt_ptr++; | 2068 | c = *prmt_ptr++; |
2041 | 2069 | ||
2042 | switch (c) { | 2070 | switch (c) { |
2043 | # if ENABLE_USERNAME_OR_HOMEDIR | ||
2044 | case 'u': | 2071 | case 'u': |
2045 | pbuf = user_buf ? user_buf : (char*)""; | 2072 | pbuf = user_buf ? user_buf : (char*)""; |
2046 | break; | 2073 | break; |
2047 | # endif | ||
2048 | case 'H': | 2074 | case 'H': |
2049 | case 'h': | 2075 | case 'h': |
2050 | pbuf = free_me = safe_gethostname(); | 2076 | pbuf = free_me = safe_gethostname(); |
@@ -2062,7 +2088,6 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
2062 | strftime_HHMMSS(timebuf, sizeof(timebuf), NULL)[-3] = '\0'; | 2088 | strftime_HHMMSS(timebuf, sizeof(timebuf), NULL)[-3] = '\0'; |
2063 | pbuf = timebuf; | 2089 | pbuf = timebuf; |
2064 | break; | 2090 | break; |
2065 | # if ENABLE_USERNAME_OR_HOMEDIR | ||
2066 | case 'w': /* current dir */ | 2091 | case 'w': /* current dir */ |
2067 | case 'W': /* basename of cur dir */ | 2092 | case 'W': /* basename of cur dir */ |
2068 | if (!cwd_buf) { | 2093 | if (!cwd_buf) { |
@@ -2089,7 +2114,6 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
2089 | if (cp) | 2114 | if (cp) |
2090 | pbuf = (char*)cp + 1; | 2115 | pbuf = (char*)cp + 1; |
2091 | break; | 2116 | break; |
2092 | # endif | ||
2093 | // bb_process_escape_sequence does this now: | 2117 | // bb_process_escape_sequence does this now: |
2094 | // case 'e': case 'E': /* \e \E = \033 */ | 2118 | // case 'e': case 'E': /* \e \E = \033 */ |
2095 | // c = '\033'; | 2119 | // c = '\033'; |
@@ -2130,10 +2154,17 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
2130 | if (c == '\n') | 2154 | if (c == '\n') |
2131 | cmdedit_prmt_len = 0; | 2155 | cmdedit_prmt_len = 0; |
2132 | else if (flg_not_length != ']') { | 2156 | else if (flg_not_length != ']') { |
2133 | #if 0 /*ENABLE_UNICODE_SUPPORT*/ | 2157 | #if ENABLE_UNICODE_SUPPORT |
2134 | /* Won't work, pbuf is one BYTE string here instead of an one Unicode char string. */ | 2158 | if (n == 1) { |
2135 | /* FIXME */ | 2159 | /* Only count single-byte characters and the first of multi-byte characters */ |
2136 | cmdedit_prmt_len += unicode_strwidth(pbuf); | 2160 | if ((unsigned char)*pbuf < 0x80 /* single byte character */ |
2161 | || (unsigned char)*pbuf >= 0xc0 /* first of multi-byte characters */ | ||
2162 | ) { | ||
2163 | cmdedit_prmt_len += n; | ||
2164 | } | ||
2165 | } else { | ||
2166 | cmdedit_prmt_len += unicode_strwidth(pbuf); | ||
2167 | } | ||
2137 | #else | 2168 | #else |
2138 | cmdedit_prmt_len += n; | 2169 | cmdedit_prmt_len += n; |
2139 | #endif | 2170 | #endif |
@@ -2143,10 +2174,8 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
2143 | free(free_me); | 2174 | free(free_me); |
2144 | } /* while */ | 2175 | } /* while */ |
2145 | 2176 | ||
2146 | # if ENABLE_USERNAME_OR_HOMEDIR | ||
2147 | if (cwd_buf != (char *)bb_msg_unknown) | 2177 | if (cwd_buf != (char *)bb_msg_unknown) |
2148 | free(cwd_buf); | 2178 | free(cwd_buf); |
2149 | # endif | ||
2150 | /* see comment (above this function) about multiline prompt redrawing */ | 2179 | /* see comment (above this function) about multiline prompt redrawing */ |
2151 | cmdedit_prompt = prompt_last_line = prmt_mem_ptr; | 2180 | cmdedit_prompt = prompt_last_line = prmt_mem_ptr; |
2152 | prmt_ptr = strrchr(cmdedit_prompt, '\n'); | 2181 | prmt_ptr = strrchr(cmdedit_prompt, '\n'); |
@@ -2154,7 +2183,7 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
2154 | prompt_last_line = prmt_ptr + 1; | 2183 | prompt_last_line = prmt_ptr + 1; |
2155 | put_prompt(); | 2184 | put_prompt(); |
2156 | } | 2185 | } |
2157 | #endif | 2186 | #endif /* FEATURE_EDITING_FANCY_PROMPT */ |
2158 | 2187 | ||
2159 | #if ENABLE_FEATURE_EDITING_WINCH | 2188 | #if ENABLE_FEATURE_EDITING_WINCH |
2160 | static void cmdedit_setwidth(void) | 2189 | static void cmdedit_setwidth(void) |
@@ -2467,6 +2496,11 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2467 | char read_key_buffer[KEYCODE_BUFFER_SIZE]; | 2496 | char read_key_buffer[KEYCODE_BUFFER_SIZE]; |
2468 | 2497 | ||
2469 | INIT_S(); | 2498 | INIT_S(); |
2499 | //command_len = 0; - done by INIT_S() | ||
2500 | //cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ | ||
2501 | cmdedit_termw = 80; | ||
2502 | IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) | ||
2503 | IF_FEATURE_EDITING_VI(delptr = delbuf;) | ||
2470 | 2504 | ||
2471 | #if !ENABLE_PLATFORM_MINGW32 | 2505 | #if !ENABLE_PLATFORM_MINGW32 |
2472 | n = get_termios_and_make_raw(STDIN_FILENO, &new_settings, &initial_settings, 0 | 2506 | n = get_termios_and_make_raw(STDIN_FILENO, &new_settings, &initial_settings, 0 |
@@ -2521,8 +2555,6 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2521 | #endif | 2555 | #endif |
2522 | 2556 | ||
2523 | /* prepare before init handlers */ | 2557 | /* prepare before init handlers */ |
2524 | cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ | ||
2525 | command_len = 0; | ||
2526 | #if ENABLE_UNICODE_SUPPORT | 2558 | #if ENABLE_UNICODE_SUPPORT |
2527 | command_ps = xzalloc(maxsize * sizeof(command_ps[0])); | 2559 | command_ps = xzalloc(maxsize * sizeof(command_ps[0])); |
2528 | #else | 2560 | #else |
@@ -3005,6 +3037,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
3005 | * before it comes in. UGLY! | 3037 | * before it comes in. UGLY! |
3006 | */ | 3038 | */ |
3007 | usleep(20*1000); | 3039 | usleep(20*1000); |
3040 | // MAYBE? tcflush(STDIN_FILENO, TCIFLUSH); /* flushes data received but not read */ | ||
3008 | } | 3041 | } |
3009 | #endif | 3042 | #endif |
3010 | 3043 | ||