Pregunta

¿Cómo consigo el tamaño terminal en Ir. En C se vería así:

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

Pero, ¿cómo puedo acceder a TIOCGWINSZ en Ir

¿Fue útil?

Solución

El compilador CGO no puede manejar argumentos variables en función C y macros en archivos de cabecera de C en la actualidad, por lo que no se puede hacer un simple

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

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

Para conseguir alrededor de las macros utilizar una constante, por lo que

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

Sin embargo CGO seguirá siendo vomitar en el ... en el prototipo de ioctl. Su mejor apuesta sería la de envolver ioctl con una función c teniendo un número específico de argumentos y vincular esa. Como un truco que puede hacer que en el comentario anterior de importación "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)
}

No he probado esto, pero algo similar debería funcionar.

Otros consejos

La mejor manera de hacer esto sería usar el paquete de llamada al sistema. El paquete de llamada al sistema no define una función ioctl, ya que sólo hace tantas cosas diferentes, pero todavía se puede llamar así:

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

Las dos cosas son dejadas para duplicar la estructura winsize y la constante que necesitan. La herramienta para esto es godefs, lo que generará un archivo de origen .go examinado estructuras y constantes en las cabeceras C. Crear un archivo termios.c que tiene este aspecto:

#include <termios.h>

enum {
    $TIOCGWINSZ = TIOCGWINSZ
};

typedef winsize $winsize;

Ahora ejecute

godefs -gpackagename termios.c > termios.go

Ahora usted debería tener todo lo necesario para obtener el tamaño de terminal. Ajuste del tamaño es tan simple como la adición de otra constante a termios.c.

leer: 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
}

No parece mucho trabajo se ha hecho sobre esto todavía desde una mirada casual de la documentación -. De hecho, no puedo encontrar ioctl en absoluto

Con un lenguaje tan temprano en su infancia, es seguro decir que usted está pisando suelo unwalked. TIOCGWINSZ, en sí, es sólo un número entero constante (me encontré su valor en el código fuente Linux):

#define TIOCGWINSZ  0x5413

Buena suerte, sin embargo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top