more: hardcode FEATURE_USE_TERMIOS=y in this applet; code shrink
No binary (build failed)
—
(log yok)
| @@ -38,32 +38,34 @@ | |
| #include "libbb.h" | |
| #include "common_bufsiz.h" | |
| - | /* Support for FEATURE_USE_TERMIOS */ |
| - | |
| struct globals { | |
| - | int cin_fileno; |
| + | int tty_fileno; |
| + | unsigned terminal_width; |
| + | unsigned terminal_height; |
| struct termios initial_settings; | |
| struct termios new_settings; | |
| } FIX_ALIASING; | |
| #define G (*(struct globals*)bb_common_bufsiz1) | |
| - | #define initial_settings (G.initial_settings) |
| - | #define new_settings (G.new_settings ) |
| - | #define cin_fileno (G.cin_fileno ) |
| #define INIT_G() do { setup_common_bufsiz(); } while (0) | |
| - | #define setTermSettings(fd, argp) \ |
| - | do { \ |
| - | if (ENABLE_FEATURE_USE_TERMIOS) \ |
| - | tcsetattr(fd, TCSANOW, argp); \ |
| - | } while (0) |
| - | #define getTermSettings(fd, argp) tcgetattr(fd, argp) |
| + | static void get_wh(void) |
| + | { |
| + | /* never returns w, h <= 1 */ |
| + | get_terminal_width_height(G.tty_fileno, &G.terminal_width, &G.terminal_height); |
| + | G.terminal_height -= 1; |
| + | } |
| + | |
| + | static void tcsetattr_tty_TCSANOW(struct termios *settings) |
| + | { |
| + | tcsetattr(G.tty_fileno, TCSANOW, settings); |
| + | } |
| static void gotsig(int sig UNUSED_PARAM) | |
| { | |
| /* bb_putchar_stderr doesn't use stdio buffering, | |
| * therefore it is safe in signal handler */ | |
| bb_putchar_stderr('\n'); | |
| - | setTermSettings(cin_fileno, &initial_settings); |
| + | tcsetattr_tty_TCSANOW(&G.initial_settings); |
| _exit(EXIT_FAILURE); | |
| } | |
| @@ -73,22 +75,16 @@ int more_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int more_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| int c = c; /* for compiler */ | |
| - | int lines; |
| int input = 0; | |
| int spaces = 0; | |
| int please_display_more_prompt; | |
| - | struct stat st; |
| - | FILE *file; |
| - | FILE *cin; |
| - | int len; |
| - | unsigned terminal_width; |
| - | unsigned terminal_height; |
| + | FILE *tty; |
| INIT_G(); | |
| /* Parse options */ | |
| /* Accepted but ignored: */ | |
| - | /* -d Display help instead of ringing bell is pressed */ |
| + | /* -d Display help instead of ringing bell */ |
| /* -f Count logical lines (IOW: long lines are not folded) */ | |
| /* -l Do not pause after any line containing a ^L (form feed) */ | |
| /* -s Squeeze blank lines into one */ | |
| @@ -100,26 +96,25 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |
| * is not a tty and turns into cat. This makes sense. */ | |
| if (!isatty(STDOUT_FILENO)) | |
| return bb_cat(argv); | |
| - | cin = fopen_for_read(CURRENT_TTY); |
| - | if (!cin) |
| + | tty = fopen_for_read(CURRENT_TTY); |
| + | if (!tty) |
| return bb_cat(argv); | |
| - | if (ENABLE_FEATURE_USE_TERMIOS) { |
| - | cin_fileno = fileno(cin); |
| - | getTermSettings(cin_fileno, &initial_settings); |
| - | new_settings = initial_settings; |
| - | new_settings.c_lflag &= ~(ICANON | ECHO); |
| - | new_settings.c_cc[VMIN] = 1; |
| - | new_settings.c_cc[VTIME] = 0; |
| - | setTermSettings(cin_fileno, &new_settings); |
| - | bb_signals(0 |
| - | + (1 << SIGINT) |
| - | + (1 << SIGQUIT) |
| - | + (1 << SIGTERM) |
| - | , gotsig); |
| - | } |
| + | G.tty_fileno = fileno(tty); |
| + | tcgetattr(G.tty_fileno, &G.initial_settings); |
| + | G.new_settings = G.initial_settings; |
| + | G.new_settings.c_lflag &= ~(ICANON | ECHO); |
| + | G.new_settings.c_cc[VMIN] = 1; |
| + | G.new_settings.c_cc[VTIME] = 0; |
| + | tcsetattr_tty_TCSANOW(&G.new_settings); |
| + | bb_signals(BB_FATAL_SIGS, gotsig); |
| do { | |
| + | struct stat st; |
| + | FILE *file; |
| + | int len; |
| + | int lines; |
| + | |
| file = stdin; | |
| if (*argv) { | |
| file = fopen_or_warn(*argv, "r"); | |
| @@ -129,17 +124,20 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |
| st.st_size = 0; | |
| fstat(fileno(file), &st); | |
| - | please_display_more_prompt = 0; |
| - | /* never returns w, h <= 1 */ |
| - | get_terminal_width_height(fileno(cin), &terminal_width, &terminal_height); |
| - | terminal_height -= 1; |
| + | get_wh(); |
| + | please_display_more_prompt = 0; |
| len = 0; | |
| lines = 0; | |
| - | while (spaces || (c = getc(file)) != EOF) { |
| + | for (;;) { |
| int wrap; | |
| + | |
| if (spaces) | |
| spaces--; | |
| + | else { |
| + | c = getc(file); |
| + | if (c == EOF) break; |
| + | } |
| loop_top: | |
| if (input != 'r' && please_display_more_prompt) { | |
| len = printf("--More-- "); | |
| @@ -151,26 +149,26 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |
| (int) ((uoff_t)ftello(file) / d), | |
| st.st_size); | |
| } | |
| - | fflush_all(); |
| /* | |
| * We've just displayed the "--More--" prompt, so now we need | |
| * to get input from the user. | |
| */ | |
| for (;;) { | |
| - | input = getc(cin); |
| + | fflush_all(); |
| + | input = getc(tty); |
| input = tolower(input); | |
| - | if (!ENABLE_FEATURE_USE_TERMIOS) |
| - | printf("\033[A"); /* cursor up */ |
| /* Erase the last message */ | |
| printf("\r%*s\r", len, ""); | |
| + | if (input == 'q') |
| + | goto end; |
| /* Due to various multibyte escape | |
| * sequences, it's not ok to accept | |
| * any input as a command to scroll | |
| * the screen. We only allow known | |
| * commands, else we show help msg. */ | |
| - | if (input == ' ' || input == '\n' || input == 'q' || input == 'r') |
| + | if (input == ' ' || input == '\n' || input == 'r') |
| break; | |
| len = printf("(Enter:next line Space:next page Q:quit R:show the rest)"); | |
| } | |
| @@ -178,15 +176,9 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |
| lines = 0; | |
| please_display_more_prompt = 0; | |
| - | if (input == 'q') |
| - | goto end; |
| - | |
| /* The user may have resized the terminal. | |
| * Re-read the dimensions. */ | |
| - | if (ENABLE_FEATURE_USE_TERMIOS) { |
| - | get_terminal_width_height(cin_fileno, &terminal_width, &terminal_height); |
| - | terminal_height -= 1; |
| - | } |
| + | get_wh(); |
| } | |
| /* Crudely convert tabs into spaces, which are | |
| @@ -206,11 +198,11 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |
| * see if any characters have been hit in the _input_ stream. This | |
| * allows the user to quit while in the middle of a file. | |
| */ | |
| - | wrap = (++len > terminal_width); |
| + | wrap = (++len > G.terminal_width); |
| if (c == '\n' || wrap) { | |
| /* Then outputting this character | |
| * will move us to a new line. */ | |
| - | if (++lines >= terminal_height || input == '\n') |
| + | if (++lines >= G.terminal_height || input == '\n') |
| please_display_more_prompt = 1; | |
| len = 0; | |
| } | |
| @@ -230,6 +222,6 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |
| fflush_all(); | |
| } while (*argv && *++argv); | |
| end: | |
| - | setTermSettings(cin_fileno, &initial_settings); |
| + | tcsetattr_tty_TCSANOW(&G.initial_settings); |
| return 0; | |
| } | |