diff --git a/include/usage.src.h b/include/usage.src.h index 6d17ab571..53ee7943a 100644 --- a/include/usage.src.h +++ b/include/usage.src.h @@ -163,16 +163,6 @@ INSERT #define blkid_full_usage "\n\n" \ "Print UUIDs of all filesystems" -#define bootchartd_trivial_usage \ - "start [PROG ARGS]|stop|init" -#define bootchartd_full_usage "\n\n" \ - "Create /var/log/bootchart.tgz with boot chart data\n" \ - "\nOptions:" \ - "\nstart: start background logging; with PROG, run PROG, then kill logging with USR1" \ - "\nstop: send USR1 to all bootchartd processes" \ - "\ninit: start background logging; stop when getty/xdm is seen (for init scripts)" \ - "\nUnder PID 1: as init, then exec $bootchart_init, /init, /sbin/init" \ - #define brctl_trivial_usage \ "COMMAND [BRIDGE [INTERFACE]]" #define brctl_full_usage "\n\n" \ diff --git a/init/bootchartd.c b/init/bootchartd.c index f7de13e2f..4e15da4e8 100644 --- a/init/bootchartd.c +++ b/init/bootchartd.c @@ -156,7 +156,7 @@ static int dump_procs(FILE *fp, int look_for_login_process) continue; p++; strchrnul(p, ')')[0] = '\0'; - /* If is gdm, kdm or a getty? */ + /* Is it gdm, kdm or a getty? */ if (((p[0] == 'g' || p[0] == 'k' || p[0] == 'x') && p[1] == 'd' && p[2] == 'm') || strstr(p, "getty") ) { @@ -258,13 +258,12 @@ static void finalize(char *tempdir, const char *prog) fprintf(header_fp, "profile.process = %s\n", prog); fputs("version = "BC_VERSION_STR"\n", header_fp); - if (ENABLE_FEATURE_BOOTCHARTD_BLOATED_HEADER) { char *hostname; char *kcmdline; time_t t; struct tm tm_time; - /* x2 for possible localized data */ + /* x2 for possible localized weekday/month names */ char date_buf[sizeof("Mon Jun 21 05:29:03 CEST 2010") * 2]; struct utsname unamebuf; @@ -313,16 +312,16 @@ static void finalize(char *tempdir, const char *prog) */ } -/* Usage: - * bootchartd start [PROG ARGS]: start logging in background, USR1 stops it. - * With PROG, runs PROG, then kills background logging. - * bootchartd stop: same as "killall -USR1 bootchartd" - * bootchartd init: start logging in background - * Stop when getty/gdm is seen (if AUTO_STOP_LOGGER = yes). - * Meant to be used from init scripts. - * bootchartd (pid==1): as init, but then execs $bootchart_init, /init, /sbin/init - * Meant to be used as kernel's init process. - */ +//usage:#define bootchartd_trivial_usage +//usage: "start [PROG ARGS]|stop|init" +//usage:#define bootchartd_full_usage "\n\n" +//usage: "Create /var/log/bootchart.tgz with boot chart data\n" +//usage: "\nOptions:" +//usage: "\nstart: start background logging; with PROG, run PROG, then kill logging with USR1" +//usage: "\nstop: send USR1 to all bootchartd processes" +//usage: "\ninit: start background logging; stop when getty/xdm is seen (for init scripts)" +//usage: "\nUnder PID 1: as init, then exec $bootchart_init, /init, /sbin/init" + int bootchartd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int bootchartd_main(int argc UNUSED_PARAM, char **argv) { @@ -358,7 +357,7 @@ int bootchartd_main(int argc UNUSED_PARAM, char **argv) cmd = CMD_PID1; } - /* Here we are in START or INIT state */ + /* Here we are in START, INIT or CMD_PID1 state */ /* Read config file: */ sample_period_us = 200 * 1000; @@ -422,7 +421,7 @@ int bootchartd_main(int argc UNUSED_PARAM, char **argv) execl(bootchart_init, bootchart_init, NULL); execl("/init", "init", NULL); execl("/sbin/init", "init", NULL); - bb_perror_msg_and_die("can't exec '%s'", "/sbin/init"); + bb_perror_msg_and_die("can't execute '%s'", "/sbin/init"); } if (cmd == CMD_START && argv[2]) { /* "start PROG ARGS" */ @@ -432,7 +431,7 @@ int bootchartd_main(int argc UNUSED_PARAM, char **argv) if (pid == 0) { /* child */ argv += 2; execvp(argv[0], argv); - bb_perror_msg_and_die("can't exec '%s'", argv[0]); + bb_perror_msg_and_die("can't execute '%s'", argv[0]); } /* parent */ waitpid(pid, NULL, 0); diff --git a/miscutils/conspy.c b/miscutils/conspy.c index 11105f0b8..6f2f0255c 100644 --- a/miscutils/conspy.c +++ b/miscutils/conspy.c @@ -56,31 +56,33 @@ struct globals { int size; int x, y; int kbd_fd; - unsigned width; - unsigned height; - unsigned col; - unsigned line; + int vcsa_fd; int ioerror_count; int key_count; int escape_count; int nokeys; int current; - int vcsa_fd; - uint16_t last_attr; - uint8_t last_bold; - uint8_t last_blink; - uint8_t last_fg; - uint8_t last_bg; - char attrbuf[sizeof("\033[0;1;5;30;40m")]; + // cached local tty parameters + unsigned width; + unsigned height; + unsigned col; + unsigned line; smallint curoff; + uint8_t last_attr; + uint8_t force_attr_change; + char attrbuf[sizeof("\033[0;1;5;30;40m")]; + // remote console struct screen_info remote; + // saved local tty terminfo struct termios term_orig; }; #define G (*ptr_to_globals) #define INIT_G() do { \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ - strcpy((char*)&G.last_attr, "\xff\xff\xff\xff\xff\xff" "\033["); \ + G.attrbuf[0] = '\033'; \ + G.attrbuf[1] = '['; \ + G.force_attr_change = 0xff; \ } while (0) enum { @@ -100,7 +102,6 @@ static void screen_read_close(void) char *data = G.data + G.current; xread(G.vcsa_fd, data, G.size); - G.last_attr = 0; for (i = 0; i < G.remote.lines; i++) { for (j = 0; j < G.remote.cols; j++, NEXT(data)) { unsigned x = j - G.x; // if will catch j < G.x too @@ -117,9 +118,12 @@ static void screen_read_close(void) static void screen_char(char *data) { - uint8_t attr = ATTR(data); + if (!BW) { + uint8_t attr = ATTR(data); + //uint8_t attr = ATTR(data) >> 1; // for framebuffer console + uint8_t attr_diff = (G.last_attr ^ attr) | G.force_attr_change; - if (!BW && G.last_attr != attr) { + if (attr_diff) { // Attribute layout for VGA compatible text videobuffer: // blinking text // |red bkgd @@ -143,51 +147,49 @@ static void screen_char(char *data) // green text // blue text // text 8th bit - // converting RGB color bit triad to BGR: - static const char color[8] = "04261537"; - char *ptr; - uint8_t fg, bold, bg, blink; + // converting RGB color bit triad to BGR: + static const char color[8] = "04261537"; + const uint8_t fg_mask = 0x07, bold_mask = 0x08; + const uint8_t bg_mask = 0x70, blink_mask = 0x80; + char *ptr; - G.last_attr = attr; + ptr = G.attrbuf + 2; /* skip "ESC [" */ - //attr >>= 1; // for framebuffer console - ptr = G.attrbuf + sizeof("\033[")-1; - fg = (attr & 0x07); - bold = (attr & 0x08); - bg = (attr & 0x70); - blink = (attr & 0x80); - if (G.last_bold > bold || G.last_blink > blink) { - G.last_bold = G.last_blink = 0; - G.last_bg = 0xff; - *ptr++ = '0'; - *ptr++ = ';'; - } - if (G.last_bold != bold) { - G.last_bold = bold; - *ptr++ = '1'; - *ptr++ = ';'; - } - if (G.last_blink != blink) { - G.last_blink = blink; - *ptr++ = '5'; - *ptr++ = ';'; - } - if (G.last_fg != fg) { - G.last_fg = fg; - *ptr++ = '3'; - *ptr++ = color[fg]; - *ptr++ = ';'; - } - if (G.last_bg != bg) { - G.last_bg = bg; - *ptr++ = '4'; - *ptr++ = color[bg >> 4]; - *ptr++ = ';'; - } - if (ptr != G.attrbuf + sizeof("\033[")-1) { - ptr[-1] = 'm'; - *ptr = '\0'; - fputs(G.attrbuf, stdout); + // (G.last_attr & ~attr) has 1 only where + // G.last_attr has 1 but attr has 0. + // Here we check whether we have transition + // bold->non-bold or blink->non-blink: + if ((G.last_attr & ~attr) & (bold_mask | blink_mask)) { + *ptr++ = '0'; // "reset all attrs" + *ptr++ = ';'; + // must set fg & bg, maybe need to set bold or blink: + attr_diff = attr | ~(bold_mask | blink_mask); + } + G.force_attr_change = 0; + G.last_attr = attr; + if (attr_diff & bold_mask) { + *ptr++ = '1'; + *ptr++ = ';'; + } + if (attr_diff & blink_mask) { + *ptr++ = '5'; + *ptr++ = ';'; + } + if (attr_diff & fg_mask) { + *ptr++ = '3'; + *ptr++ = color[attr & fg_mask]; + *ptr++ = ';'; + } + if (attr_diff & bg_mask) { + *ptr++ = '4'; + *ptr++ = color[(attr & bg_mask) >> 4]; + *ptr++ = ';'; + } + if (ptr != G.attrbuf + 2) { + ptr[-1] = 'm'; + *ptr = '\0'; + fputs(G.attrbuf, stdout); + } } } putchar(CHAR(data)); @@ -402,6 +404,7 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) termbuf.c_cc[VMIN] = 1; termbuf.c_cc[VTIME] = 0; tcsetattr(G.kbd_fd, TCSANOW, &termbuf); + poll_timeout_ms = 250; while (1) { struct pollfd pfd;