github.com/kopoli/go-terminal-size@v0.0.0-20170219200355-5c97524c8b54/size_unix.go (about) 1 // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris 2 3 package tsize 4 5 import ( 6 "os" 7 "os/signal" 8 "unsafe" 9 10 "golang.org/x/sys/unix" 11 ) 12 13 type winsize struct { 14 rows uint16 15 cols uint16 16 x uint16 17 y uint16 18 } 19 20 var unixSyscall = unix.Syscall 21 22 func getTerminalSize(fp *os.File) (s Size, err error) { 23 ws := winsize{} 24 25 _, _, errno := unixSyscall( 26 unix.SYS_IOCTL, 27 fp.Fd(), 28 uintptr(unix.TIOCGWINSZ), 29 uintptr(unsafe.Pointer(&ws))) 30 31 if errno != 0 { 32 err = errno 33 return 34 } 35 36 s = Size{ 37 Width: int(ws.cols), 38 Height: int(ws.rows), 39 } 40 41 return 42 } 43 44 func getTerminalSizeChanges(sc chan Size, done chan struct{}) error { 45 ch := make(chan os.Signal, 1) 46 47 sig := unix.SIGWINCH 48 49 signal.Notify(ch, sig) 50 go func() { 51 for { 52 select { 53 case <-ch: 54 var err error 55 s, err := getTerminalSize(os.Stdout) 56 if err == nil { 57 sc <- s 58 } 59 case <-done: 60 signal.Reset(sig) 61 close(ch) 62 return 63 } 64 } 65 }() 66 67 return nil 68 }