aboutsummaryrefslogtreecommitdiff
path: root/miscutils/less.c
diff options
context:
space:
mode:
Diffstat (limited to 'miscutils/less.c')
-rw-r--r--miscutils/less.c99
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
336static NOINLINE void less_exit(void) 344static 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
1132static int64_t unix_getch_nowait(void)
1133#else
1096static int64_t getch_nowait(void) 1134static 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
1198static int64_t getch_nowait(void)
1199{
1200 int64_t c;
1201
1202 if (terminal_mode(FALSE) & VT_INPUT)
1203 return unix_getch_nowait();
1204
1205retry:
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
1797static void sig_catcher(int sig) 1881static 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
1804static void sigwinch_handler(int sig UNUSED_PARAM) 1889static void sigwinch_handler(int sig UNUSED_PARAM)
@@ -1810,7 +1895,11 @@ static void sigwinch_handler(int sig UNUSED_PARAM)
1810int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1895int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1811int less_main(int argc, char **argv) 1896int 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