2009-11-14 140 views

回答

3

的CGO编译器目前还不能处理的交流功能变量参数和宏在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的原型上...你最好的选择将是包装的ioctl交流功能服用参数的具体数量和链接,在作为一个黑客,你可以做的是,在上述意见进口“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) 
} 

我没有测试此,但类似的东西应该工作。

0

它看起来并不像很多工作已经在此从文档的偶然一瞥尚未完成 - 实际上,我根本找不到ioctl

有了这种早期的语言,可以肯定地说,你踩着未铺设的地面。 TIOCGWINSZ,本身就是一个恒定的整数(我发现它在Linux源代码值):

#define TIOCGWINSZ 0x5413 

祝你好运,虽然。

1

这样做的最好方法是使用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添加另一个常量一样简单。

1

读:http://www.darkcoding.net/software/pretty-command-line-console-output-on-unix-in-python-and-go-lang/

const (
    TIOCGWINSZ  = 0x5413 
    TIOCGWINSZ_OSX = 1074295912 
) 

type window struct { 
    Row uint16 
    Col uint16 
    Xpixel uint16 
    Ypixel uint16 
} 

func terminalWidth() (int, error) { 
    w := new(window) 
    tio := syscall.TIOCGWINSZ 
    if runtime.GOOS == "darwin" { 
     tio = TIOCGWINSZ_OSX 
    } 
    res, _, err := syscall.Syscall(syscall.SYS_IOCTL, 
     uintptr(syscall.Stdin), 
     uintptr(tio), 
     uintptr(unsafe.Pointer(w)), 
    ) 
    if int(res) == -1 { 
     return 0, err 
    } 
    return int(w.Col), nil 
}