Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/miscutils/less.c
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/miscutils/less.c
r3232 r3621 48 48 //config: help 49 49 //config: The -M/-m flag enables a more sophisticated status line. 50 //config: 51 //config:config FEATURE_LESS_TRUNCATE 52 //config: bool "Enable -S" 53 //config: default y 54 //config: depends on LESS 55 //config: help 56 //config: The -S flag causes long lines to be truncated rather than 57 //config: wrapped. 50 58 //config: 51 59 //config:config FEATURE_LESS_MARKS … … 99 107 100 108 //usage:#define less_trivial_usage 101 //usage: "[-E" IF_FEATURE_LESS_FLAGS("Mm") "Nh~I?] [FILE]..." 109 //usage: "[-E" IF_FEATURE_LESS_REGEXP("I")IF_FEATURE_LESS_FLAGS("Mm") 110 //usage: "N" IF_FEATURE_LESS_TRUNCATE("S") "h~] [FILE]..." 102 111 //usage:#define less_full_usage "\n\n" 103 112 //usage: "View FILE (or stdin) one screenful at a time\n" 104 113 //usage: "\n -E Quit once the end of a file is reached" 114 //usage: IF_FEATURE_LESS_REGEXP( 115 //usage: "\n -I Ignore case in all searches" 116 //usage: ) 105 117 //usage: IF_FEATURE_LESS_FLAGS( 106 118 //usage: "\n -M,-m Display status line with line numbers" … … 108 120 //usage: ) 109 121 //usage: "\n -N Prefix line number to each line" 110 //usage: "\n -I Ignore case in all searches" 122 //usage: IF_FEATURE_LESS_TRUNCATE( 123 //usage: "\n -S Truncate long lines" 124 //usage: ) 111 125 //usage: "\n -~ Suppress ~s displayed past EOF" 112 126 … … 114 128 115 129 #include "libbb.h" 130 #include "common_bufsiz.h" 116 131 #if ENABLE_FEATURE_LESS_REGEXP 117 132 #include "xregex.h" … … 143 158 FLAG_TILDE = 1 << 4, 144 159 FLAG_I = 1 << 5, 145 FLAG_S = (1 << 6) * ENABLE_FEATURE_LESS_ DASHCMD,160 FLAG_S = (1 << 6) * ENABLE_FEATURE_LESS_TRUNCATE, 146 161 /* hijack command line options variable for internal state vars */ 147 162 LESS_STATE_MATCH_BACKWARDS = 1 << 15, … … 175 190 char *filename; 176 191 char **files; 192 #if ENABLE_FEATURE_LESS_FLAGS 193 int num_lines; /* a flag if < 0, line count if >= 0 */ 194 # define REOPEN_AND_COUNT (-1) 195 # define REOPEN_STDIN (-2) 196 # define NOT_REGULAR_FILE (-3) 197 #endif 177 198 #if ENABLE_FEATURE_LESS_MARKS 178 199 unsigned num_marks; … … 216 237 #define filename (G.filename ) 217 238 #define files (G.files ) 239 #define num_lines (G.num_lines ) 218 240 #define num_marks (G.num_marks ) 219 241 #define mark_lines (G.mark_lines ) … … 318 340 if (*d != '\0') { 319 341 new_line_pos++; 320 if (*d == '\t') /* tab */342 if (*d == '\t') { /* tab */ 321 343 new_line_pos += 7; 344 new_line_pos &= (~7); 345 } 322 346 s++; 323 347 d++; … … 381 405 #endif 382 406 407 static int at_end(void) 408 { 409 return (option_mask32 & FLAG_S) 410 ? !(cur_fline <= max_fline && 411 max_lineno > LINENO(flines[cur_fline]) + max_displayed_line) 412 : !(max_fline > cur_fline + max_displayed_line); 413 } 414 383 415 /* Devilishly complex routine. 384 416 * … … 403 435 * (takes into account tabs and backspaces) 404 436 * eof_error - < 0 error, == 0 EOF, > 0 not EOF/error 437 * 438 * "git log -p | less -m" on the kernel git tree is a good test for EAGAINs, 439 * "/search on very long input" and "reaching max line count" corner cases. 405 440 */ 406 441 static void read_lines(void) 407 442 { 408 #define readbuf bb_common_bufsiz1409 443 char *current_line, *p; 410 444 int w = width; 411 445 char last_terminated = terminated; 446 time_t last_time = 0; 447 int retry_EAGAIN = 2; 412 448 #if ENABLE_FEATURE_LESS_REGEXP 413 449 unsigned old_max_fline = max_fline; 414 time_t last_time = 0; 415 unsigned seconds_p1 = 3; /* seconds_to_loop + 1 */ 416 #endif 450 #endif 451 452 #define readbuf bb_common_bufsiz1 453 setup_common_bufsiz(); 454 455 /* (careful: max_fline can be -1) */ 456 if (max_fline + 1 > MAXLINES) 457 return; 417 458 418 459 if (option_mask32 & FLAG_N) 419 460 w -= 8; 420 461 421 IF_FEATURE_LESS_REGEXP(again0:) 422 423 p = current_line = ((char*)xmalloc(w + 4)) + 4; 424 max_fline += last_terminated; 462 p = current_line = ((char*)xmalloc(w + 5)) + 4; 425 463 if (!last_terminated) { 426 464 const char *cp = flines[max_fline]; 427 strcpy(p, cp); 428 p += strlen(current_line); 429 free(MEMPTR(flines[max_fline])); 465 p = stpcpy(p, cp); 466 free(MEMPTR(cp)); 430 467 /* last_line_pos is still valid from previous read_lines() */ 431 468 } else { 469 max_fline++; 432 470 last_line_pos = 0; 433 471 } … … 440 478 /* if no unprocessed chars left, eat more */ 441 479 if (readpos >= readeof) { 442 ndelay_on(0); 443 eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); 444 ndelay_off(0); 480 int flags = ndelay_on(0); 481 482 while (1) { 483 time_t t; 484 485 errno = 0; 486 eof_error = safe_read(STDIN_FILENO, readbuf, COMMON_BUFSIZE); 487 if (errno != EAGAIN) 488 break; 489 t = time(NULL); 490 if (t != last_time) { 491 last_time = t; 492 if (--retry_EAGAIN < 0) 493 break; 494 } 495 sched_yield(); 496 } 497 fcntl(0, F_SETFL, flags); /* ndelay_off(0) */ 445 498 readpos = 0; 446 499 readeof = eof_error; 447 500 if (eof_error <= 0) 448 501 goto reached_eof; 502 retry_EAGAIN = 1; 449 503 } 450 504 c = readbuf[readpos]; … … 465 519 new_last_line_pos &= (~7); 466 520 } 467 if ((int)new_last_line_pos > =w)521 if ((int)new_last_line_pos > w) 468 522 break; 469 523 last_line_pos = new_last_line_pos; … … 481 535 *p = '\0'; 482 536 } /* end of "read chars until we have a line" loop */ 537 #if 0 538 //BUG: also triggers on this: 539 // { printf "\nfoo\n"; sleep 1; printf "\nbar\n"; } | less 540 // (resulting in lost empty line between "foo" and "bar" lines) 541 // the "terminated" logic needs fixing (or explaining) 483 542 /* Corner case: linewrap with only "" wrapping to next line */ 484 543 /* Looks ugly on screen, so we do not store this empty line */ … … 488 547 continue; 489 548 } 549 #endif 490 550 reached_eof: 491 551 last_terminated = terminated; … … 501 561 break; 502 562 } 503 if (!(option_mask32 & FLAG_S) 504 ? (max_fline > cur_fline + max_displayed_line) 505 : (max_fline >= cur_fline 506 && max_lineno > LINENO(flines[cur_fline]) + max_displayed_line) 507 ) { 563 if (!at_end()) { 508 564 #if !ENABLE_FEATURE_LESS_REGEXP 509 565 break; … … 518 574 } 519 575 if (eof_error <= 0) { 520 if (eof_error < 0) {521 if (errno == EAGAIN) {522 /* not yet eof or error, reset flag (or else523 * we will hog CPU - select() will return524 * immediately */525 eof_error = 1;526 } else {527 print_statusline(bb_msg_read_error);528 }529 }530 #if !ENABLE_FEATURE_LESS_REGEXP531 576 break; 532 #else533 if (wanted_match < num_matches) {534 break;535 } else { /* goto_match called us */536 time_t t = time(NULL);537 if (t != last_time) {538 last_time = t;539 if (--seconds_p1 == 0)540 break;541 }542 sched_yield();543 goto again0; /* go loop again (max 2 seconds) */544 }545 #endif546 577 } 547 578 max_fline++; 548 current_line = ((char*)xmalloc(w + 4)) + 4;579 current_line = ((char*)xmalloc(w + 5)) + 4; 549 580 p = current_line; 550 581 last_line_pos = 0; 551 582 } /* end of "read lines until we reach cur_fline" loop */ 583 584 if (eof_error < 0) { 585 if (errno == EAGAIN) { 586 eof_error = 1; 587 } else { 588 print_statusline(bb_msg_read_error); 589 } 590 } 591 #if ENABLE_FEATURE_LESS_FLAGS 592 else if (eof_error == 0) 593 num_lines = max_lineno; 594 #endif 595 552 596 fill_match_lines(old_max_fline); 553 597 #if ENABLE_FEATURE_LESS_REGEXP … … 559 603 560 604 #if ENABLE_FEATURE_LESS_FLAGS 561 /* Interestingly, writing calc_percent as a function saves around 32 bytes 562 * on my build. */ 563 static int calc_percent(void) 564 { 565 unsigned p = (100 * (cur_fline+max_displayed_line+1) + max_fline/2) / (max_fline+1); 566 return p <= 100 ? p : 100; 605 static int safe_lineno(int fline) 606 { 607 if (fline >= max_fline) 608 fline = max_fline - 1; 609 610 /* also catches empty file (max_fline == 0) */ 611 if (fline < 0) 612 return 0; 613 614 return LINENO(flines[fline]) + 1; 615 } 616 617 /* count number of lines in file */ 618 static void update_num_lines(void) 619 { 620 int count, fd; 621 struct stat stbuf; 622 ssize_t len, i; 623 char buf[4096]; 624 625 /* only do this for regular files */ 626 if (num_lines == REOPEN_AND_COUNT || num_lines == REOPEN_STDIN) { 627 count = 0; 628 fd = open("/proc/self/fd/0", O_RDONLY); 629 if (fd < 0 && num_lines == REOPEN_AND_COUNT) { 630 /* "filename" is valid only if REOPEN_AND_COUNT */ 631 fd = open(filename, O_RDONLY); 632 } 633 if (fd < 0) { 634 /* somebody stole my file! */ 635 num_lines = NOT_REGULAR_FILE; 636 return; 637 } 638 if (fstat(fd, &stbuf) != 0 || !S_ISREG(stbuf.st_mode)) { 639 num_lines = NOT_REGULAR_FILE; 640 goto do_close; 641 } 642 while ((len = safe_read(fd, buf, sizeof(buf))) > 0) { 643 for (i = 0; i < len; ++i) { 644 if (buf[i] == '\n' && ++count == MAXLINES) 645 goto done; 646 } 647 } 648 done: 649 num_lines = count; 650 do_close: 651 close(fd); 652 } 567 653 } 568 654 … … 570 656 static void m_status_print(void) 571 657 { 572 int percentage; 658 int first, last; 659 unsigned percent; 573 660 574 661 if (less_gets_pos >= 0) /* don't touch statusline while input is done! */ … … 579 666 if (num_files > 1) 580 667 printf(" (file %i of %i)", current_file, num_files); 581 printf(" lines %i-%i/%i ", 582 cur_fline + 1, cur_fline + max_displayed_line + 1, 583 max_fline + 1); 584 if (cur_fline >= (int)(max_fline - max_displayed_line)) { 585 printf("(END)"NORMAL); 668 669 first = safe_lineno(cur_fline); 670 last = (option_mask32 & FLAG_S) 671 ? MIN(first + max_displayed_line, max_lineno) 672 : safe_lineno(cur_fline + max_displayed_line); 673 printf(" lines %i-%i", first, last); 674 675 update_num_lines(); 676 if (num_lines >= 0) 677 printf("/%i", num_lines); 678 679 if (at_end()) { 680 printf(" (END)"); 586 681 if (num_files > 1 && current_file != num_files) 587 printf(HIGHLIGHT" - next: %s"NORMAL, files[current_file]); 588 return; 589 } 590 percentage = calc_percent(); 591 printf("%i%%"NORMAL, percentage); 682 printf(" - next: %s", files[current_file]); 683 } else if (num_lines > 0) { 684 percent = (100 * last + num_lines/2) / num_lines; 685 printf(" %i%%", percent <= 100 ? percent : 100); 686 } 687 printf(NORMAL); 592 688 } 593 689 #endif … … 611 707 612 708 clear_line(); 613 if (cur_fline && cur_fline < (int)(max_fline - max_displayed_line)) {709 if (cur_fline && !at_end()) { 614 710 bb_putchar(':'); 615 711 return; … … 624 720 } 625 721 print_hilite(p); 626 }627 628 static void cap_cur_fline(int nlines)629 {630 int diff;631 if (cur_fline < 0)632 cur_fline = 0;633 if (cur_fline + max_displayed_line > max_fline + TILDES) {634 cur_fline -= nlines;635 if (cur_fline < 0)636 cur_fline = 0;637 diff = max_fline - (cur_fline + max_displayed_line) + TILDES;638 /* As the number of lines requested was too large, we just move639 * to the end of the file */640 if (diff > 0)641 cur_fline += diff;642 }643 722 } 644 723 … … 654 733 "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"; 655 734 656 static void lineno_str(char *nbuf9, const char *line) 657 { 658 nbuf9[0] = '\0'; 659 if (option_mask32 & FLAG_N) { 660 const char *fmt; 661 unsigned n; 662 663 if (line == empty_line_marker) { 664 memset(nbuf9, ' ', 8); 665 nbuf9[8] = '\0'; 666 return; 667 } 735 static void print_lineno(const char *line) 736 { 737 const char *fmt = " "; 738 unsigned n = n; /* for compiler */ 739 740 if (line != empty_line_marker) { 668 741 /* Width of 7 preserves tab spacing in the text */ 669 742 fmt = "%7u "; 670 743 n = LINENO(line) + 1; 671 if (n > 9999999 ) {744 if (n > 9999999 && MAXLINES > 9999999) { 672 745 n %= 10000000; 673 746 fmt = "%07u "; 674 747 } 675 sprintf(nbuf9, fmt, n);676 }748 } 749 printf(fmt, n); 677 750 } 678 751 … … 686 759 regmatch_t match_structs; 687 760 688 char buf[width]; 689 char nbuf9[9]; 761 char buf[width+1]; 690 762 const char *str = line; 691 763 char *p = buf; … … 737 809 } 738 810 739 lineno_str(nbuf9, line); 740 if (!growline) { 741 printf(CLEAR_2_EOL"%s%s\n", nbuf9, str); 742 return; 743 } 744 printf(CLEAR_2_EOL"%s%s%s\n", nbuf9, growline, str); 811 printf("%s%s\n", growline ? growline : "", str); 745 812 free(growline); 746 813 } … … 751 818 static void print_ascii(const char *str) 752 819 { 753 char buf[width]; 754 char nbuf9[9]; 820 char buf[width+1]; 755 821 char *p; 756 822 size_t n; 757 758 lineno_str(nbuf9, str);759 printf(CLEAR_2_EOL"%s", nbuf9);760 823 761 824 while (*str) { … … 791 854 792 855 move_cursor(0, 0); 793 for (i = 0; i <= max_displayed_line; i++) 856 for (i = 0; i <= max_displayed_line; i++) { 857 printf(CLEAR_2_EOL); 858 if (option_mask32 & FLAG_N) 859 print_lineno(buffer[i]); 794 860 if (pattern_valid) 795 861 print_found(buffer[i]); 796 862 else 797 863 print_ascii(buffer[i]); 864 } 865 if ((option_mask32 & FLAG_E) 866 && eof_error <= 0 867 && (max_fline - cur_fline) <= max_displayed_line 868 ) { 869 less_exit(EXIT_SUCCESS); 870 } 798 871 status_print(); 799 872 } … … 802 875 { 803 876 unsigned i; 804 #if ENABLE_FEATURE_LESS_ DASHCMD877 #if ENABLE_FEATURE_LESS_TRUNCATE 805 878 int fpos = cur_fline; 806 879 … … 834 907 } 835 908 909 /* move cur_fline to a given line number, reading lines if necessary */ 910 static void goto_lineno(int target) 911 { 912 if (target <= 0 ) { 913 cur_fline = 0; 914 } 915 else if (target > LINENO(flines[cur_fline])) { 916 retry: 917 while (LINENO(flines[cur_fline]) != target && cur_fline < max_fline) 918 ++cur_fline; 919 /* target not reached but more input is available */ 920 if (LINENO(flines[cur_fline]) != target && eof_error > 0) { 921 read_lines(); 922 goto retry; 923 } 924 } 925 else { 926 /* search backwards through already-read lines */ 927 while (LINENO(flines[cur_fline]) != target && cur_fline > 0) 928 --cur_fline; 929 } 930 } 931 932 static void cap_cur_fline(void) 933 { 934 if ((option_mask32 & FLAG_S)) { 935 if (cur_fline > max_fline) 936 cur_fline = max_fline; 937 if (LINENO(flines[cur_fline]) + max_displayed_line > max_lineno + TILDES) { 938 goto_lineno(max_lineno - max_displayed_line + TILDES); 939 read_lines(); 940 } 941 } 942 else { 943 if (cur_fline + max_displayed_line > max_fline + TILDES) 944 cur_fline = max_fline - max_displayed_line + TILDES; 945 if (cur_fline < 0) 946 cur_fline = 0; 947 } 948 } 949 836 950 /* Move the buffer up and down in the file in order to scroll */ 837 951 static void buffer_down(int nlines) 838 952 { 839 cur_fline += nlines; 953 if ((option_mask32 & FLAG_S)) 954 goto_lineno(LINENO(flines[cur_fline]) + nlines); 955 else 956 cur_fline += nlines; 840 957 read_lines(); 841 cap_cur_fline( nlines);958 cap_cur_fline(); 842 959 buffer_fill_and_print(); 843 960 } … … 845 962 static void buffer_up(int nlines) 846 963 { 847 cur_fline -= nlines; 848 if (cur_fline < 0) cur_fline = 0; 964 if ((option_mask32 & FLAG_S)) { 965 goto_lineno(LINENO(flines[cur_fline]) - nlines); 966 } 967 else { 968 cur_fline -= nlines; 969 if (cur_fline < 0) 970 cur_fline = 0; 971 } 849 972 read_lines(); 850 973 buffer_fill_and_print(); 851 974 } 852 975 976 /* display a given line where the argument can be either an index into 977 * the flines array or a line number */ 978 static void buffer_to_line(int linenum, int is_lineno) 979 { 980 if (linenum <= 0) 981 cur_fline = 0; 982 else if (is_lineno) 983 goto_lineno(linenum); 984 else 985 cur_fline = linenum; 986 read_lines(); 987 cap_cur_fline(); 988 buffer_fill_and_print(); 989 } 990 853 991 static void buffer_line(int linenum) 854 992 { 855 if (linenum < 0) 856 linenum = 0; 857 cur_fline = linenum; 858 read_lines(); 859 if (linenum + max_displayed_line > max_fline) 860 linenum = max_fline - max_displayed_line + TILDES; 861 if (linenum < 0) 862 linenum = 0; 863 cur_fline = linenum; 864 buffer_fill_and_print(); 993 buffer_to_line(linenum, FALSE); 994 } 995 996 static void buffer_lineno(int lineno) 997 { 998 buffer_to_line(lineno, TRUE); 865 999 } 866 1000 … … 869 1003 if (filename) { 870 1004 xmove_fd(xopen(filename, O_RDONLY), STDIN_FILENO); 1005 #if ENABLE_FEATURE_LESS_FLAGS 1006 num_lines = REOPEN_AND_COUNT; 1007 #endif 871 1008 } else { 872 1009 /* "less" with no arguments in argv[] */ 873 1010 /* For status line only */ 874 1011 filename = xstrdup(bb_msg_standard_input); 1012 #if ENABLE_FEATURE_LESS_FLAGS 1013 num_lines = REOPEN_STDIN; 1014 #endif 875 1015 } 876 1016 readpos = 0; … … 924 1064 rd = 1; 925 1065 /* Are we interested in stdin? */ 926 //TODO: reuse code for determining this 927 if (!(option_mask32 & FLAG_S) 928 ? !(max_fline > cur_fline + max_displayed_line) 929 : !(max_fline >= cur_fline 930 && max_lineno > LINENO(flines[cur_fline]) + max_displayed_line) 931 ) { 1066 if (at_end()) { 932 1067 if (eof_error > 0) /* did NOT reach eof yet */ 933 1068 rd = 0; /* yes, we are interested in stdin */ … … 1240 1375 while (i < sizeof(num_input)-1) { 1241 1376 keypress = less_getch(i + 1); 1242 if ((unsigned)keypress > 255 || !isdigit( num_input[i]))1377 if ((unsigned)keypress > 255 || !isdigit(keypress)) 1243 1378 break; 1244 1379 num_input[i] = keypress; … … 1264 1399 break; 1265 1400 case 'g': case '<': case 'G': case '>': 1266 cur_fline = num + max_displayed_line; 1267 read_lines(); 1268 buffer_line(num - 1); 1401 buffer_lineno(num - 1); 1269 1402 break; 1270 1403 case 'p': case '%': 1271 num = num * (max_fline / 100); /* + max_fline / 2; */ 1272 cur_fline = num + max_displayed_line; 1273 read_lines(); 1274 buffer_line(num); 1404 #if ENABLE_FEATURE_LESS_FLAGS 1405 update_num_lines(); 1406 num = num * (num_lines > 0 ? num_lines : max_lineno) / 100; 1407 #else 1408 num = num * max_lineno / 100; 1409 #endif 1410 buffer_lineno(num); 1275 1411 break; 1276 1412 #if ENABLE_FEATURE_LESS_REGEXP … … 1312 1448 option_mask32 ^= FLAG_TILDE; 1313 1449 break; 1450 #if ENABLE_FEATURE_LESS_TRUNCATE 1314 1451 case 'S': 1315 1452 option_mask32 ^= FLAG_S; 1316 1453 buffer_fill_and_print(); 1317 1454 break; 1455 #endif 1318 1456 #if ENABLE_FEATURE_LESS_LINENUMS 1319 1457 case 'N': … … 1609 1747 int less_main(int argc, char **argv) 1610 1748 { 1749 char *tty_name; 1750 int tty_fd; 1751 1611 1752 INIT_G(); 1612 1753 1613 /* TODO: -x: do not interpret backspace, -xx: tab also */ 1614 /* -xxx: newline also */ 1615 /* -w N: assume width N (-xxx -w 32: hex viewer of sorts) */ 1616 getopt32(argv, "EMmN~I" IF_FEATURE_LESS_DASHCMD("S")); 1754 /* TODO: -x: do not interpret backspace, -xx: tab also 1755 * -xxx: newline also 1756 * -w N: assume width N (-xxx -w 32: hex viewer of sorts) 1757 * -s: condense many empty lines to one 1758 * (used by some setups for manpage display) 1759 */ 1760 getopt32(argv, "EMmN~I" IF_FEATURE_LESS_TRUNCATE("S") /*ignored:*/"s"); 1617 1761 argc -= optind; 1618 1762 argv += optind; … … 1638 1782 empty_line_marker = ""; 1639 1783 1640 kbd_fd = open(CURRENT_TTY, O_RDONLY); 1641 if (kbd_fd < 0) 1642 return bb_cat(argv); 1643 ndelay_on(kbd_fd); 1784 /* Some versions of less can survive w/o controlling tty, 1785 * try to do the same. This also allows to specify an alternative 1786 * tty via "less 1<>TTY". 1787 * We don't try to use STDOUT_FILENO directly, 1788 * since we want to set this fd to non-blocking mode, 1789 * and not bother with restoring it on exit. 1790 */ 1791 tty_name = xmalloc_ttyname(STDOUT_FILENO); 1792 if (tty_name) { 1793 tty_fd = open(tty_name, O_RDONLY); 1794 free(tty_name); 1795 if (tty_fd < 0) 1796 goto try_ctty; 1797 } else { 1798 /* Try controlling tty */ 1799 try_ctty: 1800 tty_fd = open(CURRENT_TTY, O_RDONLY); 1801 if (tty_fd < 0) 1802 return bb_cat(argv); 1803 } 1804 ndelay_on(tty_fd); 1805 kbd_fd = tty_fd; /* save in a global */ 1644 1806 1645 1807 tcgetattr(kbd_fd, &term_orig); … … 1806 1968 or from within less by using the - or -- command. 1807 1969 Options may be given in one of two forms: either a single 1808 character preceded by a -, or a name prece eded by --.1970 character preceded by a -, or a name preceded by --. 1809 1971 -? ........ --help 1810 1972 Display help (from command line).
Note:
See TracChangeset
for help on using the changeset viewer.