diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-09-19 14:31:44 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-09-19 14:31:44 +0000 |
| commit | debaf2fe024748cd559e86eba41bb503882bf9ff (patch) | |
| tree | 9e6273aa7867a32f20a9db0420846d2271f81b0d | |
| parent | 20b253d2d8e87587a3b9913ac76a49cdafa002ad (diff) | |
| download | busybox-w32-debaf2fe024748cd559e86eba41bb503882bf9ff.tar.gz busybox-w32-debaf2fe024748cd559e86eba41bb503882bf9ff.tar.bz2 busybox-w32-debaf2fe024748cd559e86eba41bb503882bf9ff.zip | |
stty: reorder code, reducing need in forward declarations.
added few missed bits of error checking for parameters.
| -rw-r--r-- | coreutils/stty.c | 409 |
1 files changed, 198 insertions, 211 deletions
diff --git a/coreutils/stty.c b/coreutils/stty.c index 7fa5feb0d..378e03e90 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c | |||
| @@ -371,30 +371,74 @@ enum { | |||
| 371 | 371 | ||
| 372 | /* The width of the screen, for output wrapping */ | 372 | /* The width of the screen, for output wrapping */ |
| 373 | static int max_col; | 373 | static int max_col; |
| 374 | |||
| 375 | /* Current position, to know when to wrap */ | 374 | /* Current position, to know when to wrap */ |
| 376 | static int current_col; | 375 | static int current_col; |
| 376 | static const char *device_name = bb_msg_standard_input; | ||
| 377 | 377 | ||
| 378 | static const char * visible(unsigned int ch); | 378 | /* Return a string that is the printable representation of character CH */ |
| 379 | static int recover_mode(const char *arg, struct termios *mode); | 379 | /* Adapted from `cat' by Torbjorn Granlund */ |
| 380 | static int screen_columns(void); | 380 | static const char *visible(unsigned int ch) |
| 381 | static void set_mode(const struct mode_info *info, | 381 | { |
| 382 | int reversed, struct termios *mode); | 382 | static char buf[10]; |
| 383 | static speed_t string_to_baud(const char *arg); | 383 | char *bpout = buf; |
| 384 | static tcflag_t* mode_type_flag(unsigned type, const struct termios *mode); | ||
| 385 | static void display_all(const struct termios *mode); | ||
| 386 | static void display_changed(const struct termios *mode); | ||
| 387 | static void display_recoverable(const struct termios *mode); | ||
| 388 | static void display_speed(const struct termios *mode, int fancy); | ||
| 389 | static void display_window_size(int fancy); | ||
| 390 | static void sane_mode(struct termios *mode); | ||
| 391 | static void set_control_char_or_die(const struct control_info *info, | ||
| 392 | const char *arg, struct termios *mode); | ||
| 393 | static void set_speed(enum speed_setting type, | ||
| 394 | const char *arg, struct termios *mode); | ||
| 395 | static void set_window_size(int rows, int cols); | ||
| 396 | 384 | ||
| 397 | static const char *device_name = bb_msg_standard_input; | 385 | if (ch == _POSIX_VDISABLE) |
| 386 | return "<undef>"; | ||
| 387 | |||
| 388 | if (ch >= 128) { | ||
| 389 | ch -= 128; | ||
| 390 | *bpout++ = 'M'; | ||
| 391 | *bpout++ = '-'; | ||
| 392 | } | ||
| 393 | |||
| 394 | if (ch < 32) { | ||
| 395 | *bpout++ = '^'; | ||
| 396 | *bpout++ = ch + 64; | ||
| 397 | } else if (ch < 127) { | ||
| 398 | *bpout++ = ch; | ||
| 399 | } else { | ||
| 400 | *bpout++ = '^'; | ||
| 401 | *bpout++ = '?'; | ||
| 402 | } | ||
| 403 | |||
| 404 | *bpout = '\0'; | ||
| 405 | return buf; | ||
| 406 | } | ||
| 407 | |||
| 408 | static tcflag_t *mode_type_flag(unsigned type, const struct termios *mode) | ||
| 409 | { | ||
| 410 | static const unsigned char tcflag_offsets[] = { | ||
| 411 | offsetof(struct termios, c_cflag), /* control */ | ||
| 412 | offsetof(struct termios, c_iflag), /* input */ | ||
| 413 | offsetof(struct termios, c_oflag), /* output */ | ||
| 414 | offsetof(struct termios, c_lflag), /* local */ | ||
| 415 | }; | ||
| 416 | |||
| 417 | if (type <= local) { | ||
| 418 | return (tcflag_t*) (((char*)mode) + tcflag_offsets[type]); | ||
| 419 | } | ||
| 420 | return NULL; | ||
| 421 | } | ||
| 422 | |||
| 423 | static speed_t string_to_baud_or_die(const char *arg) | ||
| 424 | { | ||
| 425 | return tty_value_to_baud(bb_xparse_number(arg, 0)); | ||
| 426 | } | ||
| 427 | |||
| 428 | static void set_speed_or_die(enum speed_setting type, const char *arg, | ||
| 429 | struct termios *mode) | ||
| 430 | { | ||
| 431 | speed_t baud; | ||
| 432 | |||
| 433 | baud = string_to_baud_or_die(arg); | ||
| 434 | |||
| 435 | if (type != output_speed) { /* either input or both */ | ||
| 436 | cfsetispeed(mode, baud); | ||
| 437 | } | ||
| 438 | if (type != input_speed) { /* either output or both */ | ||
| 439 | cfsetospeed(mode, baud); | ||
| 440 | } | ||
| 441 | } | ||
| 398 | 442 | ||
| 399 | static ATTRIBUTE_NORETURN void perror_on_device_and_die(const char *fmt) | 443 | static ATTRIBUTE_NORETURN void perror_on_device_and_die(const char *fmt) |
| 400 | { | 444 | { |
| @@ -438,6 +482,103 @@ static void wrapf(const char *message, ...) | |||
| 438 | current_col = 0; | 482 | current_col = 0; |
| 439 | } | 483 | } |
| 440 | 484 | ||
| 485 | #ifdef TIOCGWINSZ | ||
| 486 | |||
| 487 | static int get_win_size(struct winsize *win) | ||
| 488 | { | ||
| 489 | return ioctl(STDIN_FILENO, TIOCGWINSZ, (char *) win); | ||
| 490 | } | ||
| 491 | |||
| 492 | static void set_window_size(int rows, int cols) | ||
| 493 | { | ||
| 494 | struct winsize win; | ||
| 495 | |||
| 496 | if (get_win_size(&win)) { | ||
| 497 | if (errno != EINVAL) { | ||
| 498 | perror_on_device("%s"); | ||
| 499 | return; | ||
| 500 | } | ||
| 501 | memset(&win, 0, sizeof(win)); | ||
| 502 | } | ||
| 503 | |||
| 504 | if (rows >= 0) | ||
| 505 | win.ws_row = rows; | ||
| 506 | if (cols >= 0) | ||
| 507 | win.ws_col = cols; | ||
| 508 | |||
| 509 | # ifdef TIOCSSIZE | ||
| 510 | /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote: | ||
| 511 | The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel. | ||
| 512 | This comment from sys/ttold.h describes Sun's twisted logic - a better | ||
| 513 | test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0). | ||
| 514 | At any rate, the problem is gone in Solaris 2.x */ | ||
| 515 | |||
| 516 | if (win.ws_row == 0 || win.ws_col == 0) { | ||
| 517 | struct ttysize ttysz; | ||
| 518 | |||
| 519 | ttysz.ts_lines = win.ws_row; | ||
| 520 | ttysz.ts_cols = win.ws_col; | ||
| 521 | |||
| 522 | win.ws_row = win.ws_col = 1; | ||
| 523 | |||
| 524 | if ((ioctl(STDIN_FILENO, TIOCSWINSZ, (char *) &win) != 0) | ||
| 525 | || (ioctl(STDIN_FILENO, TIOCSSIZE, (char *) &ttysz) != 0)) { | ||
| 526 | perror_on_device("%s"); | ||
| 527 | } | ||
| 528 | return; | ||
| 529 | } | ||
| 530 | # endif | ||
| 531 | |||
| 532 | if (ioctl(STDIN_FILENO, TIOCSWINSZ, (char *) &win)) | ||
| 533 | perror_on_device("%s"); | ||
| 534 | } | ||
| 535 | |||
| 536 | static void display_window_size(int fancy) | ||
| 537 | { | ||
| 538 | const char *fmt_str = "%s\0%s: no size information for this device"; | ||
| 539 | struct winsize win; | ||
| 540 | |||
| 541 | if (get_win_size(&win)) { | ||
| 542 | if ((errno != EINVAL) || ((fmt_str += 2), !fancy)) { | ||
| 543 | perror_on_device(fmt_str); | ||
| 544 | } | ||
| 545 | } else { | ||
| 546 | wrapf(fancy ? "rows %d; columns %d;" : "%d %d\n", | ||
| 547 | win.ws_row, win.ws_col); | ||
| 548 | } | ||
| 549 | } | ||
| 550 | |||
| 551 | #else /* !TIOCGWINSZ */ | ||
| 552 | |||
| 553 | static inline void display_window_size(int fancy) {} | ||
| 554 | |||
| 555 | #endif /* !TIOCGWINSZ */ | ||
| 556 | |||
| 557 | static int screen_columns(void) | ||
| 558 | { | ||
| 559 | int columns; | ||
| 560 | const char *s; | ||
| 561 | |||
| 562 | #ifdef TIOCGWINSZ | ||
| 563 | struct winsize win; | ||
| 564 | |||
| 565 | /* With Solaris 2.[123], this ioctl fails and errno is set to | ||
| 566 | EINVAL for telnet (but not rlogin) sessions. | ||
| 567 | On ISC 3.0, it fails for the console and the serial port | ||
| 568 | (but it works for ptys). | ||
| 569 | It can also fail on any system when stdout isn't a tty. | ||
| 570 | In case of any failure, just use the default */ | ||
| 571 | if (get_win_size(&win) == 0 && win.ws_col > 0) | ||
| 572 | return win.ws_col; | ||
| 573 | #endif | ||
| 574 | |||
| 575 | columns = 80; | ||
| 576 | if ((s = getenv("COLUMNS"))) { | ||
| 577 | columns = atoi(s); | ||
| 578 | } | ||
| 579 | return columns; | ||
| 580 | } | ||
| 581 | |||
| 441 | static const struct suffix_mult stty_suffixes[] = { | 582 | static const struct suffix_mult stty_suffixes[] = { |
| 442 | {"b", 512 }, | 583 | {"b", 512 }, |
| 443 | {"k", 1024}, | 584 | {"k", 1024}, |
| @@ -469,9 +610,9 @@ enum { | |||
| 469 | param_rows = 2 | 0x80, | 610 | param_rows = 2 | 0x80, |
| 470 | param_cols = 3 | 0x80, | 611 | param_cols = 3 | 0x80, |
| 471 | param_size = 4, | 612 | param_size = 4, |
| 472 | param_ispeed = 5 | 0x80, | 613 | param_speed = 5, |
| 473 | param_ospeed = 6 | 0x80, | 614 | param_ispeed = 6 | 0x80, |
| 474 | param_speed = 7, | 615 | param_ospeed = 7 | 0x80, |
| 475 | }; | 616 | }; |
| 476 | 617 | ||
| 477 | static int find_param(const char *name) | 618 | static int find_param(const char *name) |
| @@ -485,13 +626,24 @@ static int find_param(const char *name) | |||
| 485 | if (streq(name, "columns")) return param_cols; | 626 | if (streq(name, "columns")) return param_cols; |
| 486 | if (streq(name, "size")) return param_size; | 627 | if (streq(name, "size")) return param_size; |
| 487 | #endif | 628 | #endif |
| 629 | if (streq(name, "speed")) return param_speed; | ||
| 488 | if (streq(name, "ispeed")) return param_ispeed; | 630 | if (streq(name, "ispeed")) return param_ispeed; |
| 489 | if (streq(name, "ospeed")) return param_ospeed; | 631 | if (streq(name, "ospeed")) return param_ospeed; |
| 490 | if (streq(name, "speed")) return param_speed; | ||
| 491 | return 0; | 632 | return 0; |
| 492 | } | 633 | } |
| 493 | 634 | ||
| 494 | 635 | ||
| 636 | static int recover_mode(const char *arg, struct termios *mode); | ||
| 637 | static void set_mode(const struct mode_info *info, | ||
| 638 | int reversed, struct termios *mode); | ||
| 639 | static void display_all(const struct termios *mode); | ||
| 640 | static void display_changed(const struct termios *mode); | ||
| 641 | static void display_recoverable(const struct termios *mode); | ||
| 642 | static void display_speed(const struct termios *mode, int fancy); | ||
| 643 | static void sane_mode(struct termios *mode); | ||
| 644 | static void set_control_char_or_die(const struct control_info *info, | ||
| 645 | const char *arg, struct termios *mode); | ||
| 646 | |||
| 495 | int stty_main(int argc, char **argv) | 647 | int stty_main(int argc, char **argv) |
| 496 | { | 648 | { |
| 497 | struct termios mode; | 649 | struct termios mode; |
| @@ -602,13 +754,19 @@ end_option: | |||
| 602 | break; | 754 | break; |
| 603 | case param_size: | 755 | case param_size: |
| 604 | #endif | 756 | #endif |
| 757 | case param_speed: | ||
| 758 | break; | ||
| 605 | case param_ispeed: | 759 | case param_ispeed: |
| 760 | /* called for the side effect of xfunc death only */ | ||
| 761 | set_speed_or_die(input_speed, argnext, &mode); | ||
| 762 | break; | ||
| 606 | case param_ospeed: | 763 | case param_ospeed: |
| 607 | case param_speed: | 764 | /* called for the side effect of xfunc death only */ |
| 765 | set_speed_or_die(output_speed, argnext, &mode); | ||
| 608 | break; | 766 | break; |
| 609 | default: | 767 | default: |
| 610 | if (recover_mode(arg, &mode) == 1) break; | 768 | if (recover_mode(arg, &mode) == 1) break; |
| 611 | if (string_to_baud(arg) != (speed_t) -1) break; | 769 | if (string_to_baud_or_die(arg) != (speed_t) -1) break; |
| 612 | bb_error_msg_and_die("invalid argument '%s'", arg); | 770 | bb_error_msg_and_die("invalid argument '%s'", arg); |
| 613 | } | 771 | } |
| 614 | noargs = 0; | 772 | noargs = 0; |
| @@ -643,7 +801,6 @@ end_option: | |||
| 643 | 801 | ||
| 644 | if (verbose_output || recoverable_output || noargs) { | 802 | if (verbose_output || recoverable_output || noargs) { |
| 645 | max_col = screen_columns(); | 803 | max_col = screen_columns(); |
| 646 | current_col = 0; | ||
| 647 | output_func(&mode); | 804 | output_func(&mode); |
| 648 | return EXIT_SUCCESS; | 805 | return EXIT_SUCCESS; |
| 649 | } | 806 | } |
| @@ -697,32 +854,31 @@ end_option: | |||
| 697 | break; | 854 | break; |
| 698 | case param_size: | 855 | case param_size: |
| 699 | max_col = screen_columns(); | 856 | max_col = screen_columns(); |
| 700 | current_col = 0; | ||
| 701 | display_window_size(0); | 857 | display_window_size(0); |
| 702 | break; | 858 | break; |
| 703 | case param_rows: | 859 | case param_rows: |
| 704 | set_window_size((int) bb_xparse_number(argnext, stty_suffixes), -1); | 860 | set_window_size((int) bb_xparse_number(argnext, stty_suffixes), -1); |
| 705 | break; | 861 | break; |
| 706 | #endif | 862 | #endif |
| 863 | case param_speed: | ||
| 864 | max_col = screen_columns(); | ||
| 865 | display_speed(&mode, 0); | ||
| 866 | break; | ||
| 707 | case param_ispeed: | 867 | case param_ispeed: |
| 708 | set_speed(input_speed, argnext, &mode); | 868 | set_speed_or_die(input_speed, argnext, &mode); |
| 709 | speed_was_set = 1; | 869 | speed_was_set = 1; |
| 710 | require_set_attr = 1; | 870 | require_set_attr = 1; |
| 711 | break; | 871 | break; |
| 712 | case param_ospeed: | 872 | case param_ospeed: |
| 713 | set_speed(output_speed, argnext, &mode); | 873 | set_speed_or_die(output_speed, argnext, &mode); |
| 714 | speed_was_set = 1; | 874 | speed_was_set = 1; |
| 715 | require_set_attr = 1; | 875 | require_set_attr = 1; |
| 716 | break; | 876 | break; |
| 717 | case param_speed: | ||
| 718 | max_col = screen_columns(); | ||
| 719 | display_speed(&mode, 0); | ||
| 720 | break; | ||
| 721 | default: | 877 | default: |
| 722 | if (recover_mode(arg, &mode) == 1) | 878 | if (recover_mode(arg, &mode) == 1) |
| 723 | require_set_attr = 1; | 879 | require_set_attr = 1; |
| 724 | else /* true: if (string_to_baud(arg) != (speed_t) -1) */ { | 880 | else /* true: if (string_to_baud_or_die(arg) != (speed_t) -1) */ { |
| 725 | set_speed(both_speeds, arg, &mode); | 881 | set_speed_or_die(both_speeds, arg, &mode); |
| 726 | speed_was_set = 1; | 882 | speed_was_set = 1; |
| 727 | require_set_attr = 1; | 883 | require_set_attr = 1; |
| 728 | } /* else - impossible (caught in the first pass): | 884 | } /* else - impossible (caught in the first pass): |
| @@ -805,8 +961,8 @@ end_option: | |||
| 805 | #define ECHOKE 0 | 961 | #define ECHOKE 0 |
| 806 | #endif | 962 | #endif |
| 807 | 963 | ||
| 808 | static void | 964 | static void set_mode(const struct mode_info *info, int reversed, |
| 809 | set_mode(const struct mode_info *info, int reversed, struct termios *mode) | 965 | struct termios *mode) |
| 810 | { | 966 | { |
| 811 | tcflag_t *bitsp; | 967 | tcflag_t *bitsp; |
| 812 | 968 | ||
| @@ -932,9 +1088,8 @@ set_mode(const struct mode_info *info, int reversed, struct termios *mode) | |||
| 932 | } | 1088 | } |
| 933 | } | 1089 | } |
| 934 | 1090 | ||
| 935 | static void | 1091 | static void set_control_char_or_die(const struct control_info *info, |
| 936 | set_control_char_or_die(const struct control_info *info, const char *arg, | 1092 | const char *arg, struct termios *mode) |
| 937 | struct termios *mode) | ||
| 938 | { | 1093 | { |
| 939 | unsigned char value; | 1094 | unsigned char value; |
| 940 | 1095 | ||
| @@ -945,143 +1100,14 @@ set_control_char_or_die(const struct control_info *info, const char *arg, | |||
| 945 | else if (streq(arg, "^-") || streq(arg, "undef")) | 1100 | else if (streq(arg, "^-") || streq(arg, "undef")) |
| 946 | value = _POSIX_VDISABLE; | 1101 | value = _POSIX_VDISABLE; |
| 947 | else if (arg[0] == '^') { /* Ignore any trailing junk (^Cjunk) */ | 1102 | else if (arg[0] == '^') { /* Ignore any trailing junk (^Cjunk) */ |
| 1103 | value = arg[1] & 0x1f; /* Non-letters get weird results */ | ||
| 948 | if (arg[1] == '?') | 1104 | if (arg[1] == '?') |
| 949 | value = 127; | 1105 | value = 127; |
| 950 | else | ||
| 951 | value = arg[1] & 0x1f; /* Non-letters get weird results */ | ||
| 952 | } else | 1106 | } else |
| 953 | value = bb_xparse_number(arg, stty_suffixes); | 1107 | value = bb_xparse_number(arg, stty_suffixes); |
| 954 | mode->c_cc[info->offset] = value; | 1108 | mode->c_cc[info->offset] = value; |
| 955 | } | 1109 | } |
| 956 | 1110 | ||
| 957 | static void | ||
| 958 | set_speed(enum speed_setting type, const char *arg, struct termios *mode) | ||
| 959 | { | ||
| 960 | speed_t baud; | ||
| 961 | |||
| 962 | baud = string_to_baud(arg); | ||
| 963 | |||
| 964 | if (type != output_speed) { /* either input or both */ | ||
| 965 | cfsetispeed(mode, baud); | ||
| 966 | } | ||
| 967 | if (type != input_speed) { /* either output or both */ | ||
| 968 | cfsetospeed(mode, baud); | ||
| 969 | } | ||
| 970 | } | ||
| 971 | |||
| 972 | #ifdef TIOCGWINSZ | ||
| 973 | |||
| 974 | static int get_win_size(struct winsize *win) | ||
| 975 | { | ||
| 976 | return ioctl(STDIN_FILENO, TIOCGWINSZ, (char *) win); | ||
| 977 | } | ||
| 978 | |||
| 979 | static void | ||
| 980 | set_window_size(int rows, int cols) | ||
| 981 | { | ||
| 982 | struct winsize win; | ||
| 983 | |||
| 984 | if (get_win_size(&win)) { | ||
| 985 | if (errno != EINVAL) { | ||
| 986 | perror_on_device("%s"); | ||
| 987 | return; | ||
| 988 | } | ||
| 989 | memset(&win, 0, sizeof(win)); | ||
| 990 | } | ||
| 991 | |||
| 992 | if (rows >= 0) | ||
| 993 | win.ws_row = rows; | ||
| 994 | if (cols >= 0) | ||
| 995 | win.ws_col = cols; | ||
| 996 | |||
| 997 | # ifdef TIOCSSIZE | ||
| 998 | /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote: | ||
| 999 | The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel. | ||
| 1000 | This comment from sys/ttold.h describes Sun's twisted logic - a better | ||
| 1001 | test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0). | ||
| 1002 | At any rate, the problem is gone in Solaris 2.x */ | ||
| 1003 | |||
| 1004 | if (win.ws_row == 0 || win.ws_col == 0) { | ||
| 1005 | struct ttysize ttysz; | ||
| 1006 | |||
| 1007 | ttysz.ts_lines = win.ws_row; | ||
| 1008 | ttysz.ts_cols = win.ws_col; | ||
| 1009 | |||
| 1010 | win.ws_row = win.ws_col = 1; | ||
| 1011 | |||
| 1012 | if ((ioctl(STDIN_FILENO, TIOCSWINSZ, (char *) &win) != 0) | ||
| 1013 | || (ioctl(STDIN_FILENO, TIOCSSIZE, (char *) &ttysz) != 0)) { | ||
| 1014 | perror_on_device("%s"); | ||
| 1015 | } | ||
| 1016 | return; | ||
| 1017 | } | ||
| 1018 | # endif | ||
| 1019 | |||
| 1020 | if (ioctl(STDIN_FILENO, TIOCSWINSZ, (char *) &win)) | ||
| 1021 | perror_on_device("%s"); | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | static void display_window_size(int fancy) | ||
| 1025 | { | ||
| 1026 | const char *fmt_str = "%s\0%s: no size information for this device"; | ||
| 1027 | struct winsize win; | ||
| 1028 | |||
| 1029 | if (get_win_size(&win)) { | ||
| 1030 | if ((errno != EINVAL) || ((fmt_str += 2), !fancy)) { | ||
| 1031 | perror_on_device(fmt_str); | ||
| 1032 | } | ||
| 1033 | } else { | ||
| 1034 | wrapf(fancy ? "rows %d; columns %d;" : "%d %d\n", | ||
| 1035 | win.ws_row, win.ws_col); | ||
| 1036 | } | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | #else /* !TIOCGWINSZ */ | ||
| 1040 | |||
| 1041 | static inline void display_window_size(int fancy) {} | ||
| 1042 | |||
| 1043 | #endif /* !TIOCGWINSZ */ | ||
| 1044 | |||
| 1045 | static int screen_columns(void) | ||
| 1046 | { | ||
| 1047 | int columns; | ||
| 1048 | const char *s; | ||
| 1049 | |||
| 1050 | #ifdef TIOCGWINSZ | ||
| 1051 | struct winsize win; | ||
| 1052 | |||
| 1053 | /* With Solaris 2.[123], this ioctl fails and errno is set to | ||
| 1054 | EINVAL for telnet (but not rlogin) sessions. | ||
| 1055 | On ISC 3.0, it fails for the console and the serial port | ||
| 1056 | (but it works for ptys). | ||
| 1057 | It can also fail on any system when stdout isn't a tty. | ||
| 1058 | In case of any failure, just use the default */ | ||
| 1059 | if (get_win_size(&win) == 0 && win.ws_col > 0) | ||
| 1060 | return win.ws_col; | ||
| 1061 | #endif | ||
| 1062 | |||
| 1063 | columns = 80; | ||
| 1064 | if ((s = getenv("COLUMNS"))) { | ||
| 1065 | columns = atoi(s); | ||
| 1066 | } | ||
| 1067 | return columns; | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | static tcflag_t *mode_type_flag(unsigned type, const struct termios *mode) | ||
| 1071 | { | ||
| 1072 | static const unsigned char tcflag_offsets[] = { | ||
| 1073 | offsetof(struct termios, c_cflag), /* control */ | ||
| 1074 | offsetof(struct termios, c_iflag), /* input */ | ||
| 1075 | offsetof(struct termios, c_oflag), /* output */ | ||
| 1076 | offsetof(struct termios, c_lflag), /* local */ | ||
| 1077 | }; | ||
| 1078 | |||
| 1079 | if (type <= local) { | ||
| 1080 | return (tcflag_t*) (((char*)mode) + tcflag_offsets[type]); | ||
| 1081 | } | ||
| 1082 | return NULL; | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | static void display_changed(const struct termios *mode) | 1111 | static void display_changed(const struct termios *mode) |
| 1086 | { | 1112 | { |
| 1087 | int i; | 1113 | int i; |
| @@ -1140,8 +1166,7 @@ static void display_changed(const struct termios *mode) | |||
| 1140 | if (current_col) wrapf("\n"); | 1166 | if (current_col) wrapf("\n"); |
| 1141 | } | 1167 | } |
| 1142 | 1168 | ||
| 1143 | static void | 1169 | static void display_all(const struct termios *mode) |
| 1144 | display_all(const struct termios *mode) | ||
| 1145 | { | 1170 | { |
| 1146 | int i; | 1171 | int i; |
| 1147 | tcflag_t *bitsp; | 1172 | tcflag_t *bitsp; |
| @@ -1214,7 +1239,6 @@ static void display_speed(const struct termios *mode, int fancy) | |||
| 1214 | static void display_recoverable(const struct termios *mode) | 1239 | static void display_recoverable(const struct termios *mode) |
| 1215 | { | 1240 | { |
| 1216 | int i; | 1241 | int i; |
| 1217 | |||
| 1218 | printf("%lx:%lx:%lx:%lx", | 1242 | printf("%lx:%lx:%lx:%lx", |
| 1219 | (unsigned long) mode->c_iflag, (unsigned long) mode->c_oflag, | 1243 | (unsigned long) mode->c_iflag, (unsigned long) mode->c_oflag, |
| 1220 | (unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag); | 1244 | (unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag); |
| @@ -1253,11 +1277,6 @@ static int recover_mode(const char *arg, struct termios *mode) | |||
| 1253 | return 1; | 1277 | return 1; |
| 1254 | } | 1278 | } |
| 1255 | 1279 | ||
| 1256 | static speed_t string_to_baud(const char *arg) | ||
| 1257 | { | ||
| 1258 | return tty_value_to_baud(bb_xparse_number(arg, 0)); | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | static void sane_mode(struct termios *mode) | 1280 | static void sane_mode(struct termios *mode) |
| 1262 | { | 1281 | { |
| 1263 | int i; | 1282 | int i; |
| @@ -1283,35 +1302,3 @@ static void sane_mode(struct termios *mode) | |||
| 1283 | } | 1302 | } |
| 1284 | } | 1303 | } |
| 1285 | } | 1304 | } |
| 1286 | |||
| 1287 | /* Return a string that is the printable representation of character CH */ | ||
| 1288 | /* Adapted from `cat' by Torbjorn Granlund */ | ||
| 1289 | |||
| 1290 | static const char *visible(unsigned int ch) | ||
| 1291 | { | ||
| 1292 | static char buf[10]; | ||
| 1293 | char *bpout = buf; | ||
| 1294 | |||
| 1295 | if (ch == _POSIX_VDISABLE) { | ||
| 1296 | return "<undef>"; | ||
| 1297 | } | ||
| 1298 | |||
| 1299 | if (ch >= 128) { | ||
| 1300 | ch -= 128; | ||
| 1301 | *bpout++ = 'M'; | ||
| 1302 | *bpout++ = '-'; | ||
| 1303 | } | ||
| 1304 | |||
| 1305 | if (ch < 32) { | ||
| 1306 | *bpout++ = '^'; | ||
| 1307 | *bpout++ = ch + 64; | ||
| 1308 | } else if (ch < 127) { | ||
| 1309 | *bpout++ = ch; | ||
| 1310 | } else { | ||
| 1311 | *bpout++ = '^'; | ||
| 1312 | *bpout++ = '?'; | ||
| 1313 | } | ||
| 1314 | |||
| 1315 | *bpout = '\0'; | ||
| 1316 | return buf; | ||
| 1317 | } | ||
