diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-09-14 09:42:40 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-09-14 09:42:40 +0200 |
commit | 363fb5ec4091120003b3f204996e7ff0aa354e58 (patch) | |
tree | e82b1163cd37f2fec8fb5f32c7ef9988bfbaed31 | |
parent | d72e804e6db1bd6eb2417961004b4fe33aba9384 (diff) | |
download | busybox-w32-363fb5ec4091120003b3f204996e7ff0aa354e58.tar.gz busybox-w32-363fb5ec4091120003b3f204996e7ff0aa354e58.tar.bz2 busybox-w32-363fb5ec4091120003b3f204996e7ff0aa354e58.zip |
hexedit: restore screen on exit
function old new delta
hexedit_main 998 1082 +84
restore_term - 29 +29
remap 168 173 +5
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 118/0) Total: 118 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/hexedit.c | 79 | ||||
-rw-r--r-- | miscutils/less.c | 2 |
2 files changed, 53 insertions, 28 deletions
diff --git a/miscutils/hexedit.c b/miscutils/hexedit.c index e8bc73b7e..b8627e826 100644 --- a/miscutils/hexedit.c +++ b/miscutils/hexedit.c | |||
@@ -15,19 +15,28 @@ | |||
15 | 15 | ||
16 | #include "libbb.h" | 16 | #include "libbb.h" |
17 | 17 | ||
18 | #define ESC "\033" | 18 | #define ESC "\033" |
19 | #define HOME ESC"[H" | 19 | #define HOME ESC"[H" |
20 | #define CLEAR ESC"[H"ESC"[J" | 20 | #define CLEAR ESC"[H"ESC"[J" |
21 | #define SET_ALT_SCR ESC"[?1049h" | ||
22 | #define POP_ALT_SCR ESC"[?1049l" | ||
23 | |||
24 | #undef CTRL | ||
25 | #define CTRL(c) ((c) & (uint8_t)~0x60) | ||
21 | 26 | ||
22 | struct globals { | 27 | struct globals { |
23 | smallint half; | 28 | smallint half; |
29 | smallint in_read_key; | ||
24 | int fd; | 30 | int fd; |
25 | unsigned height; | 31 | unsigned height; |
32 | unsigned row; | ||
26 | uint8_t *addr; | 33 | uint8_t *addr; |
27 | uint8_t *current_byte; | 34 | uint8_t *current_byte; |
28 | uint8_t *eof_byte; | 35 | uint8_t *eof_byte; |
29 | off_t size; | 36 | off_t size; |
30 | off_t offset; | 37 | off_t offset; |
38 | /* needs to be zero-inited, thus keeping it in G: */ | ||
39 | char read_key_buffer[KEYCODE_BUFFER_SIZE]; | ||
31 | struct termios orig_termios; | 40 | struct termios orig_termios; |
32 | }; | 41 | }; |
33 | #define G (*ptr_to_globals) | 42 | #define G (*ptr_to_globals) |
@@ -41,6 +50,24 @@ struct globals { | |||
41 | /* "12ef5670 (xx )*16 _1_3_5_7_9abcdef\n"NUL */ | 50 | /* "12ef5670 (xx )*16 _1_3_5_7_9abcdef\n"NUL */ |
42 | #define LINEBUF_SIZE (8 + 1 + 3*16 + 16 + 1 + 1 /*paranoia:*/ + 13) | 51 | #define LINEBUF_SIZE (8 + 1 + 3*16 + 16 + 1 + 1 /*paranoia:*/ + 13) |
43 | 52 | ||
53 | static void restore_term(void) | ||
54 | { | ||
55 | tcsetattr_stdin_TCSANOW(&G.orig_termios); | ||
56 | printf(POP_ALT_SCR); | ||
57 | fflush_all(); | ||
58 | } | ||
59 | |||
60 | static void sig_catcher(int sig) | ||
61 | { | ||
62 | if (!G.in_read_key) { | ||
63 | /* now it's not safe to do I/O, just inform the main loop */ | ||
64 | bb_got_signal = sig; | ||
65 | return; | ||
66 | } | ||
67 | restore_term(); | ||
68 | kill_myself_with_sig(sig); | ||
69 | } | ||
70 | |||
44 | static int format_line(char *hex, uint8_t *data, off_t offset) | 71 | static int format_line(char *hex, uint8_t *data, off_t offset) |
45 | { | 72 | { |
46 | int ofs_pos; | 73 | int ofs_pos; |
@@ -141,9 +168,10 @@ static void remap(unsigned cur_pos) | |||
141 | G.fd, | 168 | G.fd, |
142 | G.offset | 169 | G.offset |
143 | ); | 170 | ); |
144 | if (G.addr == MAP_FAILED) | 171 | if (G.addr == MAP_FAILED) { |
145 | //TODO: restore termios? | 172 | restore_term(); |
146 | bb_perror_msg_and_die("mmap"); | 173 | bb_perror_msg_and_die("mmap"); |
174 | } | ||
147 | 175 | ||
148 | G.current_byte = G.addr + cur_pos; | 176 | G.current_byte = G.addr + cur_pos; |
149 | 177 | ||
@@ -201,12 +229,6 @@ static void move_mapping_lower(void) | |||
201 | remap(pos); | 229 | remap(pos); |
202 | } | 230 | } |
203 | 231 | ||
204 | static void sig_catcher(int sig) | ||
205 | { | ||
206 | tcsetattr_stdin_TCSANOW(&G.orig_termios); | ||
207 | kill_myself_with_sig(sig); | ||
208 | } | ||
209 | |||
210 | //usage:#define hexedit_trivial_usage | 232 | //usage:#define hexedit_trivial_usage |
211 | //usage: "FILE" | 233 | //usage: "FILE" |
212 | //usage:#define hexedit_full_usage "\n\n" | 234 | //usage:#define hexedit_full_usage "\n\n" |
@@ -214,8 +236,6 @@ static void sig_catcher(int sig) | |||
214 | int hexedit_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 236 | int hexedit_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
215 | int hexedit_main(int argc UNUSED_PARAM, char **argv) | 237 | int hexedit_main(int argc UNUSED_PARAM, char **argv) |
216 | { | 238 | { |
217 | unsigned row = 0; | ||
218 | |||
219 | INIT_G(); | 239 | INIT_G(); |
220 | 240 | ||
221 | get_terminal_width_height(-1, NULL, &G.height); | 241 | get_terminal_width_height(-1, NULL, &G.height); |
@@ -237,7 +257,7 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv) | |||
237 | 257 | ||
238 | remap(0); | 258 | remap(0); |
239 | 259 | ||
240 | printf(CLEAR); | 260 | printf(SET_ALT_SCR); |
241 | redraw(); | 261 | redraw(); |
242 | printf(ESC"[1;10H"); /* position on 1st hex byte in first line */ | 262 | printf(ESC"[1;10H"); /* position on 1st hex byte in first line */ |
243 | 263 | ||
@@ -245,21 +265,22 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv) | |||
245 | //Backspace: undo | 265 | //Backspace: undo |
246 | //Enter: goto specified position | 266 | //Enter: goto specified position |
247 | //Ctrl-L: redraw | 267 | //Ctrl-L: redraw |
248 | //Ctrl-X: save and exit (maybe also Q?) | ||
249 | //Ctrl-Z: suspend | 268 | //Ctrl-Z: suspend |
250 | //'/', Ctrl-S: search | 269 | //'/', Ctrl-S: search |
251 | //TODO: go to end-of-screen on exit (for this, sighandler should interrupt read_key()) | ||
252 | //TODO: detect window resize | 270 | //TODO: detect window resize |
253 | //TODO: read-only mode if open(O_RDWR) fails? hide cursor in this case? | ||
254 | 271 | ||
255 | for (;;) { | 272 | for (;;) { |
256 | char read_key_buffer[KEYCODE_BUFFER_SIZE]; | ||
257 | unsigned cnt; | 273 | unsigned cnt; |
258 | int32_t key; | 274 | int32_t key = key; // for compiler |
259 | uint8_t byte; | 275 | uint8_t byte; |
260 | 276 | ||
261 | fflush_all(); | 277 | fflush_all(); |
262 | key = read_key(STDIN_FILENO, read_key_buffer, -1); | 278 | G.in_read_key = 1; |
279 | if (!bb_got_signal) | ||
280 | key = read_key(STDIN_FILENO, G.read_key_buffer, -1); | ||
281 | G.in_read_key = 0; | ||
282 | if (bb_got_signal) | ||
283 | key = CTRL('X'); | ||
263 | 284 | ||
264 | cnt = 1; | 285 | cnt = 1; |
265 | switch (key) { | 286 | switch (key) { |
@@ -329,9 +350,9 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv) | |||
329 | } | 350 | } |
330 | down: | 351 | down: |
331 | putchar('\n'); /* down one line, possibly scroll screen */ | 352 | putchar('\n'); /* down one line, possibly scroll screen */ |
332 | row++; | 353 | G.row++; |
333 | if (row >= G.height) { | 354 | if (G.row >= G.height) { |
334 | row--; | 355 | G.row--; |
335 | redraw_cur_line(); | 356 | redraw_cur_line(); |
336 | } | 357 | } |
337 | if (--cnt) | 358 | if (--cnt) |
@@ -371,8 +392,8 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv) | |||
371 | } | 392 | } |
372 | G.current_byte -= 16; | 393 | G.current_byte -= 16; |
373 | up: | 394 | up: |
374 | if (row != 0) { | 395 | if (G.row != 0) { |
375 | row--; | 396 | G.row--; |
376 | printf(ESC"[A"); /* up (won't scroll) */ | 397 | printf(ESC"[A"); /* up (won't scroll) */ |
377 | } else { | 398 | } else { |
378 | //printf(ESC"[T"); /* scroll up */ - not implemented on Linux VT! | 399 | //printf(ESC"[T"); /* scroll up */ - not implemented on Linux VT! |
@@ -382,8 +403,12 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv) | |||
382 | if (--cnt) | 403 | if (--cnt) |
383 | goto k_up; | 404 | goto k_up; |
384 | break; | 405 | break; |
385 | } | 406 | case CTRL('X'): |
386 | } | 407 | restore_term(); |
408 | return EXIT_SUCCESS; | ||
409 | } /* switch */ | ||
410 | } /* for (;;) */ | ||
387 | 411 | ||
412 | /* not reached */ | ||
388 | return EXIT_SUCCESS; | 413 | return EXIT_SUCCESS; |
389 | } | 414 | } |
diff --git a/miscutils/less.c b/miscutils/less.c index 241f7f8ba..f869a9e82 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
@@ -1103,7 +1103,7 @@ static int64_t getch_nowait(void) | |||
1103 | goto again; | 1103 | goto again; |
1104 | } | 1104 | } |
1105 | /* EOF/error (ssh session got killed etc) */ | 1105 | /* EOF/error (ssh session got killed etc) */ |
1106 | less_exit(0); | 1106 | less_exit(EXIT_SUCCESS); |
1107 | } | 1107 | } |
1108 | set_tty_cooked(); | 1108 | set_tty_cooked(); |
1109 | return key64; | 1109 | return key64; |