aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-09-14 09:42:40 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-09-14 09:42:40 +0200
commit363fb5ec4091120003b3f204996e7ff0aa354e58 (patch)
treee82b1163cd37f2fec8fb5f32c7ef9988bfbaed31
parentd72e804e6db1bd6eb2417961004b4fe33aba9384 (diff)
downloadbusybox-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.c79
-rw-r--r--miscutils/less.c2
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
22struct globals { 27struct 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
53static void restore_term(void)
54{
55 tcsetattr_stdin_TCSANOW(&G.orig_termios);
56 printf(POP_ALT_SCR);
57 fflush_all();
58}
59
60static 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
44static int format_line(char *hex, uint8_t *data, off_t offset) 71static 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
204static 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)
214int hexedit_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 236int hexedit_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
215int hexedit_main(int argc UNUSED_PARAM, char **argv) 237int 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;