diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-11 10:38:52 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-11 10:38:52 +0100 |
commit | c5891fe1af821dae83a8b1df088462b6989d089b (patch) | |
tree | ef426c50dfd05a3e8623408c3208a442e28e9dd7 | |
parent | 80f806cac9b418c07b149a683a4d1d989507d4d8 (diff) | |
download | busybox-w32-c5891fe1af821dae83a8b1df088462b6989d089b.tar.gz busybox-w32-c5891fe1af821dae83a8b1df088462b6989d089b.tar.bz2 busybox-w32-c5891fe1af821dae83a8b1df088462b6989d089b.zip |
more: hardcode FEATURE_USE_TERMIOS=y in this applet; code shrink
function old new delta
get_wh - 27 +27
tcsetattr_tty_TCSANOW - 18 +18
gotsig 35 27 -8
more_main 835 759 -76
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 0/2 up/down: 45/-84) Total: -39 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | util-linux/more.c | 106 |
1 files changed, 49 insertions, 57 deletions
diff --git a/util-linux/more.c b/util-linux/more.c index 934b30f8a..7fa60bdba 100644 --- a/util-linux/more.c +++ b/util-linux/more.c | |||
@@ -38,32 +38,34 @@ | |||
38 | #include "libbb.h" | 38 | #include "libbb.h" |
39 | #include "common_bufsiz.h" | 39 | #include "common_bufsiz.h" |
40 | 40 | ||
41 | /* Support for FEATURE_USE_TERMIOS */ | ||
42 | |||
43 | struct globals { | 41 | struct globals { |
44 | int cin_fileno; | 42 | int tty_fileno; |
43 | unsigned terminal_width; | ||
44 | unsigned terminal_height; | ||
45 | struct termios initial_settings; | 45 | struct termios initial_settings; |
46 | struct termios new_settings; | 46 | struct termios new_settings; |
47 | } FIX_ALIASING; | 47 | } FIX_ALIASING; |
48 | #define G (*(struct globals*)bb_common_bufsiz1) | 48 | #define G (*(struct globals*)bb_common_bufsiz1) |
49 | #define initial_settings (G.initial_settings) | ||
50 | #define new_settings (G.new_settings ) | ||
51 | #define cin_fileno (G.cin_fileno ) | ||
52 | #define INIT_G() do { setup_common_bufsiz(); } while (0) | 49 | #define INIT_G() do { setup_common_bufsiz(); } while (0) |
53 | 50 | ||
54 | #define setTermSettings(fd, argp) \ | 51 | static void get_wh(void) |
55 | do { \ | 52 | { |
56 | if (ENABLE_FEATURE_USE_TERMIOS) \ | 53 | /* never returns w, h <= 1 */ |
57 | tcsetattr(fd, TCSANOW, argp); \ | 54 | get_terminal_width_height(G.tty_fileno, &G.terminal_width, &G.terminal_height); |
58 | } while (0) | 55 | G.terminal_height -= 1; |
59 | #define getTermSettings(fd, argp) tcgetattr(fd, argp) | 56 | } |
57 | |||
58 | static void tcsetattr_tty_TCSANOW(struct termios *settings) | ||
59 | { | ||
60 | tcsetattr(G.tty_fileno, TCSANOW, settings); | ||
61 | } | ||
60 | 62 | ||
61 | static void gotsig(int sig UNUSED_PARAM) | 63 | static void gotsig(int sig UNUSED_PARAM) |
62 | { | 64 | { |
63 | /* bb_putchar_stderr doesn't use stdio buffering, | 65 | /* bb_putchar_stderr doesn't use stdio buffering, |
64 | * therefore it is safe in signal handler */ | 66 | * therefore it is safe in signal handler */ |
65 | bb_putchar_stderr('\n'); | 67 | bb_putchar_stderr('\n'); |
66 | setTermSettings(cin_fileno, &initial_settings); | 68 | tcsetattr_tty_TCSANOW(&G.initial_settings); |
67 | _exit(EXIT_FAILURE); | 69 | _exit(EXIT_FAILURE); |
68 | } | 70 | } |
69 | 71 | ||
@@ -73,22 +75,16 @@ int more_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
73 | int more_main(int argc UNUSED_PARAM, char **argv) | 75 | int more_main(int argc UNUSED_PARAM, char **argv) |
74 | { | 76 | { |
75 | int c = c; /* for compiler */ | 77 | int c = c; /* for compiler */ |
76 | int lines; | ||
77 | int input = 0; | 78 | int input = 0; |
78 | int spaces = 0; | 79 | int spaces = 0; |
79 | int please_display_more_prompt; | 80 | int please_display_more_prompt; |
80 | struct stat st; | 81 | FILE *tty; |
81 | FILE *file; | ||
82 | FILE *cin; | ||
83 | int len; | ||
84 | unsigned terminal_width; | ||
85 | unsigned terminal_height; | ||
86 | 82 | ||
87 | INIT_G(); | 83 | INIT_G(); |
88 | 84 | ||
89 | /* Parse options */ | 85 | /* Parse options */ |
90 | /* Accepted but ignored: */ | 86 | /* Accepted but ignored: */ |
91 | /* -d Display help instead of ringing bell is pressed */ | 87 | /* -d Display help instead of ringing bell */ |
92 | /* -f Count logical lines (IOW: long lines are not folded) */ | 88 | /* -f Count logical lines (IOW: long lines are not folded) */ |
93 | /* -l Do not pause after any line containing a ^L (form feed) */ | 89 | /* -l Do not pause after any line containing a ^L (form feed) */ |
94 | /* -s Squeeze blank lines into one */ | 90 | /* -s Squeeze blank lines into one */ |
@@ -100,26 +96,25 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
100 | * is not a tty and turns into cat. This makes sense. */ | 96 | * is not a tty and turns into cat. This makes sense. */ |
101 | if (!isatty(STDOUT_FILENO)) | 97 | if (!isatty(STDOUT_FILENO)) |
102 | return bb_cat(argv); | 98 | return bb_cat(argv); |
103 | cin = fopen_for_read(CURRENT_TTY); | 99 | tty = fopen_for_read(CURRENT_TTY); |
104 | if (!cin) | 100 | if (!tty) |
105 | return bb_cat(argv); | 101 | return bb_cat(argv); |
106 | 102 | ||
107 | if (ENABLE_FEATURE_USE_TERMIOS) { | 103 | G.tty_fileno = fileno(tty); |
108 | cin_fileno = fileno(cin); | 104 | tcgetattr(G.tty_fileno, &G.initial_settings); |
109 | getTermSettings(cin_fileno, &initial_settings); | 105 | G.new_settings = G.initial_settings; |
110 | new_settings = initial_settings; | 106 | G.new_settings.c_lflag &= ~(ICANON | ECHO); |
111 | new_settings.c_lflag &= ~(ICANON | ECHO); | 107 | G.new_settings.c_cc[VMIN] = 1; |
112 | new_settings.c_cc[VMIN] = 1; | 108 | G.new_settings.c_cc[VTIME] = 0; |
113 | new_settings.c_cc[VTIME] = 0; | 109 | tcsetattr_tty_TCSANOW(&G.new_settings); |
114 | setTermSettings(cin_fileno, &new_settings); | 110 | bb_signals(BB_FATAL_SIGS, gotsig); |
115 | bb_signals(0 | ||
116 | + (1 << SIGINT) | ||
117 | + (1 << SIGQUIT) | ||
118 | + (1 << SIGTERM) | ||
119 | , gotsig); | ||
120 | } | ||
121 | 111 | ||
122 | do { | 112 | do { |
113 | struct stat st; | ||
114 | FILE *file; | ||
115 | int len; | ||
116 | int lines; | ||
117 | |||
123 | file = stdin; | 118 | file = stdin; |
124 | if (*argv) { | 119 | if (*argv) { |
125 | file = fopen_or_warn(*argv, "r"); | 120 | file = fopen_or_warn(*argv, "r"); |
@@ -129,17 +124,20 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
129 | st.st_size = 0; | 124 | st.st_size = 0; |
130 | fstat(fileno(file), &st); | 125 | fstat(fileno(file), &st); |
131 | 126 | ||
132 | please_display_more_prompt = 0; | 127 | get_wh(); |
133 | /* never returns w, h <= 1 */ | ||
134 | get_terminal_width_height(fileno(cin), &terminal_width, &terminal_height); | ||
135 | terminal_height -= 1; | ||
136 | 128 | ||
129 | please_display_more_prompt = 0; | ||
137 | len = 0; | 130 | len = 0; |
138 | lines = 0; | 131 | lines = 0; |
139 | while (spaces || (c = getc(file)) != EOF) { | 132 | for (;;) { |
140 | int wrap; | 133 | int wrap; |
134 | |||
141 | if (spaces) | 135 | if (spaces) |
142 | spaces--; | 136 | spaces--; |
137 | else { | ||
138 | c = getc(file); | ||
139 | if (c == EOF) break; | ||
140 | } | ||
143 | loop_top: | 141 | loop_top: |
144 | if (input != 'r' && please_display_more_prompt) { | 142 | if (input != 'r' && please_display_more_prompt) { |
145 | len = printf("--More-- "); | 143 | len = printf("--More-- "); |
@@ -151,26 +149,26 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
151 | (int) ((uoff_t)ftello(file) / d), | 149 | (int) ((uoff_t)ftello(file) / d), |
152 | st.st_size); | 150 | st.st_size); |
153 | } | 151 | } |
154 | fflush_all(); | ||
155 | 152 | ||
156 | /* | 153 | /* |
157 | * We've just displayed the "--More--" prompt, so now we need | 154 | * We've just displayed the "--More--" prompt, so now we need |
158 | * to get input from the user. | 155 | * to get input from the user. |
159 | */ | 156 | */ |
160 | for (;;) { | 157 | for (;;) { |
161 | input = getc(cin); | 158 | fflush_all(); |
159 | input = getc(tty); | ||
162 | input = tolower(input); | 160 | input = tolower(input); |
163 | if (!ENABLE_FEATURE_USE_TERMIOS) | ||
164 | printf("\033[A"); /* cursor up */ | ||
165 | /* Erase the last message */ | 161 | /* Erase the last message */ |
166 | printf("\r%*s\r", len, ""); | 162 | printf("\r%*s\r", len, ""); |
167 | 163 | ||
164 | if (input == 'q') | ||
165 | goto end; | ||
168 | /* Due to various multibyte escape | 166 | /* Due to various multibyte escape |
169 | * sequences, it's not ok to accept | 167 | * sequences, it's not ok to accept |
170 | * any input as a command to scroll | 168 | * any input as a command to scroll |
171 | * the screen. We only allow known | 169 | * the screen. We only allow known |
172 | * commands, else we show help msg. */ | 170 | * commands, else we show help msg. */ |
173 | if (input == ' ' || input == '\n' || input == 'q' || input == 'r') | 171 | if (input == ' ' || input == '\n' || input == 'r') |
174 | break; | 172 | break; |
175 | len = printf("(Enter:next line Space:next page Q:quit R:show the rest)"); | 173 | len = printf("(Enter:next line Space:next page Q:quit R:show the rest)"); |
176 | } | 174 | } |
@@ -178,15 +176,9 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
178 | lines = 0; | 176 | lines = 0; |
179 | please_display_more_prompt = 0; | 177 | please_display_more_prompt = 0; |
180 | 178 | ||
181 | if (input == 'q') | ||
182 | goto end; | ||
183 | |||
184 | /* The user may have resized the terminal. | 179 | /* The user may have resized the terminal. |
185 | * Re-read the dimensions. */ | 180 | * Re-read the dimensions. */ |
186 | if (ENABLE_FEATURE_USE_TERMIOS) { | 181 | get_wh(); |
187 | get_terminal_width_height(cin_fileno, &terminal_width, &terminal_height); | ||
188 | terminal_height -= 1; | ||
189 | } | ||
190 | } | 182 | } |
191 | 183 | ||
192 | /* Crudely convert tabs into spaces, which are | 184 | /* Crudely convert tabs into spaces, which are |
@@ -206,11 +198,11 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
206 | * see if any characters have been hit in the _input_ stream. This | 198 | * see if any characters have been hit in the _input_ stream. This |
207 | * allows the user to quit while in the middle of a file. | 199 | * allows the user to quit while in the middle of a file. |
208 | */ | 200 | */ |
209 | wrap = (++len > terminal_width); | 201 | wrap = (++len > G.terminal_width); |
210 | if (c == '\n' || wrap) { | 202 | if (c == '\n' || wrap) { |
211 | /* Then outputting this character | 203 | /* Then outputting this character |
212 | * will move us to a new line. */ | 204 | * will move us to a new line. */ |
213 | if (++lines >= terminal_height || input == '\n') | 205 | if (++lines >= G.terminal_height || input == '\n') |
214 | please_display_more_prompt = 1; | 206 | please_display_more_prompt = 1; |
215 | len = 0; | 207 | len = 0; |
216 | } | 208 | } |
@@ -230,6 +222,6 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
230 | fflush_all(); | 222 | fflush_all(); |
231 | } while (*argv && *++argv); | 223 | } while (*argv && *++argv); |
232 | end: | 224 | end: |
233 | setTermSettings(cin_fileno, &initial_settings); | 225 | tcsetattr_tty_TCSANOW(&G.initial_settings); |
234 | return 0; | 226 | return 0; |
235 | } | 227 | } |