如何获得终端窗口宽度?

时间:2011-12-15 22:03:43

标签: c linux console terminal

我正在使用Clinux处理嵌入式系统。用户可以通过SSH或控制台串行电缆连接到设备。他可以通过PuTTY或Tera Term来做到这一点。我的问题是,在他连接后,我怎么知道他的窗户的宽度?我尝试了不同的方法,如果我在linux上模拟我的系统,它们可以正常工作,但它们都不能在设备上运行:

  1. ioctl()

    struct winsize ws;
    ioctl(..., TIOCGWINSZ, &ws); 
    

    此方法适用于PC,但它始终在设备上返回0。

  2. tgetnum()

    setupterm((char *)0, 1, (int *)0);
    CGR_INT columns = tgetnum("co");
    

    此方法适用于PC,但它始终在设备上返回80x24。

  3. getmaxyx()

    CGR_INT xdim;
    CGR_INT ydim;
    initscr();
    refresh();
    getmaxyx(stdscr, ydim, xdim);
    

    此方法适用于pc,但它始终在设备上返回0

2 个答案:

答案 0 :(得分:3)

我使用此代码将一堆等号打印为分隔符。适用于我尝试过的大多数盒子/术语。不确定你在说什么设备。值得一试,我猜; - )

#include <termios.h>
#include <sys/ioctl.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
   struct winsize ws;
   ioctl(0, TIOCGWINSZ, &ws);

   int i=0;
   for(;i<10*ws.ws_col;++i) printf("=");
   printf("\n");
   return 0;
}

答案 1 :(得分:2)

TIOCGWINSZ是要走的路。你的设备必须公布它的大小,否则这是行不通的。以xterm为例:

device —— ttyS driver —— ttyS0 devnode —— screen/minicom
xterm —— pty devnode —— pty driver —— pts devnode —— bash

xterm在第一次生成ioctl(TIOCSWINSZ)时让tty驱动程序知道窗口大小。从中产生的bash和程序可以查询它。如果你调整xterm窗口的大小,它会告诉tty驱动程序新的大小,xterm也会向其子进程发出SIGWINCH(在这种情况下为bash),以通知它大小的变化。

这些都不会发生在设备(例如你的设备)之前,它们首先不知道它们连接的是什么。 tty驱动程序也不知道连接到它的是什么。 (它通常也不关心。)xterm可以告诉驱动程序大小,因为它可以发出ioctl,但ioctl不会通过串行传输。从理论上讲,它是一个专门的内核驱动程序,它知道如何与您的特定设备进行大小更改(可能是串行协议,因此不需要重写核心组件)。

注意,连接的设备甚至可能没有固定区域的概念 - 例如。打印机可以被认为具有几乎无限多的线。

ncurses如果看到0x0则假设为80x24,因为程序员就是这样定义的。这个大小可能不正确,在实践中通常不是因为人们可以调整窗口大小(即使他们不能,就像在tty1上,他们仍然可以使用像屏幕(1)这样的东西,并将大小缩小到小于80x24的大小)。