views:

359

answers:

2

How do I get the terminal size in Go. In C it would look like this:

struct ttysize ts; 
ioctl(0, TIOCGWINSZ, &ts);

But how to i access TIOCGWINSZ in Go

A: 

It doesn't look like much work has been done on this yet from a casual glance of the documentation -- in fact, I can't find ioctl at all.

With a language this early in its infancy, it's safe to say that you're treading unwalked ground. TIOCGWINSZ, itself, is just a constant integer (I found its value in the Linux source code):

#define TIOCGWINSZ  0x5413

Good luck, though.

Jed Smith
+2  A: 

The cgo compiler can't handle variable arguments in a c function and macros in c header files at present, so you can't do a simple

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

func GetWinSz() {
    var ts C.ttysize;
    C.ioctl(0,C.TIOCGWINSZ,&ts)
}

To get around the macros use a constant, so

// #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)
}

However cgo will still barf on the ... in ioctl's prototype. Your best bet would be to wrap ioctl with a c function taking a specific number of arguments and link that in. As a hack you can do that in the comment above import "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)
}

I've not tested this, but something similar should work.

Scott Wales