Terminal 如何在Go中获得终端尺寸?

Terminal 如何在Go中获得终端尺寸?,terminal,posix,go,ioctl,Terminal,Posix,Go,Ioctl,如何在Go中获得终端尺寸。在C中,它将如下所示: struct ttysize ts; ioctl(0, TIOCGWINSZ, &ts); syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(TIOCGWINSZ), uintptr(unsafe.Pointer(&ts))) #include <termios.h> enum { $TIOCGWINSZ = TIOCGWINSZ }; t

如何在Go中获得终端尺寸。在C中,它将如下所示:

struct ttysize ts; 
ioctl(0, TIOCGWINSZ, &ts);
syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(TIOCGWINSZ), uintptr(unsafe.Pointer(&ts)))
#include <termios.h>

enum {
    $TIOCGWINSZ = TIOCGWINSZ
};

typedef winsize $winsize;

但是如何在Go中访问TIOCGWINSZ

随便看一下文档,似乎还没有做多少工作——事实上,我根本找不到
ioctl

对于一种处于婴儿期的语言来说,可以肯定地说,你正在踏上一条无人行走的道路
TIOCGWINSZ
本身就是一个常量整数(我在Linux源代码中找到了它的值):


不过,祝你好运。

cgo编译器目前无法处理c函数中的变量参数和c头文件中的宏,因此你无法进行简单的编译

// #include <sys/ioctl.h>
// typedef struct ttysize ttysize;
import "C"

func GetWinSz() {
    var ts C.ttysize;
    C.ioctl(0,C.TIOCGWINSZ,&ts)
}
/#包括
//typedef struct ttysize ttysize;
输入“C”
func GetWinSz(){
变量ts C.ttysize;
C.ioctl(0、C.TIOCGWINSZ和ts)
}
要绕过宏,请使用常量,因此

// #include <sys/ioctl.h>
// typedef struct ttysize ttysize;
import "C"

const TIOCGWINSZ C.ulong = 0x5413; // Value from Jed Smith's answer

func GetWinSz() {
    var ts C.ttysize;
    C.ioctl(0,TIOCGWINSZ,&ts)
}
/#包括
//typedef struct ttysize ttysize;
输入“C”
const TIOCGWINSZ C.ulong=0x5413;//杰德·史密斯答案的价值
func GetWinSz(){
变量ts C.ttysize;
C.ioctl(0、TIOCGWINSZ和ts)
}
然而,cgo仍然会吐在。。。在ioctl的原型中。最好的办法是用一个接受特定数量参数的c函数包装ioctl,并将其链接到中。作为黑客,你可以在上面的评论中输入“C”

/#包括
//typedef struct ttysize ttysize;
//void myioctl(inti,无符号长l,ttysize*t){ioctl(i,l,t);}
输入“C”
const TIOCGWINSZ C.ulong=0x5413;//杰德·史密斯答案的价值
func GetWinSz(){
变量ts C.ttysize;
C.myioctl(0,TIOCGWINSZ和ts)
}

我还没有对此进行测试,但是类似的方法应该可以工作。

最好的方法是使用syscall包。syscall包没有定义ioctl函数,因为它只做很多不同的事情,但您仍然可以这样调用它:

struct ttysize ts; 
ioctl(0, TIOCGWINSZ, &ts);
syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(TIOCGWINSZ), uintptr(unsafe.Pointer(&ts)))
#include <termios.h>

enum {
    $TIOCGWINSZ = TIOCGWINSZ
};

typedef winsize $winsize;
剩下的两件事是复制winsize结构和所需的常量。这方面的工具是godefs,它将通过查看C标题中的结构和常量来生成一个.go源文件。创建一个termios.c文件,如下所示:

struct ttysize ts; 
ioctl(0, TIOCGWINSZ, &ts);
syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(TIOCGWINSZ), uintptr(unsafe.Pointer(&ts)))
#include <termios.h>

enum {
    $TIOCGWINSZ = TIOCGWINSZ
};

typedef winsize $winsize;
现在,您应该拥有获得终端大小所需的一切。设置大小非常简单,只需将另一个常量添加到termios.c.

读取: