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 8a0525cb7..467c76e2a 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 | ||