How to set the size of the terminal?

How to get the size of the terminal in Go. In C, it will look like this:

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

But how can I access TIOCGWINSZ in Go

+3
source share
4 answers

The cgo compiler cannot handle variable arguments in c functions and macros in c header files at present, so you cannot make simple

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

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

To bypass macros, use a constant, therefore

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

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

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

However, cgo will still be ... on the ioctl prototype. It would be best to wrap ioctl with a c function, taking a certain number of arguments and binding it. As a hack, you can do this in the comments above to 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 answer

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

, - .

+3

- syscall. syscall ioctl, , :

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

- winsize , . godefs, .go, C. 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
}
+1
source

It doesn't seem like a lot of work has been done on this, but from a casual look at the documentation - in fact, I can’t find it at all ioctl.

With the language that he started in early childhood, it is safe to say that you knock on negligence. TIOCGWINSZ, by itself, is just a constant integer (I found its value in the Linux source code):

#define TIOCGWINSZ  0x5413

Good luck, however.

0
source

Source: https://habr.com/ru/post/1722839/


All Articles