aboutsummaryrefslogtreecommitdiff
path: root/miscutils/less.c
diff options
context:
space:
mode:
Diffstat (limited to 'miscutils/less.c')
-rw-r--r--miscutils/less.c90
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 {
298static void set_tty_cooked(void) 304static 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
1093static int64_t getch_nowait(void) 1133static 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
1195static int64_t getch_nowait(void)
1196{
1197 int64_t c;
1198
1199retry:
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
1794static void sig_catcher(int sig) 1875static 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
1800static void sigwinch_handler(int sig UNUSED_PARAM) 1882static void sigwinch_handler(int sig UNUSED_PARAM)
@@ -1806,7 +1888,9 @@ static void sigwinch_handler(int sig UNUSED_PARAM)
1806int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1888int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1807int less_main(int argc, char **argv) 1889int 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 */