为了账号安全,请及时绑定邮箱和手机立即绑定

您如何在Go中获得终端大小?

您如何在Go中获得终端大小?

Go
红糖糍粑 2021-04-08 14:15:34
如何在Go中获取终端大小。在C中,它看起来像这样:struct ttysize ts; ioctl(0, TIOCGWINSZ, &ts);但是我如何在Go中访问TIOCGWINSZ
查看完整描述

3 回答

?
米脂

TA贡献1836条经验 获得超3个赞

目前,cgo编译器无法处理ac函数中的变量参数和c头文件中的宏,因此您无法做一个简单的操作


// #include <sys/ioctl.h>

// typedef struct ttysize ttysize;

import "C"


func GetWinSz() {

    var 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)

}

但是,cgo仍然会在ioctl的原型中bar之以鼻。最好的选择是用带有特定数量参数的ac函数包装ioctl并将其链接。作为hack,您可以在上面的注释中导入“ C”


// #include <sys/ioctl.h>

// typedef struct ttysize ttysize;

// void myioctl(int i, unsigned long l, ttysize * t){ioctl(i,l,t);}

import "C"


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


func GetWinSz() {

    var ts C.ttysize;

    C.myioctl(0,TIOCGWINSZ,&ts)

}

我还没有测试过,但是类似的东西应该可以工作。


查看完整回答
反对 回复 2021-04-26
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

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


syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(TIOCGWINSZ), uintptr(unsafe.Pointer(&ts)))

剩下的两件事是复制winsize结构和所需的常数。用于此目的的工具是godefs,它将通过查看C头文件中的结构和常量来生成.go源文件。创建一个如下所示的termios.c文件:


#include <termios.h>


enum {

    $TIOCGWINSZ = TIOCGWINSZ

};


typedef winsize $winsize;

现在运行


godefs -gpackagename termios.c > termios.go

现在,您应该拥有了获取终端大小所需的一切。设置大小就像向termios.c添加另一个常量一样简单。


查看完整回答
反对 回复 2021-04-26
  • 3 回答
  • 0 关注
  • 252 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信