From 7b18107384d950358e146d42bf02b391fab5ffd6 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 28 Oct 2010 21:34:56 +0200 Subject: [PATCH] *: use _exit() in sighandlers; showkey: do not use exit-thru-sighandler While at it, make ESC sequences more readable; and removed check for isatty(stdin) in reset. Code shrink: text data bss dec hex filename 884771 936 17216 902923 dc70b busybox_old 884723 936 17216 902875 dc6db busybox_unstripped Signed-off-by: Marek Polacek Signed-off-by: Denys Vlasenko --- console-tools/reset.c | 12 ++++--- console-tools/resize.c | 2 +- console-tools/showkey.c | 73 +++++++++++++++++++---------------------- libbb/lineedit.c | 20 ++++++----- miscutils/conspy.c | 13 +++++--- miscutils/less.c | 14 ++++---- miscutils/watchdog.c | 2 +- util-linux/more.c | 14 +++++--- 8 files changed, 78 insertions(+), 72 deletions(-) diff --git a/console-tools/reset.c b/console-tools/reset.c index 7dffdea18..1806ce742 100644 --- a/console-tools/reset.c +++ b/console-tools/reset.c @@ -8,11 +8,13 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ -#include "libbb.h" - /* BTW, which "standard" package has this utility? It doesn't seem * to be ncurses, coreutils, console-tools... then what? */ +#include "libbb.h" + +#define ESC "\033" + #if ENABLE_STTY int stty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; #endif @@ -26,15 +28,15 @@ int reset_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) /* no options, no getopt */ - if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) { + if (/*isatty(STDIN_FILENO) &&*/ isatty(STDOUT_FILENO)) { /* See 'man 4 console_codes' for details: * "ESC c" -- Reset * "ESC ( K" -- Select user mapping - * "ESC [ J" -- Erase to the end of screen * "ESC [ 0 m" -- Reset all display attributes + * "ESC [ J" -- Erase to the end of screen * "ESC [ ? 25 h" -- Make cursor visible */ - printf("\033c\033(K\033[J\033[0m\033[?25h"); + printf(ESC"c" ESC"(K" ESC"[0m" ESC"[J" ESC"[?25h"); /* http://bugs.busybox.net/view.php?id=1414: * people want it to reset echo etc: */ #if ENABLE_STTY diff --git a/console-tools/resize.c b/console-tools/resize.c index 12e50a116..fdfe2a6a0 100644 --- a/console-tools/resize.c +++ b/console-tools/resize.c @@ -17,7 +17,7 @@ static void onintr(int sig UNUSED_PARAM) { tcsetattr(STDERR_FILENO, TCSANOW, old_termios_p); - exit(EXIT_FAILURE); + _exit(EXIT_FAILURE); } int resize_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; diff --git a/console-tools/showkey.c b/console-tools/showkey.c index 149ea6465..b29c84d6a 100644 --- a/console-tools/showkey.c +++ b/console-tools/showkey.c @@ -10,27 +10,7 @@ #include "libbb.h" #include -// set raw tty mode -// also used by microcom -// libbb candidates? -static void xget1(struct termios *t, struct termios *oldt) -{ - tcgetattr(STDIN_FILENO, oldt); - *t = *oldt; - cfmakeraw(t); -} - -static void xset1(struct termios *tio) -{ - int ret = tcsetattr(STDIN_FILENO, TCSAFLUSH, tio); - if (ret) { - bb_perror_msg("can't tcsetattr for stdin"); - } -} -/* - * GLOBALS - */ struct globals { int kbmode; struct termios tio, tio0; @@ -44,13 +24,22 @@ struct globals { } while (0) -static void signal_handler(int signo) +// set raw tty mode +// also used by microcom +// libbb candidates? +static void xget1(struct termios *t, struct termios *oldt) { - // restore keyboard and console settings - xset1(&tio0); - xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)kbmode); - // alarmed? -> exit 0 - exit(SIGALRM == signo); + tcgetattr(STDIN_FILENO, oldt); + *t = *oldt; + cfmakeraw(t); +} + +static void xset1(struct termios *t) +{ + int ret = tcsetattr(STDIN_FILENO, TCSAFLUSH, t); + if (ret) { + bb_perror_msg("can't tcsetattr for stdin"); + } } int showkey_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; @@ -62,20 +51,21 @@ int showkey_main(int argc UNUSED_PARAM, char **argv) OPT_s = (1<<2), // display only the raw scan-codes }; + INIT_G(); + // FIXME: aks are all mutually exclusive getopt32(argv, "aks"); - INIT_G(); - // get keyboard settings xioctl(STDIN_FILENO, KDGKBMODE, &kbmode); printf("kb mode was %s\n\nPress any keys. Program terminates %s\n\n", kbmode == K_RAW ? "RAW" : (kbmode == K_XLATE ? "XLATE" : (kbmode == K_MEDIUMRAW ? "MEDIUMRAW" : - (kbmode == K_UNICODE ? "UNICODE" : "?UNKNOWN?"))) - , (option_mask32 & OPT_a) ? "when CTRL+D pressed" : "10s after last keypress" + (kbmode == K_UNICODE ? "UNICODE" : "UNKNOWN"))) + , (option_mask32 & OPT_a) ? "on EOF (ctrl-D)" : "10s after last keypress" ); + // prepare for raw mode xget1(&tio, &tio0); // put stdin in raw mode @@ -83,34 +73,37 @@ int showkey_main(int argc UNUSED_PARAM, char **argv) if (option_mask32 & OPT_a) { unsigned char c; + // just read stdin char by char - while (1 == safe_read(STDIN_FILENO, &c, 1)) { + while (1 == read(STDIN_FILENO, &c, 1)) { printf("%3u 0%03o 0x%02x\r\n", c, c, c); if (04 /*CTRL-D*/ == c) break; } } else { - // we should exit on any signal - bb_signals(BB_FATAL_SIGS, signal_handler); // set raw keyboard mode xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)((option_mask32 & OPT_k) ? K_MEDIUMRAW : K_RAW)); + // we should exit on any signal; signals should interrupt read + bb_signals_recursive_norestart(BB_FATAL_SIGS, record_signo); + // read and show scancodes - while (1) { + while (!bb_got_signal) { char buf[18]; int i, n; + // setup 10s watchdog alarm(10); // read scancodes n = read(STDIN_FILENO, buf, sizeof(buf)); i = 0; while (i < n) { - char c = buf[i]; - // show raw scancodes ordered? -> if (option_mask32 & OPT_s) { + // show raw scancodes printf("0x%02x ", buf[i++]); - // show interpreted scancodes (default) ? -> } else { + // show interpreted scancodes (default) + char c = buf[i]; int kc; if (i+2 < n && (c & 0x7f) == 0 @@ -130,9 +123,9 @@ int showkey_main(int argc UNUSED_PARAM, char **argv) } } - // cleanup - signal_handler(SIGALRM); + // restore keyboard and console settings + xset1(&tio0); + xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)kbmode); - // should never be here! return EXIT_SUCCESS; } diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 066b569f6..68006ffba 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -94,8 +94,10 @@ static bool BB_ispunct(CHAR_T c) { return ((unsigned)c < 256 && ispunct(c)); } #endif -#define SEQ_CLEAR_TILL_END_OF_SCREEN "\033[J" -//#define SEQ_CLEAR_TILL_END_OF_LINE "\033[K" +#define ESC "\033" + +#define SEQ_CLEAR_TILL_END_OF_SCREEN ESC"[J" +//#define SEQ_CLEAR_TILL_END_OF_LINE ESC"[K" enum { @@ -446,7 +448,7 @@ static void input_backward(unsigned num) } while (--num); return; } - printf("\033[%uD", num); + printf(ESC"[%uD", num); return; } @@ -471,7 +473,7 @@ static void input_backward(unsigned num) */ unsigned sv_cursor; /* go to 1st column; go up to first line */ - printf("\r" "\033[%uA", cmdedit_y); + printf("\r" ESC"[%uA", cmdedit_y); cmdedit_y = 0; sv_cursor = cursor; put_prompt(); /* sets cursor to 0 */ @@ -488,12 +490,12 @@ static void input_backward(unsigned num) cmdedit_x = (width * cmdedit_y - num) % width; cmdedit_y -= lines_up; /* go to 1st column; go up */ - printf("\r" "\033[%uA", lines_up); + printf("\r" ESC"[%uA", lines_up); /* go to correct column. * xterm, konsole, Linux VT interpret 0 as 1 below! wow. * need to *make sure* we skip it if cmdedit_x == 0 */ if (cmdedit_x) - printf("\033[%uC", cmdedit_x); + printf(ESC"[%uC", cmdedit_x); } } @@ -501,7 +503,7 @@ static void input_backward(unsigned num) static void redraw(int y, int back_cursor) { if (y > 0) /* up y lines */ - printf("\033[%uA", y); + printf(ESC"[%uA", y); bb_putchar('\r'); put_prompt(); put_till_end_and_adv_cursor(); @@ -1626,7 +1628,7 @@ static void ask_terminal(void) pfd.events = POLLIN; if (safe_poll(&pfd, 1, 0) == 0) { S.sent_ESC_br6n = 1; - fputs("\033" "[6n", stdout); + fputs(ESC"[6n", stdout); fflush_all(); /* make terminal see it ASAP! */ } } @@ -2074,7 +2076,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li case CTRL('L'): vi_case(CTRL('L')|VI_CMDMODE_BIT:) /* Control-l -- clear screen */ - printf("\033[H"); /* cursor to top,left */ + printf(ESC"[H"); /* cursor to top,left */ redraw(0, command_len - cursor); break; #if MAX_HISTORY > 0 diff --git a/miscutils/conspy.c b/miscutils/conspy.c index 01928b35f..040fa86f3 100644 --- a/miscutils/conspy.c +++ b/miscutils/conspy.c @@ -43,6 +43,9 @@ #include "libbb.h" #include + +#define ESC "\033" + struct screen_info { unsigned char lines, cols, cursor_x, cursor_y; }; @@ -70,7 +73,7 @@ struct globals { unsigned col; unsigned line; smallint curoff; // unknown:0 cursor on:-1 cursor off:1 - char attrbuf[sizeof("\033[0;1;5;30;40m")]; + char attrbuf[sizeof(ESC"[0;1;5;30;40m")]; // remote console struct screen_info remote; // saved local tty terminfo @@ -101,7 +104,7 @@ enum { static void clrscr(void) { // Home, clear till end of screen - fputs("\033[1;1H" "\033[J", stdout); + fputs(ESC"[1;1H" ESC"[J", stdout); G.col = G.line = 0; } @@ -109,7 +112,7 @@ static void set_cursor(int state) { if (G.curoff != state) { G.curoff = state; - fputs("\033[?25", stdout); + fputs(ESC"[?25", stdout); bb_putchar("h?l"[1 + state]); } } @@ -119,7 +122,7 @@ static void gotoxy(int col, int line) if (G.col != col || G.line != line) { G.col = col; G.line = line; - printf("\033[%u;%uH", line + 1, col + 1); + printf(ESC"[%u;%uH", line + 1, col + 1); } } @@ -132,7 +135,7 @@ static void cleanup(int code) } // Reset attributes if (!BW) - fputs("\033[0m", stdout); + fputs(ESC"[0m", stdout); bb_putchar('\n'); if (code > 1) kill_myself_with_sig(code); diff --git a/miscutils/less.c b/miscutils/less.c index 500059d2a..9e12c11a7 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -28,13 +28,15 @@ #include "xregex.h" #endif + +#define ESC "\033" /* The escape codes for highlighted and normal text */ -#define HIGHLIGHT "\033[7m" -#define NORMAL "\033[0m" +#define HIGHLIGHT ESC"[7m" +#define NORMAL ESC"[0m" /* The escape code to home and clear to the end of screen */ -#define CLEAR "\033[H\033[J" +#define CLEAR ESC"[H\033[J" /* The escape code to clear to the end of line */ -#define CLEAR_2_EOL "\033[K" +#define CLEAR_2_EOL ESC"[K" enum { /* Absolute max of lines eaten */ @@ -165,12 +167,12 @@ static void set_tty_cooked(void) top-left corner of the console */ static void move_cursor(int line, int row) { - printf("\033[%u;%uH", line, row); + printf(ESC"[%u;%uH", line, row); } static void clear_line(void) { - printf("\033[%u;0H" CLEAR_2_EOL, max_displayed_line + 2); + printf(ESC"[%u;0H" CLEAR_2_EOL, max_displayed_line + 2); } static void print_hilite(const char *str) diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c index 36902a214..630782660 100644 --- a/miscutils/watchdog.c +++ b/miscutils/watchdog.c @@ -24,7 +24,7 @@ static void watchdog_shutdown(int sig UNUSED_PARAM) write(3, &V, 1); /* Magic, see watchdog-api.txt in kernel */ if (ENABLE_FEATURE_CLEAN_UP) close(3); - exit(EXIT_SUCCESS); + _exit(EXIT_SUCCESS); } int watchdog_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; diff --git a/util-linux/more.c b/util-linux/more.c index 1fd6f9ee8..788609a08 100644 --- a/util-linux/more.c +++ b/util-linux/more.c @@ -29,16 +29,20 @@ struct globals { #define new_settings (G.new_settings ) #define cin_fileno (G.cin_fileno ) -#define setTermSettings(fd, argp) do { \ - if (ENABLE_FEATURE_USE_TERMIOS) tcsetattr(fd, TCSANOW, argp); \ - } 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 gotsig(int sig UNUSED_PARAM) { - bb_putchar('\n'); + /* bb_putchar_stderr doesn't use stdio buffering, + * therefore it is safe in signal handler */ + bb_putchar_stderr('\n'); setTermSettings(cin_fileno, &initial_settings); - exit(EXIT_FAILURE); + _exit(EXIT_FAILURE); } #define CONVERTED_TAB_SIZE 8 -- 2.25.1