diff options
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/conspy.c | 211 |
1 files changed, 101 insertions, 110 deletions
diff --git a/miscutils/conspy.c b/miscutils/conspy.c index 6f2f0255c..565922ca0 100644 --- a/miscutils/conspy.c +++ b/miscutils/conspy.c | |||
| @@ -46,9 +46,9 @@ struct screen_info { | |||
| 46 | unsigned char lines, cols, cursor_x, cursor_y; | 46 | unsigned char lines, cols, cursor_x, cursor_y; |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | #define CHAR(x) ((uint8_t)((x)[0])) | 49 | #define CHAR(x) (*(uint8_t*)(x)) |
| 50 | #define ATTR(x) ((uint8_t)((x)[1])) | 50 | #define ATTR(x) (((uint8_t*)(x))[1]) |
| 51 | #define NEXT(x) ((x)+=2) | 51 | #define NEXT(x) ((x) += 2) |
| 52 | #define DATA(x) (*(uint16_t*)(x)) | 52 | #define DATA(x) (*(uint16_t*)(x)) |
| 53 | 53 | ||
| 54 | struct globals { | 54 | struct globals { |
| @@ -56,25 +56,25 @@ struct globals { | |||
| 56 | int size; | 56 | int size; |
| 57 | int x, y; | 57 | int x, y; |
| 58 | int kbd_fd; | 58 | int kbd_fd; |
| 59 | int vcsa_fd; | ||
| 60 | int ioerror_count; | 59 | int ioerror_count; |
| 61 | int key_count; | 60 | int key_count; |
| 62 | int escape_count; | 61 | int escape_count; |
| 63 | int nokeys; | 62 | int nokeys; |
| 64 | int current; | 63 | int current; |
| 64 | int first_line_offset; | ||
| 65 | int last_attr; | ||
| 65 | // cached local tty parameters | 66 | // cached local tty parameters |
| 66 | unsigned width; | 67 | unsigned width; |
| 67 | unsigned height; | 68 | unsigned height; |
| 68 | unsigned col; | 69 | unsigned col; |
| 69 | unsigned line; | 70 | unsigned line; |
| 70 | smallint curoff; | 71 | smallint curoff; // unknown:0 cursor on:-1 cursor off:1 |
| 71 | uint8_t last_attr; | ||
| 72 | uint8_t force_attr_change; | ||
| 73 | char attrbuf[sizeof("\033[0;1;5;30;40m")]; | 72 | char attrbuf[sizeof("\033[0;1;5;30;40m")]; |
| 74 | // remote console | 73 | // remote console |
| 75 | struct screen_info remote; | 74 | struct screen_info remote; |
| 76 | // saved local tty terminfo | 75 | // saved local tty terminfo |
| 77 | struct termios term_orig; | 76 | struct termios term_orig; |
| 77 | char vcsa_name[sizeof("/dev/vcsaNN")]; | ||
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | #define G (*ptr_to_globals) | 80 | #define G (*ptr_to_globals) |
| @@ -82,7 +82,8 @@ struct globals { | |||
| 82 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 82 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
| 83 | G.attrbuf[0] = '\033'; \ | 83 | G.attrbuf[0] = '\033'; \ |
| 84 | G.attrbuf[1] = '['; \ | 84 | G.attrbuf[1] = '['; \ |
| 85 | G.force_attr_change = 0xff; \ | 85 | G.width = G.height = UINT_MAX; \ |
| 86 | G.last_attr--; \ | ||
| 86 | } while (0) | 87 | } while (0) |
| 87 | 88 | ||
| 88 | enum { | 89 | enum { |
| @@ -96,24 +97,80 @@ enum { | |||
| 96 | #define FLAG(x) (1 << FLAG_##x) | 97 | #define FLAG(x) (1 << FLAG_##x) |
| 97 | #define BW (option_mask32 & FLAG(n)) | 98 | #define BW (option_mask32 & FLAG(n)) |
| 98 | 99 | ||
| 100 | static void clrscr(void) | ||
| 101 | { | ||
| 102 | // Home, clear till end of screen | ||
| 103 | fputs("\033[1;1H" "\033[J", stdout); | ||
| 104 | G.col = G.line = 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | static void set_cursor(int state) | ||
| 108 | { | ||
| 109 | if (G.curoff != state) { | ||
| 110 | G.curoff = state; | ||
| 111 | fputs("\033[?25", stdout); | ||
| 112 | bb_putchar("h?l"[1 + state]); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | static void gotoxy(int col, int line) | ||
| 117 | { | ||
| 118 | if (G.col != col || G.line != line) { | ||
| 119 | G.col = col; | ||
| 120 | G.line = line; | ||
| 121 | printf("\033[%u;%uH", line + 1, col + 1); | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | static void cleanup(int code) | ||
| 126 | { | ||
| 127 | set_cursor(-1); // cursor on | ||
| 128 | tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig); | ||
| 129 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
| 130 | close(G.kbd_fd); | ||
| 131 | } | ||
| 132 | // Reset attributes | ||
| 133 | if (!BW) | ||
| 134 | fputs("\033[0m", stdout); | ||
| 135 | bb_putchar('\n'); | ||
| 136 | if (code > 1) | ||
| 137 | kill_myself_with_sig(code); | ||
| 138 | exit(code); | ||
| 139 | } | ||
| 140 | |||
| 99 | static void screen_read_close(void) | 141 | static void screen_read_close(void) |
| 100 | { | 142 | { |
| 101 | unsigned i, j; | 143 | unsigned i, j; |
| 102 | char *data = G.data + G.current; | 144 | int vcsa_fd; |
| 103 | 145 | char *data; | |
| 104 | xread(G.vcsa_fd, data, G.size); | 146 | |
| 147 | // Close & re-open vcsa in case they have swapped virtual consoles | ||
| 148 | vcsa_fd = xopen(G.vcsa_name, O_RDONLY); | ||
| 149 | xread(vcsa_fd, &G.remote, 4); | ||
| 150 | i = G.remote.cols * 2; | ||
| 151 | G.first_line_offset = G.y * i; | ||
| 152 | i *= G.remote.lines; | ||
| 153 | if (G.data == NULL) { | ||
| 154 | G.size = i; | ||
| 155 | G.data = xzalloc(2 * i); | ||
| 156 | } | ||
| 157 | else if (G.size != i) { | ||
| 158 | cleanup(1); | ||
| 159 | } | ||
| 160 | data = G.data + G.current; | ||
| 161 | xread(vcsa_fd, data, G.size); | ||
| 162 | close(vcsa_fd); | ||
| 105 | for (i = 0; i < G.remote.lines; i++) { | 163 | for (i = 0; i < G.remote.lines; i++) { |
| 106 | for (j = 0; j < G.remote.cols; j++, NEXT(data)) { | 164 | for (j = 0; j < G.remote.cols; j++, NEXT(data)) { |
| 107 | unsigned x = j - G.x; // if will catch j < G.x too | 165 | unsigned x = j - G.x; // if will catch j < G.x too |
| 108 | unsigned y = i - G.y; // if will catch i < G.y too | 166 | unsigned y = i - G.y; // if will catch i < G.y too |
| 109 | 167 | ||
| 110 | if (CHAR(data) < ' ') | 168 | if (CHAR(data) < ' ') |
| 111 | *data = ' '; // CHAR(data) = ' '; | 169 | CHAR(data) = ' '; |
| 112 | if (y >= G.height || x >= G.width) | 170 | if (y >= G.height || x >= G.width) |
| 113 | DATA(data) = 0; | 171 | DATA(data) = 0; |
| 114 | } | 172 | } |
| 115 | } | 173 | } |
| 116 | close(G.vcsa_fd); | ||
| 117 | } | 174 | } |
| 118 | 175 | ||
| 119 | static void screen_char(char *data) | 176 | static void screen_char(char *data) |
| @@ -121,7 +178,7 @@ static void screen_char(char *data) | |||
| 121 | if (!BW) { | 178 | if (!BW) { |
| 122 | uint8_t attr = ATTR(data); | 179 | uint8_t attr = ATTR(data); |
| 123 | //uint8_t attr = ATTR(data) >> 1; // for framebuffer console | 180 | //uint8_t attr = ATTR(data) >> 1; // for framebuffer console |
| 124 | uint8_t attr_diff = (G.last_attr ^ attr) | G.force_attr_change; | 181 | uint8_t attr_diff = G.last_attr ^ attr; |
| 125 | 182 | ||
| 126 | if (attr_diff) { | 183 | if (attr_diff) { |
| 127 | // Attribute layout for VGA compatible text videobuffer: | 184 | // Attribute layout for VGA compatible text videobuffer: |
| @@ -153,19 +210,20 @@ static void screen_char(char *data) | |||
| 153 | const uint8_t bg_mask = 0x70, blink_mask = 0x80; | 210 | const uint8_t bg_mask = 0x70, blink_mask = 0x80; |
| 154 | char *ptr; | 211 | char *ptr; |
| 155 | 212 | ||
| 156 | ptr = G.attrbuf + 2; /* skip "ESC [" */ | 213 | ptr = G.attrbuf + 2; // skip "ESC [" |
| 157 | 214 | ||
| 158 | // (G.last_attr & ~attr) has 1 only where | 215 | // (G.last_attr & ~attr) has 1 only where |
| 159 | // G.last_attr has 1 but attr has 0. | 216 | // G.last_attr has 1 but attr has 0. |
| 160 | // Here we check whether we have transition | 217 | // Here we check whether we have transition |
| 161 | // bold->non-bold or blink->non-blink: | 218 | // bold->non-bold or blink->non-blink: |
| 162 | if ((G.last_attr & ~attr) & (bold_mask | blink_mask)) { | 219 | if (G.last_attr < 0 // initial value |
| 220 | || ((G.last_attr & ~attr) & (bold_mask | blink_mask)) != 0 | ||
| 221 | ) { | ||
| 163 | *ptr++ = '0'; // "reset all attrs" | 222 | *ptr++ = '0'; // "reset all attrs" |
| 164 | *ptr++ = ';'; | 223 | *ptr++ = ';'; |
| 165 | // must set fg & bg, maybe need to set bold or blink: | 224 | // must set fg & bg, maybe need to set bold or blink: |
| 166 | attr_diff = attr | ~(bold_mask | blink_mask); | 225 | attr_diff = attr | ~(bold_mask | blink_mask); |
| 167 | } | 226 | } |
| 168 | G.force_attr_change = 0; | ||
| 169 | G.last_attr = attr; | 227 | G.last_attr = attr; |
| 170 | if (attr_diff & bold_mask) { | 228 | if (attr_diff & bold_mask) { |
| 171 | *ptr++ = '1'; | 229 | *ptr++ = '1'; |
| @@ -196,44 +254,12 @@ static void screen_char(char *data) | |||
| 196 | G.col++; | 254 | G.col++; |
| 197 | } | 255 | } |
| 198 | 256 | ||
| 199 | static void clrscr(void) | ||
| 200 | { | ||
| 201 | // Home, clear till end of src, cursor on | ||
| 202 | fputs("\033[1;1H" "\033[J" "\033[?25h", stdout); | ||
| 203 | G.curoff = G.col = G.line = 0; | ||
| 204 | } | ||
| 205 | |||
| 206 | static void curoff(void) | ||
| 207 | { | ||
| 208 | if (!G.curoff) { | ||
| 209 | G.curoff = 1; | ||
| 210 | fputs("\033[?25l", stdout); | ||
| 211 | } | ||
| 212 | } | ||
| 213 | |||
| 214 | static void curon(void) | ||
| 215 | { | ||
| 216 | if (G.curoff) { | ||
| 217 | G.curoff = 0; | ||
| 218 | fputs("\033[?25h", stdout); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | |||
| 222 | static void gotoxy(int col, int line) | ||
| 223 | { | ||
| 224 | if (G.col != col || G.line != line) { | ||
| 225 | G.col = col; | ||
| 226 | G.line = line; | ||
| 227 | printf("\033[%u;%uH", line + 1, col + 1); | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | static void screen_dump(void) | 257 | static void screen_dump(void) |
| 232 | { | 258 | { |
| 233 | int linefeed_cnt; | 259 | int linefeed_cnt; |
| 234 | int line, col; | 260 | int line, col; |
| 235 | int linecnt = G.remote.lines - G.y; | 261 | int linecnt = G.remote.lines - G.y; |
| 236 | char *data = G.data + G.current + (2 * G.y * G.remote.cols); | 262 | char *data = G.data + G.current + G.first_line_offset; |
| 237 | 263 | ||
| 238 | linefeed_cnt = 0; | 264 | linefeed_cnt = 0; |
| 239 | for (line = 0; line < linecnt && line < G.height; line++) { | 265 | for (line = 0; line < linecnt && line < G.height; line++) { |
| @@ -263,41 +289,13 @@ static void curmove(void) | |||
| 263 | { | 289 | { |
| 264 | unsigned cx = G.remote.cursor_x - G.x; | 290 | unsigned cx = G.remote.cursor_x - G.x; |
| 265 | unsigned cy = G.remote.cursor_y - G.y; | 291 | unsigned cy = G.remote.cursor_y - G.y; |
| 292 | int cursor = 1; | ||
| 266 | 293 | ||
| 267 | if (cx >= G.width || cy >= G.height) { | 294 | if (cx < G.width && cy < G.height) { |
| 268 | curoff(); | ||
| 269 | } else { | ||
| 270 | curon(); | ||
| 271 | gotoxy(cx, cy); | 295 | gotoxy(cx, cy); |
| 296 | cursor = -1; | ||
| 272 | } | 297 | } |
| 273 | fflush_all(); | 298 | set_cursor(cursor); |
| 274 | } | ||
| 275 | |||
| 276 | static void cleanup(int code) | ||
| 277 | { | ||
| 278 | curon(); | ||
| 279 | fflush_all(); | ||
| 280 | tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig); | ||
| 281 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
| 282 | close(G.kbd_fd); | ||
| 283 | } | ||
| 284 | // Reset attributes | ||
| 285 | if (!BW) | ||
| 286 | fputs("\033[0m", stdout); | ||
| 287 | bb_putchar('\n'); | ||
| 288 | if (code > 1) | ||
| 289 | kill_myself_with_sig(code); // does not return | ||
| 290 | exit(code); | ||
| 291 | } | ||
| 292 | |||
| 293 | static void get_initial_data(const char* vcsa_name) | ||
| 294 | { | ||
| 295 | G.vcsa_fd = xopen(vcsa_name, O_RDONLY); | ||
| 296 | xread(G.vcsa_fd, &G.remote, 4); | ||
| 297 | G.size = G.remote.cols * G.remote.lines * 2; | ||
| 298 | G.width = G.height = UINT_MAX; | ||
| 299 | G.data = xzalloc(2 * G.size); | ||
| 300 | screen_read_close(); | ||
| 301 | } | 299 | } |
| 302 | 300 | ||
| 303 | static void create_cdev_if_doesnt_exist(const char* name, dev_t dev) | 301 | static void create_cdev_if_doesnt_exist(const char* name, dev_t dev) |
| @@ -345,7 +343,6 @@ static NOINLINE void start_shell_in_child(const char* tty_name) | |||
| 345 | int conspy_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 343 | int conspy_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 346 | int conspy_main(int argc UNUSED_PARAM, char **argv) | 344 | int conspy_main(int argc UNUSED_PARAM, char **argv) |
| 347 | { | 345 | { |
| 348 | char vcsa_name[sizeof("/dev/vcsaNN")]; | ||
| 349 | char tty_name[sizeof("/dev/ttyNN")]; | 346 | char tty_name[sizeof("/dev/ttyNN")]; |
| 350 | #define keybuf bb_common_bufsiz1 | 347 | #define keybuf bb_common_bufsiz1 |
| 351 | struct termios termbuf; | 348 | struct termios termbuf; |
| @@ -365,7 +362,7 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
| 365 | applet_long_options = getopt_longopts; | 362 | applet_long_options = getopt_longopts; |
| 366 | #endif | 363 | #endif |
| 367 | INIT_G(); | 364 | INIT_G(); |
| 368 | strcpy(vcsa_name, "/dev/vcsa"); | 365 | strcpy(G.vcsa_name, "/dev/vcsa"); |
| 369 | 366 | ||
| 370 | opt_complementary = "x+:y+"; // numeric params | 367 | opt_complementary = "x+:y+"; // numeric params |
| 371 | opts = getopt32(argv, "vcsndfx:y:", &G.x, &G.y); | 368 | opts = getopt32(argv, "vcsndfx:y:", &G.x, &G.y); |
| @@ -373,19 +370,19 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
| 373 | ttynum = 0; | 370 | ttynum = 0; |
| 374 | if (argv[0]) { | 371 | if (argv[0]) { |
| 375 | ttynum = xatou_range(argv[0], 0, 63); | 372 | ttynum = xatou_range(argv[0], 0, 63); |
| 376 | sprintf(vcsa_name + sizeof("/dev/vcsa")-1, "%u", ttynum); | 373 | sprintf(G.vcsa_name + sizeof("/dev/vcsa")-1, "%u", ttynum); |
| 377 | } | 374 | } |
| 378 | sprintf(tty_name, "%s%u", "/dev/tty", ttynum); | 375 | sprintf(tty_name, "%s%u", "/dev/tty", ttynum); |
| 379 | if (opts & FLAG(c)) { | 376 | if (opts & FLAG(c)) { |
| 380 | if ((opts & (FLAG(s)|FLAG(v))) != FLAG(v)) | 377 | if ((opts & (FLAG(s)|FLAG(v))) != FLAG(v)) |
| 381 | create_cdev_if_doesnt_exist(tty_name, makedev(4, ttynum)); | 378 | create_cdev_if_doesnt_exist(tty_name, makedev(4, ttynum)); |
| 382 | create_cdev_if_doesnt_exist(vcsa_name, makedev(7, 128 + ttynum)); | 379 | create_cdev_if_doesnt_exist(G.vcsa_name, makedev(7, 128 + ttynum)); |
| 383 | } | 380 | } |
| 384 | if ((opts & FLAG(s)) && ttynum) { | 381 | if ((opts & FLAG(s)) && ttynum) { |
| 385 | start_shell_in_child(tty_name); | 382 | start_shell_in_child(tty_name); |
| 386 | } | 383 | } |
| 387 | 384 | ||
| 388 | get_initial_data(vcsa_name); | 385 | screen_read_close(); |
| 389 | if (opts & FLAG(d)) { | 386 | if (opts & FLAG(d)) { |
| 390 | screen_dump(); | 387 | screen_dump(); |
| 391 | bb_putchar('\n'); | 388 | bb_putchar('\n'); |
| @@ -412,17 +409,11 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
| 412 | int i, j; | 409 | int i, j; |
| 413 | char *data, *old; | 410 | char *data, *old; |
| 414 | 411 | ||
| 415 | // Close & re-open vcsa in case they have | 412 | // in the first loop G.width = G.height = 0: refresh |
| 416 | // swapped virtual consoles | ||
| 417 | G.vcsa_fd = xopen(vcsa_name, O_RDONLY); | ||
| 418 | xread(G.vcsa_fd, &G.remote, 4); | ||
| 419 | if (G.size != (G.remote.cols * G.remote.lines * 2)) { | ||
| 420 | cleanup(1); | ||
| 421 | } | ||
| 422 | i = G.width; | 413 | i = G.width; |
| 423 | j = G.height; | 414 | j = G.height; |
| 424 | get_terminal_width_height(G.kbd_fd, &G.width, &G.height); | 415 | get_terminal_width_height(G.kbd_fd, &G.width, &G.height); |
| 425 | if ((option_mask32 & FLAG(f))) { | 416 | if (option_mask32 & FLAG(f)) { |
| 426 | int nx = G.remote.cursor_x - G.width + 1; | 417 | int nx = G.remote.cursor_x - G.width + 1; |
| 427 | int ny = G.remote.cursor_y - G.height + 1; | 418 | int ny = G.remote.cursor_y - G.height + 1; |
| 428 | 419 | ||
| @@ -454,8 +445,8 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
| 454 | screen_dump(); | 445 | screen_dump(); |
| 455 | } else { | 446 | } else { |
| 456 | // For each remote line | 447 | // For each remote line |
| 457 | old += G.y * G.remote.cols * 2; | 448 | old += G.first_line_offset; |
| 458 | data += G.y * G.remote.cols * 2; | 449 | data += G.first_line_offset; |
| 459 | for (i = G.y; i < G.remote.lines; i++) { | 450 | for (i = G.y; i < G.remote.lines; i++) { |
| 460 | char *first = NULL; // first char which needs updating | 451 | char *first = NULL; // first char which needs updating |
| 461 | char *last = last; // last char which needs updating | 452 | char *last = last; // last char which needs updating |
| @@ -463,10 +454,8 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
| 463 | 454 | ||
| 464 | if (iy >= G.height) | 455 | if (iy >= G.height) |
| 465 | break; | 456 | break; |
| 466 | old += G.x * 2; | 457 | for (j = 0; j < G.remote.cols; j++, NEXT(old), NEXT(data)) { |
| 467 | data += G.x * 2; | 458 | unsigned jx = j - G.x; // if will catch j >= G.x too |
| 468 | for (j = G.x; j < G.remote.cols; j++, NEXT(old), NEXT(data)) { | ||
| 469 | unsigned jx = j - G.x; | ||
| 470 | 459 | ||
| 471 | if (jx < G.width && DATA(data) != DATA(old)) { | 460 | if (jx < G.width && DATA(data) != DATA(old)) { |
| 472 | last = data; | 461 | last = data; |
| @@ -486,6 +475,7 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
| 486 | curmove(); | 475 | curmove(); |
| 487 | 476 | ||
| 488 | // Wait for local user keypresses | 477 | // Wait for local user keypresses |
| 478 | fflush_all(); | ||
| 489 | pfd.fd = G.kbd_fd; | 479 | pfd.fd = G.kbd_fd; |
| 490 | pfd.events = POLLIN; | 480 | pfd.events = POLLIN; |
| 491 | bytes_read = 0; | 481 | bytes_read = 0; |
| @@ -532,15 +522,16 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
| 532 | else if (kbd_mode != K_XLATE && kbd_mode != K_UNICODE) | 522 | else if (kbd_mode != K_XLATE && kbd_mode != K_UNICODE) |
| 533 | G.key_count = 0; // scan code mode | 523 | G.key_count = 0; // scan code mode |
| 534 | else { | 524 | else { |
| 535 | for (i = 0; i < G.key_count && result != -1; i++) | 525 | char *p = keybuf; |
| 536 | result = ioctl(handle, TIOCSTI, keybuf + i); | 526 | for (; G.key_count != 0 && result != -1; p++, G.key_count--) { |
| 537 | G.key_count -= i; | 527 | result = ioctl(handle, TIOCSTI, p); |
| 528 | // If there is an application on console which reacts | ||
| 529 | // to keypresses, we need to make our first sleep | ||
| 530 | // shorter to quickly redraw whatever it printed there. | ||
| 531 | poll_timeout_ms = 20; | ||
| 532 | } | ||
| 538 | if (G.key_count) | 533 | if (G.key_count) |
| 539 | memmove(keybuf, keybuf + i, G.key_count); | 534 | memmove(keybuf, p, G.key_count); |
| 540 | // If there is an application on console which reacts | ||
| 541 | // to keypresses, we need to make our first sleep | ||
| 542 | // shorter to quickly redraw whatever it printed there. | ||
| 543 | poll_timeout_ms = 20; | ||
| 544 | } | 535 | } |
| 545 | // Close & re-open tty in case they have | 536 | // Close & re-open tty in case they have |
| 546 | // swapped virtual consoles | 537 | // swapped virtual consoles |
| @@ -553,5 +544,5 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
| 553 | else if (errno != EIO || ++G.ioerror_count > 4) | 544 | else if (errno != EIO || ++G.ioerror_count > 4) |
| 554 | cleanup(1); | 545 | cleanup(1); |
| 555 | } | 546 | } |
| 556 | } | 547 | } /* while (1) */ |
| 557 | } | 548 | } |
