0

我有以下代码来获取 Linux 中屏幕的宽度和高度。

#ifdef TIOCGSIZE
struct ttysize ts;
ioctl(STDIN_FILENO, TIOCGSIZE, &ts);
cols = ts.ts_cols;
lines = ts.ts_lines;
#elif defined(TIOCGWINSZ)
struct winsize ts;
ioctl(STDIN_FILENO, TIOCGWINSZ, &ts);
cols = ts.ws_col;
lines = ts.ws_row;
#endif /* TIOCGSIZE */

ttysize 和 winsize 有什么区别?

4

2 回答 2

1

ttysize是 SunOS 3.0(1986 年 2 月)的原始实现,不久后被 废弃winsize,它增加了以像素为单位的窗口大小。以下是<sys/ttycom.h>SunOS 4 中的定义:

/*
 * 窗口/终端尺寸结构。
 * 此信息由内核存储
 * 为了提供一致的界面,
 * 但不被内核使用。
 *
 * 类型必须是“无符号短”,因此不需要 types.h。
 */
结构体大小 {
        无符号短 ws_row;/* 行,以字符为单位 */
        无符号短 ws_col;/* 列,以字符为单位 */
        无符号短 ws_xpixel;/* 水平尺寸,像素 - 未使用 */
        无符号短ws_ypixel;/* 垂直大小,像素 - 未使用 */
};

#define TIOCGWINSZ _IOR(t, 104, struct winsize) /* 获取窗口大小 */
#define TIOCSWINSZ _IOW(t, 103, struct winsize) /* 设置窗口大小 */

/*
 * Sun 版本相同。
 */
结构 ttysize {
        int ts_lines; /* 终端的行数 */
        int ts_cols; /* 终端的列数 */
};

#define TIOCSSIZE _IOW(t,37,struct ttysize)/*设置tty大小*/
#define TIOCGSIZE _IOR(t,38,struct ttysize)/* 获取 tty 大小 */

数据类型不同(整数会浪费内存),并且字段具有不同的名称。

ttysize结构早已过时:如果系统提供任何一个,winsize则支持。在 1997 年将 ncurses 移植到 SCO OpenServer 时,情况并非如此,正如lib_setup.c 中的此块所述

/*
 * SCO 定义了 TIOCGSIZE 和相应的结构。其他系统(SunOS、
 * Solaris, IRIX) 定义 TIOCGWINSZ 和 struct winsize。
 */
#ifdef TIOCGSIZE
# 定义 IOCTL_WINSIZE TIOCGSIZE
# 定义 STRUCT_WINSIZE 结构 ttysize
# 定义 WINSIZE_ROWS(n) (int)n.ts_lines
# 定义 WINSIZE_COLS(n) (int)n.ts_cols
#别的
# ifdef TIOCGWINSZ
# 定义 IOCTL_WINSIZE TIOCGWINSZ
# 定义 STRUCT_WINSIZE struct winsize
# 定义 WINSIZE_ROWS(n) (int)n.ws_row
# 定义 WINSIZE_COLS(n) (int)n.ws_col
# 万一
#万一

您可能会注意到评论中没有提到 Linux。根据asm-sparc64/ioctls.h中的评论,从2.6.16ttysize开始不支持ioctl :

/* 请注意,所有在 Linux 中不可用的 ioctl 都有一个
 * 前面的双下划线:a) 避免某些程序
 * 认为我们在 Linux 下支持一些 ioctl(自动配置的东西)
 */
...
#define TIOCCONS _IO('t', 36)
#define __TIOCSSIZE _IOW('t', 37, struct sunos_ttysize) /* SunOS 特定 */
#define __TIOCGSIZE _IOR('t', 38, struct sunos_ttysize) /* SunOS 特定 */
#define TIOCGSOFTCAR _IOR('t', 100, int)
#define TIOCSSOFTCAR _IOW('t', 101, int)
#define __TIOCUCNTL _IOW('t', 102, int) /* SunOS 特定 */
#define TIOCSWINSZ _IOW('t', 103, struct winsize)
#define TIOCGWINSZ _IOR('t', 104, struct winsize)

1995 年更早的评论添加了定义(没有双下划线)。可能有一些程序在 Linux 上使用了它,尽管winsize在 Linux 开始之前在大多数平台上已经很好地建立了。进一步挖掘发现双下划线是在 1996 年引入的(patch-2.1.9 linux/include/asm-sparc/ioctls.h)。鉴于此,很少有程序会在 Linux 上使用它。

进一步阅读:

于 2018-06-09T00:45:16.037 回答
0

它们具有相同的功能(至少在这种情况下 - 可能一个结构具有此处未使用的附加字段)。

从历史上看,一些(主要是较旧的)Linux 版本对 IOCTL 代码有不同的定义。因此,某些 Linux 版本仅定义了 TIOCGSIZE(使用 ttysize 结构),而某些 Linux 版本仅定义了 TIOCGWINSZ。

使用“#ifdef”结构,可以为两个 Linux 版本编译程序。

较新的 Linux 版本应该定义两个 IOCTL。

于 2013-09-20T07:19:54.813 回答