*: use _exit() in sighandlers; showkey: do not use exit-thru-sighandler
No binary (build failed)
—
(log yok)
| @@ -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 | |
| @@ -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; | |
| @@ -10,27 +10,7 @@ | |
| #include "libbb.h" | |
| #include <linux/kd.h> | |
| - | // 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; | |
| } | |
| @@ -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 | |
| @@ -43,6 +43,9 @@ | |
| #include "libbb.h" | |
| #include <sys/kd.h> | |
| + | |
| + | #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); | |
| @@ -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) | |
| @@ -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; | |
| @@ -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 | |