2009-11-14 67 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 
}