| | 665 | |
| | 666 | |
| | 667 | [=#console] |
| | 668 | = Serial Console |
| | 669 | |
| | 670 | == Serial Console Window Size |
| | 671 | console applications running inside Linux virtual terminal applications (xterm, rxvt etc) will receive SIGWINCH after a resize operation has taken place and adjust accordingly. |
| | 672 | |
| | 673 | When using a serial console there is no such mechanism and you can see the affect of this by connecting to a serial console (ie jtag_com/jtag_gang) and showing your size either via env vars or via the 'stty size' app: |
| | 674 | {{{#!bash |
| | 675 | ~# echo $LINES $COLUMNS |
| | 676 | 24 80 |
| | 677 | ~# stty size |
| | 678 | 24 80 |
| | 679 | }}} |
| | 680 | |
| | 681 | No matter how you resize that virtual terminal window (ie xterm), the above commands will always report the same size. |
| | 682 | |
| | 683 | It is possible for the application to actively ask for the current console window size so the second best thing is to do this every time a command prompt is printed by the shell. This can be achieved by sending a ANSI code to position the cursor to 999,999 then request the cursor position. |
| | 684 | |
| | 685 | The 'resize' app from the 'xterm' package does this, but here is also a cleaner version with less dependencies: |
| | 686 | {{{#!bash |
| | 687 | wget http://web.archive.org/web/20081224152013/http://www.davehylands.com/gumstix-wiki/resize/resize.c |
| | 688 | gcc resize.c -o /usr/local/bin/resize |
| | 689 | }}} |
| | 690 | |
| | 691 | You can also do this with shell scripts that do the same thing: |
| | 692 | {{{#!bash |
| | 693 | resize() { |
| | 694 | old=$(stty -g) |
| | 695 | stty raw -echo min 0 time 5 |
| | 696 | printf '\0337\033[r\033[999;999H\033[6n\0338' > /dev/tty |
| | 697 | IFS='[;R' read -r _ rows cols _ < /dev/tty |
| | 698 | stty "$old" |
| | 699 | #echo "size:${cols}x${rows}" |
| | 700 | stty cols "$cols" rows "$rows" |
| | 701 | } |
| | 702 | }}} |
| | 703 | |
| | 704 | you could add this and the following to your /etc/bash.bashrc: |
| | 705 | {{{#!bash |
| | 706 | [[ "$(tty)" =~ "/dev/ttymxc" ]] && { resize; } |
| | 707 | }}} |
| | 708 | |
| | 709 | some people also opt to use the 'trap' shell function to execute it on every command: |
| | 710 | {{{#!bash |
| | 711 | [[ "$(tty)" =~ "/dev/ttymxc" ]] && { trap resize DEBUG; } |
| | 712 | }}} |
| | 713 | |
| | 714 | Notes: |
| | 715 | - 'tty' shows the name of the terminal device (ie /dev/ttymxc1 if on a Ventana serial console) |
| | 716 | - 'stty size' outputs the current terminal size based on what the kernel thinks |
| | 717 | - this has nothing to do with terminal type (TERM) |
| | 718 | - when remotely connected to a board via ssh for example, this isn't an issue as that can use SIGWINCH |
| | 719 | orts 24 80 |
| | 720 | - the COLUMNS and LINES env variables reflect the size of the tty |
| | 721 | - resizable terminals are the result of NAWS 'Negotiate About Window Size' from RFC 1073 Telnet Window Size Option |
| | 722 | |
| | 723 | References: |
| | 724 | - https://unix.stackexchange.com/questions/16578/resizable-serial-console-window |
| | 725 | - http://web.archive.org/web/20081224152013/http://www.davehylands.com/gumstix-wiki/resize/resize.c |
| | 726 | {{{#!c |
| | 727 | /* resize.c */ |
| | 728 | |
| | 729 | #include <stdio.h> |
| | 730 | #include <ctype.h> |
| | 731 | #include <stdlib.h> |
| | 732 | #include <unistd.h> |
| | 733 | #include <sys/types.h> |
| | 734 | #include <string.h> |
| | 735 | #include <termio.h> |
| | 736 | #include <termios.h> |
| | 737 | |
| | 738 | |
| | 739 | #include <signal.h> |
| | 740 | #include <pwd.h> |
| | 741 | |
| | 742 | #define ESC "\033" |
| | 743 | |
| | 744 | |
| | 745 | #define TIMEOUT 10 |
| | 746 | |
| | 747 | |
| | 748 | char *myname; |
| | 749 | |
| | 750 | char getsize[] = ESC "7" ESC "[r" ESC "[999;999H" ESC "[6n"; |
| | 751 | char restore[] = ESC "8"; |
| | 752 | |
| | 753 | struct termios tioorig; |
| | 754 | |
| | 755 | char size[] = ESC "[%d;%dR"; |
| | 756 | |
| | 757 | int tty; |
| | 758 | FILE *ttyfp; |
| | 759 | |
| | 760 | static void onintr (int sig); |
| | 761 | static void resize_timeout (int sig); |
| | 762 | static void Usage (void); |
| | 763 | static void readstring (FILE *fp, char *buf, char *str); |
| | 764 | |
| | 765 | char * |
| | 766 | x_basename(char *name) |
| | 767 | { |
| | 768 | char *cp; |
| | 769 | |
| | 770 | cp = strrchr(name, '/'); |
| | 771 | return (cp ? cp + 1 : name); |
| | 772 | } |
| | 773 | |
| | 774 | |
| | 775 | /* |
| | 776 | tells tty driver to reflect current screen size |
| | 777 | */ |
| | 778 | |
| | 779 | int |
| | 780 | main (int argc, char **argv) |
| | 781 | { |
| | 782 | |
| | 783 | int rows, cols; |
| | 784 | struct termios tio; |
| | 785 | char buf[BUFSIZ]; |
| | 786 | struct winsize ws; |
| | 787 | char *name_of_tty; |
| | 788 | |
| | 789 | myname = x_basename(argv[0]); |
| | 790 | |
| | 791 | if (argc > 1) Usage(); |
| | 792 | |
| | 793 | name_of_tty = "/dev/tty"; |
| | 794 | |
| | 795 | if ((ttyfp = fopen (name_of_tty, "r+")) == NULL) { |
| | 796 | fprintf (stderr, "%s: can't open terminal %s\n", |
| | 797 | myname, name_of_tty); |
| | 798 | exit (1); |
| | 799 | } |
| | 800 | tty = fileno(ttyfp); |
| | 801 | |
| | 802 | tcgetattr(tty, &tioorig); |
| | 803 | tio = tioorig; |
| | 804 | tio.c_iflag &= ~ICRNL; |
| | 805 | tio.c_lflag &= ~(ICANON | ECHO); |
| | 806 | tio.c_cflag |= CS8; |
| | 807 | tio.c_cc[VMIN] = 6; |
| | 808 | tio.c_cc[VTIME] = 1; |
| | 809 | signal(SIGINT, onintr); |
| | 810 | signal(SIGQUIT, onintr); |
| | 811 | signal(SIGTERM, onintr); |
| | 812 | tcsetattr(tty, TCSADRAIN, &tio); |
| | 813 | |
| | 814 | write(tty, getsize, strlen(getsize)); |
| | 815 | readstring(ttyfp, buf, size); |
| | 816 | if(sscanf (buf, size, &rows, &cols) != 2) { |
| | 817 | fprintf(stderr, "%s: Can't get rows and columns\r\n", myname); |
| | 818 | onintr(0); |
| | 819 | } |
| | 820 | write(tty, restore, strlen(restore)); |
| | 821 | |
| | 822 | if (ioctl (tty, TIOCGWINSZ, &ws) != -1) { |
| | 823 | /* we don't have any way of directly finding out |
| | 824 | the current height & width of the window in pixels. We try |
| | 825 | our best by computing the font height and width from the "old" |
| | 826 | struct winsize values, and multiplying by these ratios...*/ |
| | 827 | if (ws.ws_col != 0) |
| | 828 | ws.ws_xpixel = cols * (ws.ws_xpixel / ws.ws_col); |
| | 829 | if (ws.ws_row != 0) |
| | 830 | ws.ws_ypixel = rows * (ws.ws_ypixel / ws.ws_row); |
| | 831 | ws.ws_row = rows; |
| | 832 | ws.ws_col = cols; |
| | 833 | ioctl (tty, TIOCSWINSZ, &ws); |
| | 834 | } |
| | 835 | |
| | 836 | tcsetattr(tty, TCSADRAIN, &tioorig); |
| | 837 | signal(SIGINT, SIG_DFL); |
| | 838 | signal(SIGQUIT, SIG_DFL); |
| | 839 | signal(SIGTERM, SIG_DFL); |
| | 840 | |
| | 841 | exit(0); |
| | 842 | } |
| | 843 | |
| | 844 | |
| | 845 | static void |
| | 846 | readstring(register FILE *fp, register char *buf, char *str) |
| | 847 | { |
| | 848 | register int last, c; |
| | 849 | |
| | 850 | signal(SIGALRM, resize_timeout); |
| | 851 | alarm (TIMEOUT); |
| | 852 | if ((c = getc(fp)) == 0233) { /* meta-escape, CSI */ |
| | 853 | *buf++ = c = ESC[0]; |
| | 854 | *buf++ = '['; |
| | 855 | } else { |
| | 856 | *buf++ = c; |
| | 857 | } |
| | 858 | if(c != *str) { |
| | 859 | fprintf(stderr, "%s: unknown character, exiting.\r\n", myname); |
| | 860 | onintr(0); |
| | 861 | } |
| | 862 | last = str[strlen(str) - 1]; |
| | 863 | while((*buf++ = getc(fp)) != last) |
| | 864 | ; |
| | 865 | alarm (0); |
| | 866 | *buf = 0; |
| | 867 | } |
| | 868 | |
| | 869 | static void |
| | 870 | Usage(void) |
| | 871 | { |
| | 872 | fprintf(stderr, |
| | 873 | "Usage: %s\n" |
| | 874 | " sets size via ioctl\n", myname); |
| | 875 | exit(1); |
| | 876 | } |
| | 877 | |
| | 878 | static void |
| | 879 | resize_timeout(int sig) |
| | 880 | { |
| | 881 | fprintf(stderr, "\n%s: timeout occurred\r\n", myname); |
| | 882 | onintr(sig); |
| | 883 | } |
| | 884 | |
| | 885 | /* ARGSUSED */ |
| | 886 | static void |
| | 887 | onintr(int sig) |
| | 888 | { |
| | 889 | tcsetattr (tty, TCSADRAIN, &tioorig); |
| | 890 | exit(1); |
| | 891 | } |
| | 892 | |
| | 893 | }}} |