diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-12 21:02:04 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-12 21:02:04 +0000 |
commit | f8abc100cc84c370f7c595846c74ab46456faccb (patch) | |
tree | f49034e2a17d8fe1dd040b0a178811b82557927b /coreutils/stty.c | |
parent | 4df8135cf6f4c4055a6eeb56eab6fd794c348a72 (diff) | |
download | busybox-w32-f8abc100cc84c370f7c595846c74ab46456faccb.tar.gz busybox-w32-f8abc100cc84c370f7c595846c74ab46456faccb.tar.bz2 busybox-w32-f8abc100cc84c370f7c595846c74ab46456faccb.zip |
stty: rearrange functions, avoiding the need in forward declarations.
No other code chages.
Diffstat (limited to 'coreutils/stty.c')
-rw-r--r-- | coreutils/stty.c | 760 |
1 files changed, 374 insertions, 386 deletions
diff --git a/coreutils/stty.c b/coreutils/stty.c index b48941429..93919b33a 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c | |||
@@ -637,17 +637,382 @@ static int find_param(const char *name) | |||
637 | return 0; | 637 | return 0; |
638 | } | 638 | } |
639 | 639 | ||
640 | static int recover_mode(const char *arg, struct termios *mode) | ||
641 | { | ||
642 | int i, n; | ||
643 | unsigned int chr; | ||
644 | unsigned long iflag, oflag, cflag, lflag; | ||
645 | |||
646 | /* Scan into temporaries since it is too much trouble to figure out | ||
647 | the right format for 'tcflag_t' */ | ||
648 | if (sscanf(arg, "%lx:%lx:%lx:%lx%n", | ||
649 | &iflag, &oflag, &cflag, &lflag, &n) != 4) | ||
650 | return 0; | ||
651 | mode->c_iflag = iflag; | ||
652 | mode->c_oflag = oflag; | ||
653 | mode->c_cflag = cflag; | ||
654 | mode->c_lflag = lflag; | ||
655 | arg += n; | ||
656 | for (i = 0; i < NCCS; ++i) { | ||
657 | if (sscanf(arg, ":%x%n", &chr, &n) != 1) | ||
658 | return 0; | ||
659 | mode->c_cc[i] = chr; | ||
660 | arg += n; | ||
661 | } | ||
662 | |||
663 | /* Fail if there are too many fields */ | ||
664 | if (*arg != '\0') | ||
665 | return 0; | ||
666 | |||
667 | return 1; | ||
668 | } | ||
669 | |||
670 | static void display_recoverable(const struct termios *mode) | ||
671 | { | ||
672 | int i; | ||
673 | printf("%lx:%lx:%lx:%lx", | ||
674 | (unsigned long) mode->c_iflag, (unsigned long) mode->c_oflag, | ||
675 | (unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag); | ||
676 | for (i = 0; i < NCCS; ++i) | ||
677 | printf(":%x", (unsigned int) mode->c_cc[i]); | ||
678 | putchar('\n'); | ||
679 | } | ||
680 | |||
681 | static void display_speed(const struct termios *mode, int fancy) | ||
682 | { | ||
683 | //01234567 8 9 | ||
684 | const char *fmt_str = "%lu %lu\n\0ispeed %lu baud; ospeed %lu baud;"; | ||
685 | unsigned long ispeed, ospeed; | ||
686 | |||
687 | ospeed = ispeed = cfgetispeed(mode); | ||
688 | if (ispeed == 0 || ispeed == (ospeed = cfgetospeed(mode))) { | ||
689 | ispeed = ospeed; /* in case ispeed was 0 */ | ||
690 | //0123 4 5 6 7 8 9 | ||
691 | fmt_str = "%lu\n\0\0\0\0\0speed %lu baud;"; | ||
692 | } | ||
693 | if (fancy) fmt_str += 9; | ||
694 | wrapf(fmt_str, tty_baud_to_value(ispeed), tty_baud_to_value(ospeed)); | ||
695 | } | ||
696 | |||
697 | static void display_all(const struct termios *mode) | ||
698 | { | ||
699 | int i; | ||
700 | tcflag_t *bitsp; | ||
701 | unsigned long mask; | ||
702 | int prev_type = control; | ||
703 | |||
704 | display_speed(mode, 1); | ||
705 | display_window_size(1); | ||
706 | #ifdef HAVE_C_LINE | ||
707 | wrapf("line = %d;\n", mode->c_line); | ||
708 | #else | ||
709 | wrapf("\n"); | ||
710 | #endif | ||
711 | |||
712 | for (i = 0; control_info[i].name != stty_min; ++i) { | ||
713 | /* If swtch is the same as susp, don't print both */ | ||
714 | #if VSWTCH == VSUSP | ||
715 | if (control_info[i].name == stty_swtch) | ||
716 | continue; | ||
717 | #endif | ||
718 | /* If eof uses the same slot as min, only print whichever applies */ | ||
719 | #if VEOF == VMIN | ||
720 | if ((mode->c_lflag & ICANON) == 0 | ||
721 | && (control_info[i].name == stty_eof | ||
722 | || control_info[i].name == stty_eol)) continue; | ||
723 | #endif | ||
724 | wrapf("%s = %s;", control_info[i].name, | ||
725 | visible(mode->c_cc[control_info[i].offset])); | ||
726 | } | ||
727 | #if VEOF == VMIN | ||
728 | if ((mode->c_lflag & ICANON) == 0) | ||
729 | #endif | ||
730 | wrapf("min = %d; time = %d;", mode->c_cc[VMIN], mode->c_cc[VTIME]); | ||
731 | if (current_col) wrapf("\n"); | ||
732 | |||
733 | for (i = 0; i < NUM_mode_info; ++i) { | ||
734 | if (mode_info[i].flags & OMIT) | ||
735 | continue; | ||
736 | if (mode_info[i].type != prev_type) { | ||
737 | wrapf("\n"); | ||
738 | prev_type = mode_info[i].type; | ||
739 | } | ||
740 | |||
741 | bitsp = mode_type_flag(mode_info[i].type, mode); | ||
742 | mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; | ||
743 | if ((*bitsp & mask) == mode_info[i].bits) | ||
744 | wrapf("%s", mode_info[i].name); | ||
745 | else if (mode_info[i].flags & REV) | ||
746 | wrapf("-%s", mode_info[i].name); | ||
747 | } | ||
748 | if (current_col) wrapf("\n"); | ||
749 | } | ||
750 | |||
751 | static void sane_mode(struct termios *mode) | ||
752 | { | ||
753 | int i; | ||
754 | tcflag_t *bitsp; | ||
755 | |||
756 | for (i = 0; i < NUM_control_info; ++i) { | ||
757 | #if VMIN == VEOF | ||
758 | if (control_info[i].name == stty_min) | ||
759 | break; | ||
760 | #endif | ||
761 | mode->c_cc[control_info[i].offset] = control_info[i].saneval; | ||
762 | } | ||
763 | |||
764 | for (i = 0; i < NUM_mode_info; ++i) { | ||
765 | if (mode_info[i].flags & SANE_SET) { | ||
766 | bitsp = mode_type_flag(mode_info[i].type, mode); | ||
767 | *bitsp = (*bitsp & ~((unsigned long)mode_info[i].mask)) | ||
768 | | mode_info[i].bits; | ||
769 | } else if (mode_info[i].flags & SANE_UNSET) { | ||
770 | bitsp = mode_type_flag(mode_info[i].type, mode); | ||
771 | *bitsp = *bitsp & ~((unsigned long)mode_info[i].mask) | ||
772 | & ~mode_info[i].bits; | ||
773 | } | ||
774 | } | ||
775 | } | ||
776 | |||
777 | /* Save set_mode from #ifdef forest plague */ | ||
778 | #ifndef ONLCR | ||
779 | #define ONLCR 0 | ||
780 | #endif | ||
781 | #ifndef OCRNL | ||
782 | #define OCRNL 0 | ||
783 | #endif | ||
784 | #ifndef ONLRET | ||
785 | #define ONLRET 0 | ||
786 | #endif | ||
787 | #ifndef XCASE | ||
788 | #define XCASE 0 | ||
789 | #endif | ||
790 | #ifndef IXANY | ||
791 | #define IXANY 0 | ||
792 | #endif | ||
793 | #ifndef TABDLY | ||
794 | #define TABDLY 0 | ||
795 | #endif | ||
796 | #ifndef OXTABS | ||
797 | #define OXTABS 0 | ||
798 | #endif | ||
799 | #ifndef IUCLC | ||
800 | #define IUCLC 0 | ||
801 | #endif | ||
802 | #ifndef OLCUC | ||
803 | #define OLCUC 0 | ||
804 | #endif | ||
805 | #ifndef ECHOCTL | ||
806 | #define ECHOCTL 0 | ||
807 | #endif | ||
808 | #ifndef ECHOKE | ||
809 | #define ECHOKE 0 | ||
810 | #endif | ||
811 | |||
812 | static void set_mode(const struct mode_info *info, int reversed, | ||
813 | struct termios *mode) | ||
814 | { | ||
815 | tcflag_t *bitsp; | ||
816 | |||
817 | bitsp = mode_type_flag(info->type, mode); | ||
818 | |||
819 | if (bitsp) { | ||
820 | if (reversed) | ||
821 | *bitsp = *bitsp & ~info->mask & ~info->bits; | ||
822 | else | ||
823 | *bitsp = (*bitsp & ~info->mask) | info->bits; | ||
824 | return; | ||
825 | } | ||
826 | |||
827 | /* Combination mode */ | ||
828 | if (info->name == evenp || info->name == parity) { | ||
829 | if (reversed) | ||
830 | mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; | ||
831 | else | ||
832 | mode->c_cflag = (mode->c_cflag & ~PARODD & ~CSIZE) | PARENB | CS7; | ||
833 | } else if (info->name == stty_oddp) { | ||
834 | if (reversed) | ||
835 | mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; | ||
836 | else | ||
837 | mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARODD | PARENB; | ||
838 | } else if (info->name == stty_nl) { | ||
839 | if (reversed) { | ||
840 | mode->c_iflag = (mode->c_iflag | ICRNL) & ~INLCR & ~IGNCR; | ||
841 | mode->c_oflag = (mode->c_oflag | ONLCR) & ~OCRNL & ~ONLRET; | ||
842 | } else { | ||
843 | mode->c_iflag = mode->c_iflag & ~ICRNL; | ||
844 | if (ONLCR) mode->c_oflag = mode->c_oflag & ~ONLCR; | ||
845 | } | ||
846 | } else if (info->name == stty_ek) { | ||
847 | mode->c_cc[VERASE] = CERASE; | ||
848 | mode->c_cc[VKILL] = CKILL; | ||
849 | } else if (info->name == stty_sane) { | ||
850 | sane_mode(mode); | ||
851 | } | ||
852 | else if (info->name == cbreak) { | ||
853 | if (reversed) | ||
854 | mode->c_lflag |= ICANON; | ||
855 | else | ||
856 | mode->c_lflag &= ~ICANON; | ||
857 | } else if (info->name == stty_pass8) { | ||
858 | if (reversed) { | ||
859 | mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; | ||
860 | mode->c_iflag |= ISTRIP; | ||
861 | } else { | ||
862 | mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; | ||
863 | mode->c_iflag &= ~ISTRIP; | ||
864 | } | ||
865 | } else if (info->name == litout) { | ||
866 | if (reversed) { | ||
867 | mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; | ||
868 | mode->c_iflag |= ISTRIP; | ||
869 | mode->c_oflag |= OPOST; | ||
870 | } else { | ||
871 | mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; | ||
872 | mode->c_iflag &= ~ISTRIP; | ||
873 | mode->c_oflag &= ~OPOST; | ||
874 | } | ||
875 | } else if (info->name == raw || info->name == cooked) { | ||
876 | if ((info->name[0] == 'r' && reversed) | ||
877 | || (info->name[0] == 'c' && !reversed)) { | ||
878 | /* Cooked mode */ | ||
879 | mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON; | ||
880 | mode->c_oflag |= OPOST; | ||
881 | mode->c_lflag |= ISIG | ICANON; | ||
882 | #if VMIN == VEOF | ||
883 | mode->c_cc[VEOF] = CEOF; | ||
884 | #endif | ||
885 | #if VTIME == VEOL | ||
886 | mode->c_cc[VEOL] = CEOL; | ||
887 | #endif | ||
888 | } else { | ||
889 | /* Raw mode */ | ||
890 | mode->c_iflag = 0; | ||
891 | mode->c_oflag &= ~OPOST; | ||
892 | mode->c_lflag &= ~(ISIG | ICANON | XCASE); | ||
893 | mode->c_cc[VMIN] = 1; | ||
894 | mode->c_cc[VTIME] = 0; | ||
895 | } | ||
896 | } | ||
897 | else if (IXANY && info->name == decctlq) { | ||
898 | if (reversed) | ||
899 | mode->c_iflag |= IXANY; | ||
900 | else | ||
901 | mode->c_iflag &= ~IXANY; | ||
902 | } | ||
903 | else if (TABDLY && info->name == stty_tabs) { | ||
904 | if (reversed) | ||
905 | mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB3; | ||
906 | else | ||
907 | mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB0; | ||
908 | } | ||
909 | else if (OXTABS && info->name == stty_tabs) { | ||
910 | if (reversed) | ||
911 | mode->c_oflag |= OXTABS; | ||
912 | else | ||
913 | mode->c_oflag &= ~OXTABS; | ||
914 | } | ||
915 | else if (XCASE && IUCLC && OLCUC | ||
916 | && (info->name == stty_lcase || info->name == stty_LCASE)) { | ||
917 | if (reversed) { | ||
918 | mode->c_lflag &= ~XCASE; | ||
919 | mode->c_iflag &= ~IUCLC; | ||
920 | mode->c_oflag &= ~OLCUC; | ||
921 | } else { | ||
922 | mode->c_lflag |= XCASE; | ||
923 | mode->c_iflag |= IUCLC; | ||
924 | mode->c_oflag |= OLCUC; | ||
925 | } | ||
926 | } | ||
927 | else if (info->name == stty_crt) { | ||
928 | mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE; | ||
929 | } | ||
930 | else if (info->name == stty_dec) { | ||
931 | mode->c_cc[VINTR] = 3; /* ^C */ | ||
932 | mode->c_cc[VERASE] = 127; /* DEL */ | ||
933 | mode->c_cc[VKILL] = 21; /* ^U */ | ||
934 | mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE; | ||
935 | if (IXANY) mode->c_iflag &= ~IXANY; | ||
936 | } | ||
937 | } | ||
938 | |||
939 | static void display_changed(const struct termios *mode) | ||
940 | { | ||
941 | int i; | ||
942 | tcflag_t *bitsp; | ||
943 | unsigned long mask; | ||
944 | int prev_type = control; | ||
945 | |||
946 | display_speed(mode, 1); | ||
947 | #ifdef HAVE_C_LINE | ||
948 | wrapf("line = %d;\n", mode->c_line); | ||
949 | #else | ||
950 | wrapf("\n"); | ||
951 | #endif | ||
952 | |||
953 | for (i = 0; control_info[i].name != stty_min; ++i) { | ||
954 | if (mode->c_cc[control_info[i].offset] == control_info[i].saneval) | ||
955 | continue; | ||
956 | /* If swtch is the same as susp, don't print both */ | ||
957 | #if VSWTCH == VSUSP | ||
958 | if (control_info[i].name == stty_swtch) | ||
959 | continue; | ||
960 | #endif | ||
961 | /* If eof uses the same slot as min, only print whichever applies */ | ||
962 | #if VEOF == VMIN | ||
963 | if ((mode->c_lflag & ICANON) == 0 | ||
964 | && (control_info[i].name == stty_eof | ||
965 | || control_info[i].name == stty_eol)) continue; | ||
966 | #endif | ||
967 | wrapf("%s = %s;", control_info[i].name, | ||
968 | visible(mode->c_cc[control_info[i].offset])); | ||
969 | } | ||
970 | if ((mode->c_lflag & ICANON) == 0) { | ||
971 | wrapf("min = %d; time = %d;", (int) mode->c_cc[VMIN], | ||
972 | (int) mode->c_cc[VTIME]); | ||
973 | } | ||
974 | if (current_col) wrapf("\n"); | ||
975 | |||
976 | for (i = 0; i < NUM_mode_info; ++i) { | ||
977 | if (mode_info[i].flags & OMIT) | ||
978 | continue; | ||
979 | if (mode_info[i].type != prev_type) { | ||
980 | if (current_col) wrapf("\n"); | ||
981 | prev_type = mode_info[i].type; | ||
982 | } | ||
983 | |||
984 | bitsp = mode_type_flag(mode_info[i].type, mode); | ||
985 | mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; | ||
986 | if ((*bitsp & mask) == mode_info[i].bits) { | ||
987 | if (mode_info[i].flags & SANE_UNSET) { | ||
988 | wrapf("%s", mode_info[i].name); | ||
989 | } | ||
990 | } else if ((mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV)) { | ||
991 | wrapf("-%s", mode_info[i].name); | ||
992 | } | ||
993 | } | ||
994 | if (current_col) wrapf("\n"); | ||
995 | } | ||
640 | 996 | ||
641 | static int recover_mode(const char *arg, struct termios *mode); | ||
642 | static void set_mode(const struct mode_info *info, | ||
643 | int reversed, struct termios *mode); | ||
644 | static void display_all(const struct termios *mode); | ||
645 | static void display_changed(const struct termios *mode); | ||
646 | static void display_recoverable(const struct termios *mode); | ||
647 | static void display_speed(const struct termios *mode, int fancy); | ||
648 | static void sane_mode(struct termios *mode); | ||
649 | static void set_control_char_or_die(const struct control_info *info, | 997 | static void set_control_char_or_die(const struct control_info *info, |
650 | const char *arg, struct termios *mode); | 998 | const char *arg, struct termios *mode) |
999 | { | ||
1000 | unsigned char value; | ||
1001 | |||
1002 | if (info->name == stty_min || info->name == stty_time) | ||
1003 | value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes); | ||
1004 | else if (arg[0] == '\0' || arg[1] == '\0') | ||
1005 | value = arg[0]; | ||
1006 | else if (streq(arg, "^-") || streq(arg, "undef")) | ||
1007 | value = _POSIX_VDISABLE; | ||
1008 | else if (arg[0] == '^') { /* Ignore any trailing junk (^Cjunk) */ | ||
1009 | value = arg[1] & 0x1f; /* Non-letters get weird results */ | ||
1010 | if (arg[1] == '?') | ||
1011 | value = 127; | ||
1012 | } else | ||
1013 | value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes); | ||
1014 | mode->c_cc[info->offset] = value; | ||
1015 | } | ||
651 | 1016 | ||
652 | int stty_main(int argc, char **argv) | 1017 | int stty_main(int argc, char **argv) |
653 | { | 1018 | { |
@@ -928,380 +1293,3 @@ end_option: | |||
928 | 1293 | ||
929 | return EXIT_SUCCESS; | 1294 | return EXIT_SUCCESS; |
930 | } | 1295 | } |
931 | |||
932 | /* Save set_mode from #ifdef forest plague */ | ||
933 | #ifndef ONLCR | ||
934 | #define ONLCR 0 | ||
935 | #endif | ||
936 | #ifndef OCRNL | ||
937 | #define OCRNL 0 | ||
938 | #endif | ||
939 | #ifndef ONLRET | ||
940 | #define ONLRET 0 | ||
941 | #endif | ||
942 | #ifndef XCASE | ||
943 | #define XCASE 0 | ||
944 | #endif | ||
945 | #ifndef IXANY | ||
946 | #define IXANY 0 | ||
947 | #endif | ||
948 | #ifndef TABDLY | ||
949 | #define TABDLY 0 | ||
950 | #endif | ||
951 | #ifndef OXTABS | ||
952 | #define OXTABS 0 | ||
953 | #endif | ||
954 | #ifndef IUCLC | ||
955 | #define IUCLC 0 | ||
956 | #endif | ||
957 | #ifndef OLCUC | ||
958 | #define OLCUC 0 | ||
959 | #endif | ||
960 | #ifndef ECHOCTL | ||
961 | #define ECHOCTL 0 | ||
962 | #endif | ||
963 | #ifndef ECHOKE | ||
964 | #define ECHOKE 0 | ||
965 | #endif | ||
966 | |||
967 | static void set_mode(const struct mode_info *info, int reversed, | ||
968 | struct termios *mode) | ||
969 | { | ||
970 | tcflag_t *bitsp; | ||
971 | |||
972 | bitsp = mode_type_flag(info->type, mode); | ||
973 | |||
974 | if (bitsp) { | ||
975 | if (reversed) | ||
976 | *bitsp = *bitsp & ~info->mask & ~info->bits; | ||
977 | else | ||
978 | *bitsp = (*bitsp & ~info->mask) | info->bits; | ||
979 | return; | ||
980 | } | ||
981 | |||
982 | /* Combination mode */ | ||
983 | if (info->name == evenp || info->name == parity) { | ||
984 | if (reversed) | ||
985 | mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; | ||
986 | else | ||
987 | mode->c_cflag = (mode->c_cflag & ~PARODD & ~CSIZE) | PARENB | CS7; | ||
988 | } else if (info->name == stty_oddp) { | ||
989 | if (reversed) | ||
990 | mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; | ||
991 | else | ||
992 | mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARODD | PARENB; | ||
993 | } else if (info->name == stty_nl) { | ||
994 | if (reversed) { | ||
995 | mode->c_iflag = (mode->c_iflag | ICRNL) & ~INLCR & ~IGNCR; | ||
996 | mode->c_oflag = (mode->c_oflag | ONLCR) & ~OCRNL & ~ONLRET; | ||
997 | } else { | ||
998 | mode->c_iflag = mode->c_iflag & ~ICRNL; | ||
999 | if (ONLCR) mode->c_oflag = mode->c_oflag & ~ONLCR; | ||
1000 | } | ||
1001 | } else if (info->name == stty_ek) { | ||
1002 | mode->c_cc[VERASE] = CERASE; | ||
1003 | mode->c_cc[VKILL] = CKILL; | ||
1004 | } else if (info->name == stty_sane) { | ||
1005 | sane_mode(mode); | ||
1006 | } | ||
1007 | else if (info->name == cbreak) { | ||
1008 | if (reversed) | ||
1009 | mode->c_lflag |= ICANON; | ||
1010 | else | ||
1011 | mode->c_lflag &= ~ICANON; | ||
1012 | } else if (info->name == stty_pass8) { | ||
1013 | if (reversed) { | ||
1014 | mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; | ||
1015 | mode->c_iflag |= ISTRIP; | ||
1016 | } else { | ||
1017 | mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; | ||
1018 | mode->c_iflag &= ~ISTRIP; | ||
1019 | } | ||
1020 | } else if (info->name == litout) { | ||
1021 | if (reversed) { | ||
1022 | mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; | ||
1023 | mode->c_iflag |= ISTRIP; | ||
1024 | mode->c_oflag |= OPOST; | ||
1025 | } else { | ||
1026 | mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; | ||
1027 | mode->c_iflag &= ~ISTRIP; | ||
1028 | mode->c_oflag &= ~OPOST; | ||
1029 | } | ||
1030 | } else if (info->name == raw || info->name == cooked) { | ||
1031 | if ((info->name[0] == 'r' && reversed) | ||
1032 | || (info->name[0] == 'c' && !reversed)) { | ||
1033 | /* Cooked mode */ | ||
1034 | mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON; | ||
1035 | mode->c_oflag |= OPOST; | ||
1036 | mode->c_lflag |= ISIG | ICANON; | ||
1037 | #if VMIN == VEOF | ||
1038 | mode->c_cc[VEOF] = CEOF; | ||
1039 | #endif | ||
1040 | #if VTIME == VEOL | ||
1041 | mode->c_cc[VEOL] = CEOL; | ||
1042 | #endif | ||
1043 | } else { | ||
1044 | /* Raw mode */ | ||
1045 | mode->c_iflag = 0; | ||
1046 | mode->c_oflag &= ~OPOST; | ||
1047 | mode->c_lflag &= ~(ISIG | ICANON | XCASE); | ||
1048 | mode->c_cc[VMIN] = 1; | ||
1049 | mode->c_cc[VTIME] = 0; | ||
1050 | } | ||
1051 | } | ||
1052 | else if (IXANY && info->name == decctlq) { | ||
1053 | if (reversed) | ||
1054 | mode->c_iflag |= IXANY; | ||
1055 | else | ||
1056 | mode->c_iflag &= ~IXANY; | ||
1057 | } | ||
1058 | else if (TABDLY && info->name == stty_tabs) { | ||
1059 | if (reversed) | ||
1060 | mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB3; | ||
1061 | else | ||
1062 | mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB0; | ||
1063 | } | ||
1064 | else if (OXTABS && info->name == stty_tabs) { | ||
1065 | if (reversed) | ||
1066 | mode->c_oflag |= OXTABS; | ||
1067 | else | ||
1068 | mode->c_oflag &= ~OXTABS; | ||
1069 | } | ||
1070 | else if (XCASE && IUCLC && OLCUC | ||
1071 | && (info->name == stty_lcase || info->name == stty_LCASE)) { | ||
1072 | if (reversed) { | ||
1073 | mode->c_lflag &= ~XCASE; | ||
1074 | mode->c_iflag &= ~IUCLC; | ||
1075 | mode->c_oflag &= ~OLCUC; | ||
1076 | } else { | ||
1077 | mode->c_lflag |= XCASE; | ||
1078 | mode->c_iflag |= IUCLC; | ||
1079 | mode->c_oflag |= OLCUC; | ||
1080 | } | ||
1081 | } | ||
1082 | else if (info->name == stty_crt) { | ||
1083 | mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE; | ||
1084 | } | ||
1085 | else if (info->name == stty_dec) { | ||
1086 | mode->c_cc[VINTR] = 3; /* ^C */ | ||
1087 | mode->c_cc[VERASE] = 127; /* DEL */ | ||
1088 | mode->c_cc[VKILL] = 21; /* ^U */ | ||
1089 | mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE; | ||
1090 | if (IXANY) mode->c_iflag &= ~IXANY; | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | static void set_control_char_or_die(const struct control_info *info, | ||
1095 | const char *arg, struct termios *mode) | ||
1096 | { | ||
1097 | unsigned char value; | ||
1098 | |||
1099 | if (info->name == stty_min || info->name == stty_time) | ||
1100 | value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes); | ||
1101 | else if (arg[0] == '\0' || arg[1] == '\0') | ||
1102 | value = arg[0]; | ||
1103 | else if (streq(arg, "^-") || streq(arg, "undef")) | ||
1104 | value = _POSIX_VDISABLE; | ||
1105 | else if (arg[0] == '^') { /* Ignore any trailing junk (^Cjunk) */ | ||
1106 | value = arg[1] & 0x1f; /* Non-letters get weird results */ | ||
1107 | if (arg[1] == '?') | ||
1108 | value = 127; | ||
1109 | } else | ||
1110 | value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes); | ||
1111 | mode->c_cc[info->offset] = value; | ||
1112 | } | ||
1113 | |||
1114 | static void display_changed(const struct termios *mode) | ||
1115 | { | ||
1116 | int i; | ||
1117 | tcflag_t *bitsp; | ||
1118 | unsigned long mask; | ||
1119 | int prev_type = control; | ||
1120 | |||
1121 | display_speed(mode, 1); | ||
1122 | #ifdef HAVE_C_LINE | ||
1123 | wrapf("line = %d;\n", mode->c_line); | ||
1124 | #else | ||
1125 | wrapf("\n"); | ||
1126 | #endif | ||
1127 | |||
1128 | for (i = 0; control_info[i].name != stty_min; ++i) { | ||
1129 | if (mode->c_cc[control_info[i].offset] == control_info[i].saneval) | ||
1130 | continue; | ||
1131 | /* If swtch is the same as susp, don't print both */ | ||
1132 | #if VSWTCH == VSUSP | ||
1133 | if (control_info[i].name == stty_swtch) | ||
1134 | continue; | ||
1135 | #endif | ||
1136 | /* If eof uses the same slot as min, only print whichever applies */ | ||
1137 | #if VEOF == VMIN | ||
1138 | if ((mode->c_lflag & ICANON) == 0 | ||
1139 | && (control_info[i].name == stty_eof | ||
1140 | || control_info[i].name == stty_eol)) continue; | ||
1141 | #endif | ||
1142 | wrapf("%s = %s;", control_info[i].name, | ||
1143 | visible(mode->c_cc[control_info[i].offset])); | ||
1144 | } | ||
1145 | if ((mode->c_lflag & ICANON) == 0) { | ||
1146 | wrapf("min = %d; time = %d;", (int) mode->c_cc[VMIN], | ||
1147 | (int) mode->c_cc[VTIME]); | ||
1148 | } | ||
1149 | if (current_col) wrapf("\n"); | ||
1150 | |||
1151 | for (i = 0; i < NUM_mode_info; ++i) { | ||
1152 | if (mode_info[i].flags & OMIT) | ||
1153 | continue; | ||
1154 | if (mode_info[i].type != prev_type) { | ||
1155 | if (current_col) wrapf("\n"); | ||
1156 | prev_type = mode_info[i].type; | ||
1157 | } | ||
1158 | |||
1159 | bitsp = mode_type_flag(mode_info[i].type, mode); | ||
1160 | mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; | ||
1161 | if ((*bitsp & mask) == mode_info[i].bits) { | ||
1162 | if (mode_info[i].flags & SANE_UNSET) { | ||
1163 | wrapf("%s", mode_info[i].name); | ||
1164 | } | ||
1165 | } else if ((mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV)) { | ||
1166 | wrapf("-%s", mode_info[i].name); | ||
1167 | } | ||
1168 | } | ||
1169 | if (current_col) wrapf("\n"); | ||
1170 | } | ||
1171 | |||
1172 | static void display_all(const struct termios *mode) | ||
1173 | { | ||
1174 | int i; | ||
1175 | tcflag_t *bitsp; | ||
1176 | unsigned long mask; | ||
1177 | int prev_type = control; | ||
1178 | |||
1179 | display_speed(mode, 1); | ||
1180 | display_window_size(1); | ||
1181 | #ifdef HAVE_C_LINE | ||
1182 | wrapf("line = %d;\n", mode->c_line); | ||
1183 | #else | ||
1184 | wrapf("\n"); | ||
1185 | #endif | ||
1186 | |||
1187 | for (i = 0; control_info[i].name != stty_min; ++i) { | ||
1188 | /* If swtch is the same as susp, don't print both */ | ||
1189 | #if VSWTCH == VSUSP | ||
1190 | if (control_info[i].name == stty_swtch) | ||
1191 | continue; | ||
1192 | #endif | ||
1193 | /* If eof uses the same slot as min, only print whichever applies */ | ||
1194 | #if VEOF == VMIN | ||
1195 | if ((mode->c_lflag & ICANON) == 0 | ||
1196 | && (control_info[i].name == stty_eof | ||
1197 | || control_info[i].name == stty_eol)) continue; | ||
1198 | #endif | ||
1199 | wrapf("%s = %s;", control_info[i].name, | ||
1200 | visible(mode->c_cc[control_info[i].offset])); | ||
1201 | } | ||
1202 | #if VEOF == VMIN | ||
1203 | if ((mode->c_lflag & ICANON) == 0) | ||
1204 | #endif | ||
1205 | wrapf("min = %d; time = %d;", mode->c_cc[VMIN], mode->c_cc[VTIME]); | ||
1206 | if (current_col) wrapf("\n"); | ||
1207 | |||
1208 | for (i = 0; i < NUM_mode_info; ++i) { | ||
1209 | if (mode_info[i].flags & OMIT) | ||
1210 | continue; | ||
1211 | if (mode_info[i].type != prev_type) { | ||
1212 | wrapf("\n"); | ||
1213 | prev_type = mode_info[i].type; | ||
1214 | } | ||
1215 | |||
1216 | bitsp = mode_type_flag(mode_info[i].type, mode); | ||
1217 | mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; | ||
1218 | if ((*bitsp & mask) == mode_info[i].bits) | ||
1219 | wrapf("%s", mode_info[i].name); | ||
1220 | else if (mode_info[i].flags & REV) | ||
1221 | wrapf("-%s", mode_info[i].name); | ||
1222 | } | ||
1223 | if (current_col) wrapf("\n"); | ||
1224 | } | ||
1225 | |||
1226 | static void display_speed(const struct termios *mode, int fancy) | ||
1227 | { | ||
1228 | //01234567 8 9 | ||
1229 | const char *fmt_str = "%lu %lu\n\0ispeed %lu baud; ospeed %lu baud;"; | ||
1230 | unsigned long ispeed, ospeed; | ||
1231 | |||
1232 | ospeed = ispeed = cfgetispeed(mode); | ||
1233 | if (ispeed == 0 || ispeed == (ospeed = cfgetospeed(mode))) { | ||
1234 | ispeed = ospeed; /* in case ispeed was 0 */ | ||
1235 | //0123 4 5 6 7 8 9 | ||
1236 | fmt_str = "%lu\n\0\0\0\0\0speed %lu baud;"; | ||
1237 | } | ||
1238 | if (fancy) fmt_str += 9; | ||
1239 | wrapf(fmt_str, tty_baud_to_value(ispeed), tty_baud_to_value(ospeed)); | ||
1240 | } | ||
1241 | |||
1242 | static void display_recoverable(const struct termios *mode) | ||
1243 | { | ||
1244 | int i; | ||
1245 | printf("%lx:%lx:%lx:%lx", | ||
1246 | (unsigned long) mode->c_iflag, (unsigned long) mode->c_oflag, | ||
1247 | (unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag); | ||
1248 | for (i = 0; i < NCCS; ++i) | ||
1249 | printf(":%x", (unsigned int) mode->c_cc[i]); | ||
1250 | putchar('\n'); | ||
1251 | } | ||
1252 | |||
1253 | static int recover_mode(const char *arg, struct termios *mode) | ||
1254 | { | ||
1255 | int i, n; | ||
1256 | unsigned int chr; | ||
1257 | unsigned long iflag, oflag, cflag, lflag; | ||
1258 | |||
1259 | /* Scan into temporaries since it is too much trouble to figure out | ||
1260 | the right format for 'tcflag_t' */ | ||
1261 | if (sscanf(arg, "%lx:%lx:%lx:%lx%n", | ||
1262 | &iflag, &oflag, &cflag, &lflag, &n) != 4) | ||
1263 | return 0; | ||
1264 | mode->c_iflag = iflag; | ||
1265 | mode->c_oflag = oflag; | ||
1266 | mode->c_cflag = cflag; | ||
1267 | mode->c_lflag = lflag; | ||
1268 | arg += n; | ||
1269 | for (i = 0; i < NCCS; ++i) { | ||
1270 | if (sscanf(arg, ":%x%n", &chr, &n) != 1) | ||
1271 | return 0; | ||
1272 | mode->c_cc[i] = chr; | ||
1273 | arg += n; | ||
1274 | } | ||
1275 | |||
1276 | /* Fail if there are too many fields */ | ||
1277 | if (*arg != '\0') | ||
1278 | return 0; | ||
1279 | |||
1280 | return 1; | ||
1281 | } | ||
1282 | |||
1283 | static void sane_mode(struct termios *mode) | ||
1284 | { | ||
1285 | int i; | ||
1286 | tcflag_t *bitsp; | ||
1287 | |||
1288 | for (i = 0; i < NUM_control_info; ++i) { | ||
1289 | #if VMIN == VEOF | ||
1290 | if (control_info[i].name == stty_min) | ||
1291 | break; | ||
1292 | #endif | ||
1293 | mode->c_cc[control_info[i].offset] = control_info[i].saneval; | ||
1294 | } | ||
1295 | |||
1296 | for (i = 0; i < NUM_mode_info; ++i) { | ||
1297 | if (mode_info[i].flags & SANE_SET) { | ||
1298 | bitsp = mode_type_flag(mode_info[i].type, mode); | ||
1299 | *bitsp = (*bitsp & ~((unsigned long)mode_info[i].mask)) | ||
1300 | | mode_info[i].bits; | ||
1301 | } else if (mode_info[i].flags & SANE_UNSET) { | ||
1302 | bitsp = mode_type_flag(mode_info[i].type, mode); | ||
1303 | *bitsp = *bitsp & ~((unsigned long)mode_info[i].mask) | ||
1304 | & ~mode_info[i].bits; | ||
1305 | } | ||
1306 | } | ||
1307 | } | ||