Syscall in getTermSize() corrupts package variable of a different library
Hi.
I am developing a CLI application which uses uilive v0.0.4 to output execution statistics to the console at runtime. Everything was fine until I decided to use sniper as a key-value storage for my app. It turned out that one of the sniper package variables got corrupted (changes it's value from 12 to 0) after calling uilive.New(). Without calling uilive.New() sniper works perfectly fine.
I traced the issue down to the IOCTL syscall in getTermSize() function in terminal_size.go:
//...
var sz windowSize
func getTermSize() (int, int) {
//...
// `sniper` package variable is fine here
_, _, _ = syscall.Syscall(syscall.SYS_IOCTL,
out.Fd(), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sz)))
// `sniper` package variable is reset to 0
return int(sz.cols), int(sz.rows)
}Ubuntu 20.04 LTS x64
I am not sure what goes wrong exactly, but it looks like using an unsafe.Pointer to the sz package variable somehow messes up the memory contents. I can't say if any other package variables are affected.
I managed to fix the issue by simply moving package variables from terminal_size.go into the getTermSize() function body, making them local (and they kinda should be local, there are no usages of them outside of terminal_size.go):
// +build !windows
package uilive
import (
"os"
"runtime"
"syscall"
"unsafe"
)
type windowSize struct {
rows uint16
cols uint16
}
func getTermSize() (int, int) {
var (
out *os.File
err error
sz windowSize
)
if runtime.GOOS == "openbsd" {
out, err = os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
return 0, 0
}
} else {
out, err = os.OpenFile("/dev/tty", os.O_WRONLY, 0)
if err != nil {
return 0, 0
}
}
_, _, _ = syscall.Syscall(syscall.SYS_IOCTL,
out.Fd(), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sz)))
return int(sz.cols), int(sz.rows)
}
What do you think? Please help me out.
Env specs:
| OS | Ubuntu 20.04 LTS x64 |
| Kernel | 5.7.7-050707-generic |
| Go | 1.15.7 |
PR: #39
P.S.: big thanks for the library, it's awesome :)