diff options
Diffstat (limited to 'miscutils/less.c')
-rw-r--r-- | miscutils/less.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/miscutils/less.c b/miscutils/less.c index 223c2558d..a5ce14c91 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 |
@@ -236,7 +240,9 @@ struct globals { | |||
236 | smallint winsize_err; | 240 | smallint winsize_err; |
237 | #endif | 241 | #endif |
238 | smallint terminated; | 242 | smallint terminated; |
243 | #if !ENABLE_PLATFORM_MINGW32 | ||
239 | struct termios term_orig, term_less; | 244 | struct termios term_orig, term_less; |
245 | #endif | ||
240 | char kbd_input[KEYCODE_BUFFER_SIZE]; | 246 | char kbd_input[KEYCODE_BUFFER_SIZE]; |
241 | }; | 247 | }; |
242 | #define G (*ptr_to_globals) | 248 | #define G (*ptr_to_globals) |
@@ -298,7 +304,9 @@ struct globals { | |||
298 | static void set_tty_cooked(void) | 304 | static void set_tty_cooked(void) |
299 | { | 305 | { |
300 | fflush_all(); | 306 | fflush_all(); |
307 | #if !ENABLE_PLATFORM_MINGW32 | ||
301 | tcsetattr(kbd_fd, TCSANOW, &term_orig); | 308 | tcsetattr(kbd_fd, TCSANOW, &term_orig); |
309 | #endif | ||
302 | } | 310 | } |
303 | 311 | ||
304 | /* Move the cursor to a position (x,y), where (0,0) is the | 312 | /* Move the cursor to a position (x,y), where (0,0) is the |
@@ -330,7 +338,11 @@ static void less_exit(int code) | |||
330 | set_tty_cooked(); | 338 | set_tty_cooked(); |
331 | if (!(G.kbd_fd_orig_flags & O_NONBLOCK)) | 339 | if (!(G.kbd_fd_orig_flags & O_NONBLOCK)) |
332 | ndelay_off(kbd_fd); | 340 | ndelay_off(kbd_fd); |
341 | #if !ENABLE_PLATFORM_MINGW32 | ||
333 | clear_line(); | 342 | clear_line(); |
343 | #else | ||
344 | printf(ESC"[?1049l"); | ||
345 | #endif | ||
334 | if (code < 0) | 346 | if (code < 0) |
335 | kill_myself_with_sig(- code); /* does not return */ | 347 | kill_myself_with_sig(- code); /* does not return */ |
336 | exit(code); | 348 | exit(code); |
@@ -575,6 +587,11 @@ static void read_lines(void) | |||
575 | last_line_pos = 0; | 587 | last_line_pos = 0; |
576 | break; | 588 | break; |
577 | } | 589 | } |
590 | #if ENABLE_PLATFORM_MINGW32 | ||
591 | if (c == '\r') { | ||
592 | continue; | ||
593 | } | ||
594 | #endif | ||
578 | /* NUL is substituted by '\n'! */ | 595 | /* NUL is substituted by '\n'! */ |
579 | if (c == '\0') c = '\n'; | 596 | if (c == '\0') c = '\n'; |
580 | *p++ = c; | 597 | *p++ = c; |
@@ -671,7 +688,12 @@ static void update_num_lines(void) | |||
671 | /* only do this for regular files */ | 688 | /* only do this for regular files */ |
672 | if (num_lines == REOPEN_AND_COUNT || num_lines == REOPEN_STDIN) { | 689 | if (num_lines == REOPEN_AND_COUNT || num_lines == REOPEN_STDIN) { |
673 | count = 0; | 690 | count = 0; |
691 | #if !ENABLE_PLATFORM_MINGW32 | ||
674 | fd = open("/proc/self/fd/0", O_RDONLY); | 692 | fd = open("/proc/self/fd/0", O_RDONLY); |
693 | #else | ||
694 | /* don't even try to access /proc on WIN32 */ | ||
695 | fd = -1; | ||
696 | #endif | ||
675 | if (fd < 0 && num_lines == REOPEN_AND_COUNT) { | 697 | if (fd < 0 && num_lines == REOPEN_AND_COUNT) { |
676 | /* "filename" is valid only if REOPEN_AND_COUNT */ | 698 | /* "filename" is valid only if REOPEN_AND_COUNT */ |
677 | fd = open(filename, O_RDONLY); | 699 | fd = open(filename, O_RDONLY); |
@@ -854,7 +876,12 @@ static void print_found(const char *line) | |||
854 | match_status = 1; | 876 | match_status = 1; |
855 | } | 877 | } |
856 | 878 | ||
879 | #if !ENABLE_PLATFORM_MINGW32 | ||
857 | printf("%s%s\n", growline ? growline : "", str); | 880 | printf("%s%s\n", growline ? growline : "", str); |
881 | #else | ||
882 | /* skip newline, we use explicit positioning on WIN32 */ | ||
883 | printf("%s%s", growline ? growline : "", str); | ||
884 | #endif | ||
858 | free(growline); | 885 | free(growline); |
859 | } | 886 | } |
860 | #else | 887 | #else |
@@ -890,7 +917,12 @@ static void print_ascii(const char *str) | |||
890 | *p = '\0'; | 917 | *p = '\0'; |
891 | print_hilite(buf); | 918 | print_hilite(buf); |
892 | } | 919 | } |
920 | #if !ENABLE_PLATFORM_MINGW32 | ||
893 | puts(str); | 921 | puts(str); |
922 | #else | ||
923 | /* skip newline, we use explicit positioning on WIN32 */ | ||
924 | printf("%s", str); | ||
925 | #endif | ||
894 | } | 926 | } |
895 | 927 | ||
896 | /* Print the buffer */ | 928 | /* Print the buffer */ |
@@ -900,6 +932,10 @@ static void buffer_print(void) | |||
900 | 932 | ||
901 | move_cursor(0, 0); | 933 | move_cursor(0, 0); |
902 | for (i = 0; i <= max_displayed_line; i++) { | 934 | for (i = 0; i <= max_displayed_line; i++) { |
935 | #if ENABLE_PLATFORM_MINGW32 | ||
936 | /* make sure we're on the right line */ | ||
937 | move_cursor(i+1, 0); | ||
938 | #endif | ||
903 | printf(CLEAR_2_EOL); | 939 | printf(CLEAR_2_EOL); |
904 | if (option_mask32 & FLAG_N) | 940 | if (option_mask32 & FLAG_N) |
905 | print_lineno(buffer[i]); | 941 | print_lineno(buffer[i]); |
@@ -1087,9 +1123,13 @@ static void reinitialize(void) | |||
1087 | if (G.winsize_err) | 1123 | if (G.winsize_err) |
1088 | printf(ESC"[999;999H" ESC"[6n"); | 1124 | printf(ESC"[999;999H" ESC"[6n"); |
1089 | #endif | 1125 | #endif |
1126 | #if ENABLE_PLATFORM_MINGW32 | ||
1127 | printf(ESC"[?1049h"); | ||
1128 | #endif | ||
1090 | buffer_fill_and_print(); | 1129 | buffer_fill_and_print(); |
1091 | } | 1130 | } |
1092 | 1131 | ||
1132 | #if !ENABLE_PLATFORM_MINGW32 | ||
1093 | static int64_t getch_nowait(void) | 1133 | static int64_t getch_nowait(void) |
1094 | { | 1134 | { |
1095 | int rd; | 1135 | int rd; |
@@ -1151,6 +1191,46 @@ static int64_t getch_nowait(void) | |||
1151 | set_tty_cooked(); | 1191 | set_tty_cooked(); |
1152 | return key64; | 1192 | return key64; |
1153 | } | 1193 | } |
1194 | #else | ||
1195 | static int64_t getch_nowait(void) | ||
1196 | { | ||
1197 | int64_t c; | ||
1198 | |||
1199 | retry: | ||
1200 | c = _getch(); | ||
1201 | if (c == 0 || c == 0xe0) { | ||
1202 | switch (_getch()) { | ||
1203 | case 0x48: | ||
1204 | c = KEYCODE_UP; | ||
1205 | break; | ||
1206 | case 0x50: | ||
1207 | c = KEYCODE_DOWN; | ||
1208 | break; | ||
1209 | case 0x49: | ||
1210 | c = KEYCODE_PAGEUP; | ||
1211 | break; | ||
1212 | case 0x51: | ||
1213 | c = KEYCODE_PAGEDOWN; | ||
1214 | break; | ||
1215 | case 0x47: | ||
1216 | c = KEYCODE_HOME; | ||
1217 | break; | ||
1218 | case 0x4f: | ||
1219 | c = KEYCODE_END; | ||
1220 | break; | ||
1221 | default: | ||
1222 | goto retry; | ||
1223 | } | ||
1224 | } | ||
1225 | |||
1226 | /* Position cursor if line input is done */ | ||
1227 | if (less_gets_pos >= 0) | ||
1228 | move_cursor(max_displayed_line + 2, less_gets_pos + 1); | ||
1229 | fflush_all(); | ||
1230 | |||
1231 | return c; | ||
1232 | } | ||
1233 | #endif | ||
1154 | 1234 | ||
1155 | /* Grab a character from input without requiring the return key. | 1235 | /* Grab a character from input without requiring the return key. |
1156 | * May return KEYCODE_xxx values. | 1236 | * May return KEYCODE_xxx values. |
@@ -1791,10 +1871,12 @@ static void keypress_process(int keypress) | |||
1791 | number_process(keypress); | 1871 | number_process(keypress); |
1792 | } | 1872 | } |
1793 | 1873 | ||
1874 | #if !ENABLE_PLATFORM_MINGW32 | ||
1794 | static void sig_catcher(int sig) | 1875 | static void sig_catcher(int sig) |
1795 | { | 1876 | { |
1796 | less_exit(- sig); | 1877 | less_exit(- sig); |
1797 | } | 1878 | } |
1879 | #endif | ||
1798 | 1880 | ||
1799 | #if ENABLE_FEATURE_LESS_WINCH | 1881 | #if ENABLE_FEATURE_LESS_WINCH |
1800 | static void sigwinch_handler(int sig UNUSED_PARAM) | 1882 | static void sigwinch_handler(int sig UNUSED_PARAM) |
@@ -1806,7 +1888,9 @@ static void sigwinch_handler(int sig UNUSED_PARAM) | |||
1806 | int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 1888 | int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
1807 | int less_main(int argc, char **argv) | 1889 | int less_main(int argc, char **argv) |
1808 | { | 1890 | { |
1891 | #if !ENABLE_PLATFORM_MINGW32 | ||
1809 | char *tty_name; | 1892 | char *tty_name; |
1893 | #endif | ||
1810 | int tty_fd; | 1894 | int tty_fd; |
1811 | 1895 | ||
1812 | INIT_G(); | 1896 | INIT_G(); |
@@ -1865,6 +1949,7 @@ int less_main(int argc, char **argv) | |||
1865 | if (option_mask32 & FLAG_TILDE) | 1949 | if (option_mask32 & FLAG_TILDE) |
1866 | empty_line_marker = ""; | 1950 | empty_line_marker = ""; |
1867 | 1951 | ||
1952 | #if !ENABLE_PLATFORM_MINGW32 | ||
1868 | /* Some versions of less can survive w/o controlling tty, | 1953 | /* Some versions of less can survive w/o controlling tty, |
1869 | * try to do the same. This also allows to specify an alternative | 1954 | * try to do the same. This also allows to specify an alternative |
1870 | * tty via "less 1<>TTY". | 1955 | * tty via "less 1<>TTY". |
@@ -1890,8 +1975,13 @@ int less_main(int argc, char **argv) | |||
1890 | } | 1975 | } |
1891 | G.kbd_fd_orig_flags = ndelay_on(tty_fd); | 1976 | G.kbd_fd_orig_flags = ndelay_on(tty_fd); |
1892 | kbd_fd = tty_fd; /* save in a global */ | 1977 | kbd_fd = tty_fd; /* save in a global */ |
1978 | #else | ||
1979 | kbd_fd = tty_fd = 0; | ||
1980 | #endif | ||
1893 | 1981 | ||
1982 | #if !ENABLE_PLATFORM_MINGW32 | ||
1894 | get_termios_and_make_raw(tty_fd, &term_less, &term_orig, TERMIOS_RAW_CRNL_INPUT); | 1983 | get_termios_and_make_raw(tty_fd, &term_less, &term_orig, TERMIOS_RAW_CRNL_INPUT); |
1984 | #endif | ||
1895 | 1985 | ||
1896 | IF_FEATURE_LESS_ASK_TERMINAL(G.winsize_err =) get_terminal_width_height(tty_fd, &width, &max_displayed_line); | 1986 | IF_FEATURE_LESS_ASK_TERMINAL(G.winsize_err =) get_terminal_width_height(tty_fd, &width, &max_displayed_line); |
1897 | /* 20: two tabstops + 4 */ | 1987 | /* 20: two tabstops + 4 */ |