diff options
Diffstat (limited to 'miscutils/less.c')
| -rw-r--r-- | miscutils/less.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/miscutils/less.c b/miscutils/less.c index 2204b1cec..5a8fc5a74 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
| @@ -145,6 +145,10 @@ | |||
| 145 | 145 | ||
| 146 | #include <sched.h> /* sched_yield() */ | 146 | #include <sched.h> /* sched_yield() */ |
| 147 | 147 | ||
| 148 | #if ENABLE_PLATFORM_MINGW32 | ||
| 149 | #include <conio.h> | ||
| 150 | #endif | ||
| 151 | |||
| 148 | #include "libbb.h" | 152 | #include "libbb.h" |
| 149 | #include "common_bufsiz.h" | 153 | #include "common_bufsiz.h" |
| 150 | #if ENABLE_FEATURE_LESS_REGEXP | 154 | #if ENABLE_FEATURE_LESS_REGEXP |
| @@ -330,7 +334,11 @@ static void restore_tty(void) | |||
| 330 | set_tty_cooked(); | 334 | set_tty_cooked(); |
| 331 | if (!(G.kbd_fd_orig_flags & O_NONBLOCK)) | 335 | if (!(G.kbd_fd_orig_flags & O_NONBLOCK)) |
| 332 | ndelay_off(kbd_fd); | 336 | ndelay_off(kbd_fd); |
| 337 | #if !ENABLE_PLATFORM_MINGW32 | ||
| 333 | clear_line(); | 338 | clear_line(); |
| 339 | #else | ||
| 340 | printf(ESC"[?1049l"); | ||
| 341 | #endif | ||
| 334 | } | 342 | } |
| 335 | 343 | ||
| 336 | static NOINLINE void less_exit(void) | 344 | static NOINLINE void less_exit(void) |
| @@ -578,6 +586,11 @@ static void read_lines(void) | |||
| 578 | last_line_pos = 0; | 586 | last_line_pos = 0; |
| 579 | break; | 587 | break; |
| 580 | } | 588 | } |
| 589 | #if ENABLE_PLATFORM_MINGW32 | ||
| 590 | if (c == '\r') { | ||
| 591 | continue; | ||
| 592 | } | ||
| 593 | #endif | ||
| 581 | /* NUL is substituted by '\n'! */ | 594 | /* NUL is substituted by '\n'! */ |
| 582 | if (c == '\0') c = '\n'; | 595 | if (c == '\0') c = '\n'; |
| 583 | *p++ = c; | 596 | *p++ = c; |
| @@ -674,7 +687,12 @@ static void update_num_lines(void) | |||
| 674 | /* only do this for regular files */ | 687 | /* only do this for regular files */ |
| 675 | if (num_lines == REOPEN_AND_COUNT || num_lines == REOPEN_STDIN) { | 688 | if (num_lines == REOPEN_AND_COUNT || num_lines == REOPEN_STDIN) { |
| 676 | count = 0; | 689 | count = 0; |
| 690 | #if !ENABLE_PLATFORM_MINGW32 | ||
| 677 | fd = open("/proc/self/fd/0", O_RDONLY); | 691 | fd = open("/proc/self/fd/0", O_RDONLY); |
| 692 | #else | ||
| 693 | /* don't even try to access /proc on WIN32 */ | ||
| 694 | fd = -1; | ||
| 695 | #endif | ||
| 678 | if (fd < 0 && num_lines == REOPEN_AND_COUNT) { | 696 | if (fd < 0 && num_lines == REOPEN_AND_COUNT) { |
| 679 | /* "filename" is valid only if REOPEN_AND_COUNT */ | 697 | /* "filename" is valid only if REOPEN_AND_COUNT */ |
| 680 | fd = open(filename, O_RDONLY); | 698 | fd = open(filename, O_RDONLY); |
| @@ -857,7 +875,12 @@ static void print_found(const char *line) | |||
| 857 | match_status = 1; | 875 | match_status = 1; |
| 858 | } | 876 | } |
| 859 | 877 | ||
| 878 | #if !ENABLE_PLATFORM_MINGW32 | ||
| 860 | printf("%s%s\n", growline ? growline : "", str); | 879 | printf("%s%s\n", growline ? growline : "", str); |
| 880 | #else | ||
| 881 | /* skip newline, we use explicit positioning on WIN32 */ | ||
| 882 | printf("%s%s", growline ? growline : "", str); | ||
| 883 | #endif | ||
| 861 | free(growline); | 884 | free(growline); |
| 862 | } | 885 | } |
| 863 | #else | 886 | #else |
| @@ -893,7 +916,12 @@ static void print_ascii(const char *str) | |||
| 893 | *p = '\0'; | 916 | *p = '\0'; |
| 894 | print_hilite(buf); | 917 | print_hilite(buf); |
| 895 | } | 918 | } |
| 919 | #if !ENABLE_PLATFORM_MINGW32 | ||
| 896 | puts(str); | 920 | puts(str); |
| 921 | #else | ||
| 922 | /* skip newline, we use explicit positioning on WIN32 */ | ||
| 923 | printf("%s", str); | ||
| 924 | #endif | ||
| 897 | } | 925 | } |
| 898 | 926 | ||
| 899 | /* Print the buffer */ | 927 | /* Print the buffer */ |
| @@ -903,6 +931,10 @@ static void buffer_print(void) | |||
| 903 | 931 | ||
| 904 | move_cursor(0, 0); | 932 | move_cursor(0, 0); |
| 905 | for (i = 0; i <= max_displayed_line; i++) { | 933 | for (i = 0; i <= max_displayed_line; i++) { |
| 934 | #if ENABLE_PLATFORM_MINGW32 | ||
| 935 | /* make sure we're on the right line */ | ||
| 936 | move_cursor(i+1, 0); | ||
| 937 | #endif | ||
| 906 | printf(CLEAR_2_EOL); | 938 | printf(CLEAR_2_EOL); |
| 907 | if (option_mask32 & FLAG_N) | 939 | if (option_mask32 & FLAG_N) |
| 908 | print_lineno(buffer[i]); | 940 | print_lineno(buffer[i]); |
| @@ -1090,10 +1122,17 @@ static void reinitialize(void) | |||
| 1090 | if (G.winsize_err) | 1122 | if (G.winsize_err) |
| 1091 | printf(ESC"[999;999H" ESC"[6n"); | 1123 | printf(ESC"[999;999H" ESC"[6n"); |
| 1092 | #endif | 1124 | #endif |
| 1125 | #if ENABLE_PLATFORM_MINGW32 | ||
| 1126 | printf(ESC"[?1049h"); | ||
| 1127 | #endif | ||
| 1093 | buffer_fill_and_print(); | 1128 | buffer_fill_and_print(); |
| 1094 | } | 1129 | } |
| 1095 | 1130 | ||
| 1131 | #if ENABLE_PLATFORM_MINGW32 | ||
| 1132 | static int64_t unix_getch_nowait(void) | ||
| 1133 | #else | ||
| 1096 | static int64_t getch_nowait(void) | 1134 | static int64_t getch_nowait(void) |
| 1135 | #endif | ||
| 1097 | { | 1136 | { |
| 1098 | int rd; | 1137 | int rd; |
| 1099 | int64_t key64; | 1138 | int64_t key64; |
| @@ -1155,6 +1194,50 @@ static int64_t getch_nowait(void) | |||
| 1155 | return key64; | 1194 | return key64; |
| 1156 | } | 1195 | } |
| 1157 | 1196 | ||
| 1197 | #if ENABLE_PLATFORM_MINGW32 | ||
| 1198 | static int64_t getch_nowait(void) | ||
| 1199 | { | ||
| 1200 | int64_t c; | ||
| 1201 | |||
| 1202 | if (terminal_mode(FALSE) & VT_INPUT) | ||
| 1203 | return unix_getch_nowait(); | ||
| 1204 | |||
| 1205 | retry: | ||
| 1206 | c = _getch(); | ||
| 1207 | if (c == 0 || c == 0xe0) { | ||
| 1208 | switch (_getch()) { | ||
| 1209 | case 0x48: | ||
| 1210 | c = KEYCODE_UP; | ||
| 1211 | break; | ||
| 1212 | case 0x50: | ||
| 1213 | c = KEYCODE_DOWN; | ||
| 1214 | break; | ||
| 1215 | case 0x49: | ||
| 1216 | c = KEYCODE_PAGEUP; | ||
| 1217 | break; | ||
| 1218 | case 0x51: | ||
| 1219 | c = KEYCODE_PAGEDOWN; | ||
| 1220 | break; | ||
| 1221 | case 0x47: | ||
| 1222 | c = KEYCODE_HOME; | ||
| 1223 | break; | ||
| 1224 | case 0x4f: | ||
| 1225 | c = KEYCODE_END; | ||
| 1226 | break; | ||
| 1227 | default: | ||
| 1228 | goto retry; | ||
| 1229 | } | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | /* Position cursor if line input is done */ | ||
| 1233 | if (less_gets_pos >= 0) | ||
| 1234 | move_cursor(max_displayed_line + 2, less_gets_pos + 1); | ||
| 1235 | fflush_all(); | ||
| 1236 | |||
| 1237 | return c; | ||
| 1238 | } | ||
| 1239 | #endif | ||
| 1240 | |||
| 1158 | /* Grab a character from input without requiring the return key. | 1241 | /* Grab a character from input without requiring the return key. |
| 1159 | * May return KEYCODE_xxx values. | 1242 | * May return KEYCODE_xxx values. |
| 1160 | * Note that this function works best with raw input. */ | 1243 | * Note that this function works best with raw input. */ |
| @@ -1794,11 +1877,13 @@ static void keypress_process(int keypress) | |||
| 1794 | number_process(keypress); | 1877 | number_process(keypress); |
| 1795 | } | 1878 | } |
| 1796 | 1879 | ||
| 1880 | #if !ENABLE_PLATFORM_MINGW32 | ||
| 1797 | static void sig_catcher(int sig) | 1881 | static void sig_catcher(int sig) |
| 1798 | { | 1882 | { |
| 1799 | restore_tty(); | 1883 | restore_tty(); |
| 1800 | kill_myself_with_sig(sig); /* does not return */ | 1884 | kill_myself_with_sig(sig); /* does not return */ |
| 1801 | } | 1885 | } |
| 1886 | #endif | ||
| 1802 | 1887 | ||
| 1803 | #if ENABLE_FEATURE_LESS_WINCH | 1888 | #if ENABLE_FEATURE_LESS_WINCH |
| 1804 | static void sigwinch_handler(int sig UNUSED_PARAM) | 1889 | static void sigwinch_handler(int sig UNUSED_PARAM) |
| @@ -1810,7 +1895,11 @@ static void sigwinch_handler(int sig UNUSED_PARAM) | |||
| 1810 | int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 1895 | int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 1811 | int less_main(int argc, char **argv) | 1896 | int less_main(int argc, char **argv) |
| 1812 | { | 1897 | { |
| 1898 | #if !ENABLE_PLATFORM_MINGW32 | ||
| 1813 | char *tty_name; | 1899 | char *tty_name; |
| 1900 | #else | ||
| 1901 | HANDLE h; | ||
| 1902 | #endif | ||
| 1814 | int tty_fd; | 1903 | int tty_fd; |
| 1815 | 1904 | ||
| 1816 | INIT_G(); | 1905 | INIT_G(); |
| @@ -1869,6 +1958,7 @@ int less_main(int argc, char **argv) | |||
| 1869 | if (option_mask32 & FLAG_TILDE) | 1958 | if (option_mask32 & FLAG_TILDE) |
| 1870 | empty_line_marker = ""; | 1959 | empty_line_marker = ""; |
| 1871 | 1960 | ||
| 1961 | #if !ENABLE_PLATFORM_MINGW32 | ||
| 1872 | /* Some versions of less can survive w/o controlling tty, | 1962 | /* Some versions of less can survive w/o controlling tty, |
| 1873 | * try to do the same. This also allows to specify an alternative | 1963 | * try to do the same. This also allows to specify an alternative |
| 1874 | * tty via "less 1<>TTY". | 1964 | * tty via "less 1<>TTY". |
| @@ -1894,6 +1984,15 @@ int less_main(int argc, char **argv) | |||
| 1894 | } | 1984 | } |
| 1895 | G.kbd_fd_orig_flags = ndelay_on(tty_fd); | 1985 | G.kbd_fd_orig_flags = ndelay_on(tty_fd); |
| 1896 | kbd_fd = tty_fd; /* save in a global */ | 1986 | kbd_fd = tty_fd; /* save in a global */ |
| 1987 | #else | ||
| 1988 | h = CreateFileA("CONIN$", GENERIC_READ | GENERIC_WRITE, | ||
| 1989 | FILE_SHARE_READ, NULL, OPEN_EXISTING, | ||
| 1990 | FILE_ATTRIBUTE_NORMAL, NULL); | ||
| 1991 | if (h == INVALID_HANDLE_VALUE) | ||
| 1992 | bb_simple_error_msg_and_die("unable to open console"); | ||
| 1993 | |||
| 1994 | kbd_fd = tty_fd = _open_osfhandle((intptr_t)h, O_BINARY); | ||
| 1995 | #endif | ||
| 1897 | 1996 | ||
| 1898 | get_termios_and_make_raw(tty_fd, &term_less, &term_orig, TERMIOS_RAW_CRNL_INPUT); | 1997 | get_termios_and_make_raw(tty_fd, &term_less, &term_orig, TERMIOS_RAW_CRNL_INPUT); |
| 1899 | 1998 | ||
